
Additional commit content 1. Modified ObjectPool Function(OnReleaseArrow and naming). 2. Modified hitBox tag in aiPrefab. 3. Modified Physics layer. 4. Modified TargetInfo variable from TargetTransform variable in FieldOfView script. 5. Added GetCurrentHp() in IAiStat script.
159 lines
5.2 KiB
C#
159 lines
5.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.Pool;
|
|
|
|
// ReSharper disable once CheckNamespace
|
|
namespace BlueWaterProject
|
|
{
|
|
public class Arrow : MonoBehaviour
|
|
{
|
|
#region Property and variable
|
|
|
|
[Tooltip("발사 이후 자동으로 사라지는데 까지 걸리는 시간")]
|
|
[Range(0f, 10f)]
|
|
[SerializeField] private float autoDestroyTime;
|
|
|
|
[Tooltip("화살이 날아가는 속도")]
|
|
[SerializeField] private float arrowSpeed = 15f;
|
|
|
|
private float g = Mathf.Abs(Physics.gravity.y);
|
|
private Vector3 targetPos;
|
|
private AttackerType attackerType;
|
|
private float inaccuracy;
|
|
|
|
private Transform attackerTransform;
|
|
private AiStat attackerStat;
|
|
private Rigidbody arrowRigidbody;
|
|
private IObjectPool<Arrow> managedArrowPool;
|
|
|
|
#endregion
|
|
|
|
#region Unity built-in function
|
|
|
|
private void Awake()
|
|
{
|
|
arrowRigidbody = Utils.GetComponentAndAssert<Rigidbody>(transform);
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other)
|
|
{
|
|
print(other.gameObject.name);
|
|
if (other.gameObject.layer == LayerMask.NameToLayer("Ground") ||
|
|
other.gameObject.layer == LayerMask.NameToLayer("Water"))
|
|
{
|
|
DestroyObject();
|
|
}
|
|
else if (other.gameObject.layer == LayerMask.NameToLayer("HitBox"))
|
|
{
|
|
switch (attackerType)
|
|
{
|
|
case AttackerType.NONE:
|
|
break;
|
|
case AttackerType.PLAYER:
|
|
if (!other.gameObject.CompareTag("Enemy"))
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
case AttackerType.PIRATE:
|
|
if (!other.gameObject.CompareTag("Enemy"))
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
case AttackerType.ENEMY:
|
|
if (!other.gameObject.CompareTag("Player") || !other.gameObject.CompareTag("Pirate"))
|
|
{
|
|
return;
|
|
}
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
var iDamageable = other.transform.parent.GetComponent<IDamageable>();
|
|
print(iDamageable);
|
|
|
|
iDamageable.TakeDamage(attackerStat, iDamageable.AiStat);
|
|
DestroyObject();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Custom function
|
|
|
|
public IEnumerator Shoot()
|
|
{
|
|
var time = 0f;
|
|
var inaccuracyOffset = new Vector3(
|
|
UnityEngine.Random.Range(-inaccuracy, inaccuracy),
|
|
UnityEngine.Random.Range(-inaccuracy, inaccuracy),
|
|
UnityEngine.Random.Range(-inaccuracy, inaccuracy)
|
|
);
|
|
var inaccurateTargetPos = targetPos + inaccuracyOffset;
|
|
|
|
transform.rotation = Quaternion.LookRotation(inaccurateTargetPos);
|
|
transform.rotation *= Quaternion.Euler(0f, -90f, 0f);
|
|
|
|
|
|
while (time < autoDestroyTime)
|
|
{
|
|
var myPos = transform.position;
|
|
var toTargetFlat = new Vector3(inaccurateTargetPos.x - myPos.x, 0, inaccurateTargetPos.z - myPos.z);
|
|
var horizontalDistance = toTargetFlat.magnitude;
|
|
var timeToTarget = horizontalDistance / arrowSpeed;
|
|
|
|
var yOffset = targetPos.y - myPos.y;
|
|
|
|
var initialVerticalSpeed = (yOffset + (0.5f * g * timeToTarget * timeToTarget)) / timeToTarget;
|
|
|
|
var launchVelocity = toTargetFlat.normalized * arrowSpeed + Vector3.up * initialVerticalSpeed;
|
|
arrowRigidbody.velocity = launchVelocity;
|
|
|
|
transform.rotation = Quaternion.LookRotation(arrowRigidbody.velocity);
|
|
transform.rotation *= Quaternion.Euler(0f, -90f, 0f);
|
|
|
|
|
|
yield return null;
|
|
}
|
|
|
|
if (gameObject.activeSelf)
|
|
{
|
|
DestroyObject();
|
|
}
|
|
}
|
|
|
|
public void SetShootingArrow(Vector3 shootPos, Vector3 targetPosition, AiStat attackerAiStat, AttackerType type, float inaccuracyValue)
|
|
{
|
|
transform.position = shootPos;
|
|
targetPos = targetPosition;
|
|
attackerStat = attackerAiStat;
|
|
attackerType = type;
|
|
inaccuracy = inaccuracyValue;
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region ObjectPool function
|
|
|
|
private void DestroyObject() => managedArrowPool.Release(this);
|
|
|
|
public void SetManagedPool(IObjectPool<Arrow> pool) => managedArrowPool = pool;
|
|
|
|
#endregion
|
|
|
|
#region Custom function
|
|
|
|
public void ReleaseArrowSetting()
|
|
{
|
|
StopAllCoroutines();
|
|
gameObject.SetActive(false);
|
|
arrowRigidbody.velocity = Vector3.zero;
|
|
arrowRigidbody.angularVelocity = Vector3.zero;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |