119 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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<Rigidbody>();
 | |
|         _arrow = GetComponent<Arrow>();
 | |
|         _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);
 | |
|     }
 | |
| } |