using Audio; using FishNet.Object.Synchronizing; using UnityEngine; using UnityEngine.XR.Interaction.Toolkit; namespace _PROJECT.Multiplayer.NewBow { public class TwoHandedBowNotch : XRSocketInteractor { [SerializeField, Range(0, 1)] private float releaseThreshold = 0.25f; public AudioClipGroup nockSounds; public AudioClipGroup releaseSounds; private TwoHandedBow _bow; private TwoHandedBowNetworkManager _networkBehavior; protected override void Awake() { base.Awake(); _bow = GetComponentInParent(); _networkBehavior = GetComponentInParent(); } protected override void OnEnable() { base.OnEnable(); _bow.selectExited.AddListener(ReleaseArrow); } protected override void OnDisable() { base.OnDisable(); _bow.selectExited.RemoveListener(ReleaseArrow); } public void ReleaseArrow(SelectExitEventArgs args) { Debug.Log("Notch select exit by " + args.interactorObject); Debug.Log("Notch has selection: " + hasSelection); if (!hasSelection) return; // Pulled enough to release the arrow Debug.Log("Notch pull amount: " + _bow.PullAmount); if (_bow.PullAmount < releaseThreshold) return; // Bow is still being held by the other hand, Debug.Log("Notch other hand is selecting: " + _bow.firstInteractorSelecting); if (_bow.firstInteractorSelecting == null) return; Debug.Log("Notch other hand is not selecting"); Debug.Log("Sending Arrow Release RPC"); _networkBehavior.LaunchArrow(_bow.PullAmount); } public override bool CanSelect(IXRSelectInteractable interactable) { return QuickSelect(interactable) && CanHover(interactable) && interactable is Arrow; } public override void ProcessInteractor(XRInteractionUpdateOrder.UpdatePhase updatePhase) { base.ProcessInteractor(updatePhase); // Move attach when bow is pulled, this updates the renderer as well attachTransform.position = _bow.secondaryAttachTransform.position; } private bool QuickSelect(IXRSelectInteractable interactable) { // This lets the Notch automatically grab the arrow return !hasSelection || IsSelecting(interactable); } private bool CanHover(IXRSelectInteractable interactable) { if (interactable is IXRHoverInteractable hoverInteractable) return CanHover(hoverInteractable); return false; } public Vector3 GetLaunchDirection() { return _networkBehavior.lastKnownLaunchDirection; } public void SetLaunchDirection(Vector3 direction) { Debug.Log("Setting launch direction: " + direction); if (direction != Vector3.zero) { _networkBehavior.SetLaunchDirection(direction); return; } Debug.Log("Launch direction is zero"); } public void PlayNockSound() { nockSounds.Play(); } public void PlayReleaseSound() { releaseSounds.Play(); } public float GetLastKnownPullAmount() { return _networkBehavior.lastKnownPullAmount; } } }