2023-05-08 15:56:10 +03:00

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