|
|
- namespace VRTK.Examples.Archery
- {
- using UnityEngine;
- using System.Collections;
-
- public class BowAim : MonoBehaviour
- {
- public float powerMultiplier;
- public float pullMultiplier;
- public float pullOffset;
- public float maxPullDistance = 1.1f;
- public float bowVibration = 0.062f;
- public float stringVibration = 0.087f;
-
- private BowAnimation bowAnimation;
- private GameObject currentArrow;
- private BowHandle handle;
-
- private VRTK_InteractableObject interact;
-
- private VRTK_InteractGrab holdControl;
- private VRTK_InteractGrab stringControl;
-
- private Quaternion releaseRotation;
- private Quaternion baseRotation;
- private bool fired;
- private float fireOffset;
- private float currentPull;
- private float previousPull;
-
- private AudioSource source;
-
- public VRTK_InteractGrab GetPullHand()
- {
- return stringControl;
- }
-
- public bool IsHeld()
- {
- return interact.IsGrabbed();
- }
-
- public bool HasArrow()
- {
- return currentArrow != null;
- }
-
- public void SetArrow(GameObject arrow)
- {
- currentArrow = arrow;
- PlaySound();
- }
-
- private void Start()
- {
- source = GetComponent<AudioSource>();
- bowAnimation = GetComponent<BowAnimation>();
- handle = GetComponentInChildren<BowHandle>();
- interact = GetComponent<VRTK_InteractableObject>();
- interact.InteractableObjectGrabbed += new InteractableObjectEventHandler(DoObjectGrab);
- }
-
- private void PlaySound()
- {
- if (source != null && !source.isPlaying)
- {
- source.Play();
- }
- }
-
- private void DoObjectGrab(object sender, InteractableObjectEventArgs e)
- {
- if (VRTK_DeviceFinder.IsControllerLeftHand(e.interactingObject))
- {
- holdControl = VRTK_DeviceFinder.GetControllerLeftHand().GetComponent<VRTK_InteractGrab>();
- stringControl = VRTK_DeviceFinder.GetControllerRightHand().GetComponent<VRTK_InteractGrab>();
- }
- else
- {
- stringControl = VRTK_DeviceFinder.GetControllerLeftHand().GetComponent<VRTK_InteractGrab>();
- holdControl = VRTK_DeviceFinder.GetControllerRightHand().GetComponent<VRTK_InteractGrab>();
- }
- StartCoroutine("GetBaseRotation");
- }
-
- private IEnumerator GetBaseRotation()
- {
- yield return new WaitForEndOfFrame();
- baseRotation = transform.localRotation;
- }
-
- private void Update()
- {
- if (currentArrow != null && IsHeld())
- {
- AimArrow();
- AimBow();
- PullString();
- if (!stringControl.IsGrabButtonPressed())
- {
- currentArrow.GetComponent<Arrow>().Fired();
- fired = true;
- releaseRotation = transform.localRotation;
- Release();
- }
- }
- else if (IsHeld())
- {
- if (fired)
- {
- fired = false;
- fireOffset = Time.time;
- }
- if (releaseRotation != baseRotation)
- {
- transform.localRotation = Quaternion.Lerp(releaseRotation, baseRotation, (Time.time - fireOffset) * 8);
- }
- }
-
- if (!IsHeld())
- {
- if (currentArrow != null)
- {
- Release();
- }
- }
- }
-
- private void Release()
- {
- bowAnimation.SetFrame(0);
- currentArrow.transform.SetParent(null);
- Collider[] arrowCols = currentArrow.GetComponentsInChildren<Collider>();
- Collider[] BowCols = GetComponentsInChildren<Collider>();
- foreach (var c in arrowCols)
- {
- c.enabled = true;
- foreach (var C in BowCols)
- {
- Physics.IgnoreCollision(c, C);
- }
- }
- currentArrow.GetComponent<Rigidbody>().isKinematic = false;
- currentArrow.GetComponent<Rigidbody>().velocity = currentPull * powerMultiplier * currentArrow.transform.TransformDirection(Vector3.forward);
- currentArrow.GetComponent<Arrow>().inFlight = true;
- currentArrow = null;
- currentPull = 0;
-
- ReleaseArrow();
- }
-
- private void ReleaseArrow()
- {
- if (stringControl)
- {
- stringControl.ForceRelease();
- }
- }
-
- private void AimArrow()
- {
- currentArrow.transform.localPosition = Vector3.zero;
- currentArrow.transform.LookAt(handle.nockSide.position);
- }
-
- private void AimBow()
- {
- transform.rotation = Quaternion.LookRotation(holdControl.transform.position - stringControl.transform.position, holdControl.transform.TransformDirection(Vector3.forward));
- }
-
- private void PullString()
- {
- currentPull = Mathf.Clamp((Vector3.Distance(holdControl.transform.position, stringControl.transform.position) - pullOffset) * pullMultiplier, 0, maxPullDistance);
- bowAnimation.SetFrame(currentPull);
-
- if (currentPull.ToString("F2") != previousPull.ToString("F2"))
- {
- VRTK_ControllerHaptics.TriggerHapticPulse(VRTK_ControllerReference.GetControllerReference(holdControl.gameObject), bowVibration);
- VRTK_ControllerHaptics.TriggerHapticPulse(VRTK_ControllerReference.GetControllerReference(stringControl.gameObject), stringVibration);
- }
- previousPull = currentPull;
- }
- }
- }
|