
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.
134 lines
4.0 KiB
C#
134 lines
4.0 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
using Random = UnityEngine.Random;
|
|
|
|
// ReSharper disable once CheckNamespace
|
|
namespace BlueWaterProject
|
|
{
|
|
public enum AttackerType
|
|
{
|
|
NONE,
|
|
PLAYER,
|
|
PIRATE,
|
|
ENEMY
|
|
}
|
|
|
|
[Serializable]
|
|
public abstract class AiController : MonoBehaviour, IDamageable
|
|
{
|
|
#region Property and variable
|
|
|
|
protected bool isAttacking;
|
|
protected AttackerType attackerType;
|
|
|
|
protected Animator aiAnimator;
|
|
protected AiMover aiMover;
|
|
protected FieldOfView fieldOfView;
|
|
protected NavMeshAgent navMeshAgent;
|
|
|
|
public static readonly int SpeedHash = Animator.StringToHash("Speed");
|
|
public static readonly int AttackHash = Animator.StringToHash("Attack");
|
|
public static readonly int DamageHash = Animator.StringToHash("TakeDamage");
|
|
public static readonly int DeathTypeHash = Animator.StringToHash("DeathType");
|
|
public static readonly int DeathHash = Animator.StringToHash("Death");
|
|
|
|
#endregion
|
|
|
|
#region abstract function
|
|
|
|
protected abstract void Attack();
|
|
|
|
#endregion
|
|
|
|
#region Unity built-in function
|
|
|
|
protected virtual void Awake()
|
|
{
|
|
aiAnimator = Utils.GetComponentAndAssert<Animator>(transform);
|
|
aiMover = Utils.GetComponentAndAssert<AiMover>(transform);
|
|
fieldOfView = Utils.GetComponentAndAssert<FieldOfView>(transform);
|
|
navMeshAgent = Utils.GetComponentAndAssert<NavMeshAgent>(transform);
|
|
|
|
if (gameObject.layer == LayerMask.NameToLayer("Player"))
|
|
{
|
|
attackerType = AttackerType.PLAYER;
|
|
}
|
|
else if (gameObject.layer == LayerMask.NameToLayer("Pirate"))
|
|
{
|
|
attackerType = AttackerType.PIRATE;
|
|
}
|
|
else if (gameObject.layer == LayerMask.NameToLayer("Enemy"))
|
|
{
|
|
attackerType = AttackerType.ENEMY;
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
SetCurrentHp(AiStat.maxHp);
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
Attack();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region interface property and function
|
|
|
|
[field: SerializeField] public AiStat AiStat { get; set; } = new();
|
|
public float GetCurrentHp() => AiStat.currentHp;
|
|
|
|
public void TakeDamage(AiStat attacker, AiStat defender)
|
|
{
|
|
// 회피 성공 체크
|
|
if (Random.Range(0, 100) < defender.avoidanceRate)
|
|
{
|
|
// TODO : 회피 처리
|
|
return;
|
|
}
|
|
|
|
var finalDamage = Utils.CalcDamage(attacker, defender);
|
|
|
|
// 방패 막기 체크
|
|
if (finalDamage == 0f)
|
|
{
|
|
// TODO : 방패로 막힘 처리(애니메이션 등)
|
|
return;
|
|
}
|
|
|
|
var changeHp = Mathf.Max(defender.currentHp - finalDamage, 0);
|
|
SetCurrentHp(changeHp);
|
|
|
|
// 죽었는지 체크
|
|
if (changeHp == 0f)
|
|
{
|
|
var randomValue = Random.Range(0, 2);
|
|
aiAnimator.SetInteger(DeathTypeHash, randomValue);
|
|
|
|
// TODO : 죽었을 때 처리(죽는 애니메이션 이후 사라지는 효과 등)
|
|
aiAnimator.SetTrigger(DeathHash);
|
|
|
|
Invoke(nameof(Destroy), 5f);
|
|
return;
|
|
}
|
|
|
|
aiAnimator.SetTrigger(DamageHash);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Custom function
|
|
|
|
private void Destroy() => Destroy(gameObject);
|
|
public bool GetIsAttacking() => isAttacking;
|
|
public FieldOfView GetFieldOfView() => fieldOfView;
|
|
public NavMeshAgent GetNavMeshAgent() => navMeshAgent;
|
|
public Animator GetAnimator() => aiAnimator;
|
|
public void SetCurrentHp(float value) => AiStat.currentHp = value;
|
|
|
|
#endregion
|
|
}
|
|
} |