You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
4.9 KiB
C#

6 months ago
using NaughtyAttributes;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Autohand;
namespace Autohand.Demo {
public class AutoBow : MonoBehaviour
{
public AutoAnimation bowAnimation;
public Grabbable bowHandleGrabbable;
public HeldPlaceJoint arrowPoint;
[Space]
public float drawbackRange = 0.3f;
public float drawbackSpring = 100f;
public float drawbackDamper = 10f;
public float tolerance = 0.005f;
[Space]
public Vector3 arrowForceDirection = Vector3.forward;
public float arrowForce = 1f;
public float arrowImpactForceMultiplier = 1f;
public AnimationCurve arrowForceCurve = AnimationCurve.Linear(0, 0, 1, 1);
protected Grabbable arrow;
protected SpringJoint arrowJoint;
int placePointIndex = 0;
public void Start()
{
placePointIndex = bowAnimation.GetTransformIndex(arrowPoint.transform);
arrowPoint.enabled = false;
arrowPoint.OnPlaceEvent += OnArrowPlace;
bowHandleGrabbable.OnGrabEvent += OnBowHandleGrab;
bowHandleGrabbable.OnReleaseEvent += OnBowHandleRelease;
}
public void Update()
{
BowStringAnimation();
}
float arrowPointValue = 0.5f;
public void BowStringAnimation()
{
if (arrowPoint.placedObject != null)
{
var arrowHand = arrowPoint.placedObject.GetHeldBy()[0];
arrowPointValue = 0.5f;
float closestPoint = 0.5f;
for (int i = 0; i < 20; i++) {
var postitionA = bowAnimation.GetTransformPositionAtPoint(placePointIndex, closestPoint + arrowPointValue / 2f);
var postitionB = bowAnimation.GetTransformPositionAtPoint(placePointIndex, closestPoint - arrowPointValue / 2f);
var postitionC = bowAnimation.GetTransformPositionAtPoint(placePointIndex, closestPoint);
var distanceA = Vector3.Distance(postitionA, arrowPoint.placedObject.transform.position);
var distanceB = Vector3.Distance(postitionB, arrowPoint.placedObject.transform.position);
var distanceC = Vector3.Distance(postitionC, arrowPoint.placedObject.transform.position);
if(distanceC < distanceA && distanceC < distanceB) { }
else if(distanceA < distanceB)
closestPoint += arrowPointValue / 2f;
else
closestPoint -= arrowPointValue / 2f;
arrowPointValue /= 2f;
}
bowAnimation.SetAnimation(closestPoint);
}
else if(arrowPointValue != 0) {
arrowPointValue = 0;
bowAnimation.SetAnimation(arrowPointValue);
}
}
public void OnBowHandleGrab(Hand hand, Grabbable grab)
{
arrowPoint.enabled = true;
}
public void OnBowHandleRelease(Hand hand, Grabbable grab)
{
arrowPoint.enabled = false;
}
public void OnArrowPlace(PlacePoint point, Grabbable grab)
{
point.placedObject.OnReleaseEvent += OnArrowRelease;
if(bowHandleGrabbable.HeldCount() > 0)
point.placedObject.IgnoreHand(bowHandleGrabbable.GetHeldBy()[0], true);
point.placedObject.ignoreReleaseTime = 1f;
}
public void OnArrowRelease(Hand hand, Grabbable grab)
{
if (arrowPoint.placedObject != null)
{
//arrowPoint.Destroyjoint();
arrowPoint.Remove(arrowPoint.placedObject);
if (bowHandleGrabbable.HeldCount() > 0){
bowAnimation.SetAnimation(0);
var bowHand = bowHandleGrabbable.GetHeldBy()[0];
EnableCollisionDelay(3f, grab, bowHandleGrabbable.GetHeldBy()[0], arrowPoint);
}
AutoArrow arrow;
if (grab.body.TryGetComponent<AutoArrow>(out arrow))
{
arrow.FireArrow(arrowForceCurve.Evaluate(arrowPointValue)*arrowForce, grab, this);
}
else
{
arrow = grab.body.gameObject.AddComponent<AutoArrow>();
arrow.FireArrow(arrowForceCurve.Evaluate(arrowPointValue) * arrowForce, grab, this);
}
}
}
IEnumerator EnableCollisionDelay(float delay, Grabbable grab, Hand hand, PlacePoint placePoint)
{
var preDrag = grab.body.angularDrag;
bowHandleGrabbable.IgnoreGrabbableCollisionUntilNone(grab);
placePoint.dontAllows.Add(grab);
yield return new WaitForSeconds(delay);
grab.IgnoreHand(hand, false);
placePoint.dontAllows.Remove(grab);
}
}
}