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);
|
|
}
|
|
} |