forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			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);
 | 
						|
    }
 | 
						|
} |