using System.Collections; using System.Collections.Generic; using UnityEngine; using VRTK; using VRTK.SecondaryControllerGrabActions; public class BowGrab : VRTK_ControlDirectionGrabAction { [SerializeField] private Vector3 m_angleOffset; [SerializeField] private Transform m_notchPoint; [Header("Pull settings")] [SerializeField] private float m_maxPullDistance = 0.5f; [SerializeField] private string m_animationParam = "bowPull"; [Header("Arrow Settings")] [SerializeField] private GameObject m_arrowPrefab; [SerializeField] private Transform m_arrowSpawn; [SerializeField] private float m_maxForce = 10f; private Animator m_animator; private Vector3 m_lastForward; private float m_lastForce; private void Start() { m_animator = GetComponent(); } public override void ProcessFixedUpdate() { if (initialised) { AimObject(); PullBow(); } } protected override void AimObject() { Vector3 direction = Vector3.Slerp((primaryGrabbingObject.transform.position - secondaryGrabbingObject.transform.position).normalized, primaryGrabbingObject.transform.forward, 0.5f); transform.rotation = Quaternion.LookRotation(direction, primaryGrabbingObject.transform.up) * Quaternion.Euler(m_angleOffset); m_lastForward = direction; } protected virtual void PullBow() { float animationValue = getBowForce(); m_animator.SetFloat(m_animationParam, animationValue); m_lastForce = animationValue; } public override void ResetAction() { base.ResetAction(); m_animator.SetFloat(m_animationParam, 0); if (m_lastForce > 0.1f) { GameObject arrow = Instantiate(m_arrowPrefab); arrow.transform.position = m_arrowSpawn.transform.position; arrow.transform.forward = m_lastForward; Rigidbody rb = arrow.GetComponent(); rb.velocity = arrow.transform.forward * m_lastForce * m_maxForce; } m_lastForce = 0; m_lastForward = Vector3.zero; } private float getBowForce() { Vector3 directionSecondHand = secondaryGrabbingObject.transform.position - m_notchPoint.transform.position; Vector3 directionPrimaryHand = primaryGrabbingObject.transform.position - m_notchPoint.transform.position; float force = 0; if (Vector3.Dot(directionSecondHand, directionPrimaryHand) > 0) force = 0; else { force = directionSecondHand.magnitude / m_maxPullDistance; if (force > 1) force = 1; } return force; } }