using System.Collections; using _PROJECT.Multiplayer.NewBow; using _PROJECT.Scripts.Bow; using FishNet.Object; using UnityEngine; public class ArrowCaster : NetworkBehaviour { [SerializeField] private Transform tip; [SerializeField] private LayerMask layerMask = ~0; [SerializeField] private float speed = 2000f; private Vector3 lastPosition = Vector3.zero; private readonly float _maxLifeTime = 30f; private float _lifeTime; private bool _launched; private Rigidbody _rigidbody; private Arrow _arrow; private RaycastHit _hit; private void Awake() { _rigidbody = GetComponent(); _arrow = GetComponent(); _launched = false; } private void Update() { if (!IsServer) return; if (!_launched) return; if (Time.time - _lifeTime > _maxLifeTime) Despawn(DespawnType.Pool); } private bool CheckForCollision(out RaycastHit hit) { if (lastPosition == Vector3.zero) lastPosition = tip.position; bool collided = Physics.Linecast(lastPosition, tip.position, out hit, layerMask); lastPosition = collided ? lastPosition : tip.position; return collided; } public void LaunchArrow(TwoHandedBowNotch notch) { if (!IsServer) return; Debug.Log("Launching arrow"); transform.rotation = Quaternion.LookRotation(notch.GetLaunchDirection()); Debug.Log("Launching arrow with direction " + notch.GetLaunchDirection()); Debug.Log("Launching arrow with pull amount " + notch.GetLastKnownPullAmount()); LaunchArrow(notch.GetLaunchDirection().normalized * (notch.GetLastKnownPullAmount() * speed)); } private void LaunchArrow(Vector3 force) { _lifeTime = Time.time; _launched = true; RemoveOwnership(); transform.parent = null; EnablePhysics(); ApplyForce(force); StartCoroutine(LaunchRoutine()); } private void ApplyForce(Vector3 force) { _rigidbody.AddForce(force); } private IEnumerator LaunchRoutine() { // Set direction while flying while (!CheckForCollision(out _hit)) { SetDirection(); yield return null; } Debug.Log(_hit.transform.name); // Once the arrow has stopped flying DisablePhysics(); CheckForHittable(_hit); } private void SetDirection() { if (_rigidbody.velocity.z > 0.5f) transform.forward = _rigidbody.velocity; } private void DisablePhysics() { _rigidbody.isKinematic = true; _rigidbody.useGravity = false; } private void EnablePhysics() { _rigidbody.isKinematic = false; _rigidbody.useGravity = true; } private void CheckForHittable(RaycastHit hit) { if (hit.transform.TryGetComponent(out IArrowHittable hittable)) hittable.Hit(_arrow); } }