2021-04-11 20:50:24 +03:00

124 lines
3.2 KiB
C#

using System;
using System.Collections;
using Audio;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
namespace Bow
{
public class Arrow : XRGrabInteractable
{
public AudioClipGroup hitSounds;
public float speed = 2000.0f;
public Transform tip = null;
public float maxLifetimeAfterShot = 60f;
private bool _inAir = false;
private Vector3 _lastPosition = Vector3.zero;
private Rigidbody _rigidbody = null;
private float _timeToDestroyOn;
protected override void Awake()
{
base.Awake();
_rigidbody = GetComponent<Rigidbody>();
_timeToDestroyOn = float.MaxValue;
}
private void FixedUpdate()
{
if (!_inAir) return;
CheckForCollision();
_lastPosition = tip.position;
if (_timeToDestroyOn <= Time.time)
{
Destroy(gameObject);
}
}
private void CheckForCollision()
{
RaycastHit hit;
if (Physics.Linecast(_lastPosition, tip.position, out hit, LayerMask.GetMask("Default"),
QueryTriggerInteraction.Ignore))
{
hit.collider.gameObject.SendMessage("OnArrowHit", this,
SendMessageOptions.DontRequireReceiver);
Stop();
hitSounds.Play();
}
}
private void Stop()
{
_inAir = false;
SetPhysics(false);
}
public void Release(float pullValue)
{
_inAir = true;
SetPhysics(true);
MaskAndFire(pullValue);
StartCoroutine(RotateWithVelocity());
_lastPosition = tip.position;
}
private void SetPhysics(bool usePhysics)
{
_rigidbody.isKinematic = !usePhysics;
_rigidbody.useGravity = usePhysics;
}
private void MaskAndFire(float power)
{
colliders[0].enabled = false;
interactionLayerMask = 1 << LayerMask.NameToLayer("IgnoreInteraction");
Vector3 force = transform.forward * (power * speed);
_rigidbody.AddForce(force);
_timeToDestroyOn = Time.time + maxLifetimeAfterShot;
}
private IEnumerator RotateWithVelocity()
{
yield return new WaitForFixedUpdate();
while (_inAir)
{
Quaternion newRotation = Quaternion.LookRotation(_rigidbody.velocity, transform.up);
transform.rotation = newRotation;
yield return null;
}
}
public new void OnSelectEntered(XRBaseInteractor interactor)
{
base.OnSelectEntered(interactor);
}
public new void OnSelectExited(XRBaseInteractor interactor)
{
base.OnSelectExited(interactor);
}
public new void OnSelectExiting(XRBaseInteractor interactor)
{
base.OnSelectExiting(interactor);
}
protected override void OnDestroy()
{
base.OnDestroy();
colliders.Clear();
}
}
}