OldBlueWater/BlueWater/Assets/02.Scripts/Ai/AiController.cs

802 lines
29 KiB
C#
Raw Normal View History

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
2023-08-29 03:41:24 +00:00
using Unity.VisualScripting;
using UnityEngine;
2023-08-08 07:53:35 +00:00
using UnityEngine.AI;
using UnityEngine.Animations;
using Random = UnityEngine.Random;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
2023-09-04 07:31:04 +00:00
public enum EAiType
2023-08-29 03:41:24 +00:00
{
NONE = -1,
PLAYER,
PIRATE,
ENEMY
}
2023-09-04 07:31:04 +00:00
public enum EAttackerType
{
NONE = -1,
OFFENSE,
DEFENSE
}
2023-09-04 07:31:04 +00:00
public enum EOffenseType
{
NONE = -1,
NORMAL,
ONLY_HOUSE
}
2023-09-04 07:31:04 +00:00
public enum EDefenseType
{
NONE = -1,
2023-09-04 07:31:04 +00:00
STRIKER,
MIDFIELDER,
DEFENDER,
KEEPER
}
[Serializable]
2023-09-12 14:46:57 +00:00
public class AiController : MonoBehaviour, IDamageable
{
#region Property and variable
[Title("Skin")]
[Tooltip("SkinnedMeshRenderer, MeshRenderer의 Material을 모두 담고 있는 리스트")]
[SerializeField] protected List<Material> skinMaterialList = new(10);
[Tooltip("캐릭터 외곽선의 기본 색상")]
[SerializeField] protected Color defaultSkinColor = Color.black;
[Tooltip("캐릭터에 마우스 커서가 올라가 있을 때 색상")]
[SerializeField] protected Color mouseEnterHighlightSkinColor = Color.white;
[Tooltip("캐릭터가 선택되었을 때 색상")]
[SerializeField] protected Color selectedSkinColor = Color.red;
[DisableIf("@true")]
[SerializeField] private IslandInfo islandInfo;
2023-09-11 07:16:02 +00:00
public bool IsAttackCoroutine { get; set; }
public Vector3 DefensePos { get; set; }
protected bool isAttacking;
2023-08-08 07:53:35 +00:00
2023-08-29 03:41:24 +00:00
protected Transform backpackContainer;
protected Transform leftWeaponContainer;
protected Transform leftShieldContainer;
protected Transform headContainer;
protected Transform rightWeaponContainer;
protected Transform bodyContainer;
protected Transform flagContainer;
protected Animator aiAnimator;
2023-08-08 07:53:35 +00:00
protected NavMeshAgent navMeshAgent;
2023-09-12 14:46:57 +00:00
//private UnitController myUnitController;
//private UnitController mouseEnterUnitController;
private UnitSelection unitSelection;
private CapsuleCollider myCollider;
private LookAtConstraint lookAtConstraint;
protected CapsuleCollider hitBoxCollider;
protected CloseWeapon closeWeapon;
private static readonly int SpeedHash = Animator.StringToHash("Speed");
protected static readonly int AttackHash = Animator.StringToHash("Attack");
private static readonly int DamageHash = Animator.StringToHash("TakeDamage");
private static readonly int DeathTypeHash = Animator.StringToHash("DeathType");
private static readonly int DeathHash = Animator.StringToHash("Death");
private static readonly int ShieldHash = Animator.StringToHash("Shield");
private static readonly int OutlineColorHash = Shader.PropertyToID("_OutlineColor");
protected static readonly WaitForSeconds FindTargetWaitTime = new(0.5f);
private static readonly WaitForSeconds CheckAgentArriveTime = new(0.1f);
2023-09-12 14:46:57 +00:00
private delegate EnemyView GetAiViewDataDelegate(string viewIdx);
#endregion
#region Unity built-in function
#if UNITY_EDITOR
protected virtual void OnDrawGizmosSelected()
{
DrawGizmosInFieldOfView();
}
#endif
protected virtual void Awake()
{
2023-08-30 02:10:16 +00:00
InitComponent();
}
private void Start()
{
2023-08-30 02:10:16 +00:00
InitStart();
ExecuteFindTarget();
2023-09-11 07:16:02 +00:00
//Attack();
navMeshAgent.stoppingDistance = AiStat.AtkRange;
}
private void OnDisable()
{
RemoveIslandInfo();
StopAllCoroutines();
}
private void Update()
{
aiAnimator.SetFloat(SpeedHash, navMeshAgent.velocity.normalized.magnitude);
2023-09-11 03:41:02 +00:00
// if (!TargetTransform || !navMeshAgent.enabled) return;
//
// var distanceToTarget = Vector3.Distance(transform.position, TargetTransform.position);
//
// navMeshAgent.isStopped = distanceToTarget <= navMeshAgent.stoppingDistance;
// switch (AiStat.AttackerType)
// {
// case EAttackerType.NONE:
// break;
// case EAttackerType.OFFENSE:
// navMeshAgent.SetDestination(distanceToTarget <= AiStat.AtkRange ? transform.position : TargetTransform.position);
// break;
// case EAttackerType.DEFENSE:
// switch (AiStat.DefenseType)
// {
// case EDefenseType.NONE:
// print("AiStat.DefenseType == NONE Error");
// break;
// case EDefenseType.STRIKER:
// navMeshAgent.SetDestination(distanceToTarget <= AiStat.AtkRange ? transform.position : TargetTransform.position);
// break;
// case EDefenseType.MIDFIELDER:
// navMeshAgent.SetDestination(distanceToTarget <= AiStat.AtkRange ? transform.position : TargetTransform.position);
// break;
// case EDefenseType.DEFENDER:
// navMeshAgent.SetDestination(distanceToTarget <= AiStat.AtkRange ? transform.position : TargetTransform.position);
// break;
// case EDefenseType.KEEPER:
// break;
// default:
// throw new ArgumentOutOfRangeException();
// }
// break;
// default:
// throw new ArgumentOutOfRangeException();
// }
}
private void FixedUpdate()
2023-08-08 07:53:35 +00:00
{
UpdateLookAtTarget();
}
2023-09-12 07:41:11 +00:00
// private void OnMouseEnter()
// {
// if (AiStat.AiType == EAiType.ENEMY) return;
//
// mouseEnterUnitController = gameObject.GetComponentInParent<UnitController>();
//
// if (mouseEnterUnitController == unitSelection.SelectedUnitController) return;
//
2023-09-12 14:46:57 +00:00
// foreach (var pirateUnitStat in mouseEnterUnitController.pirateUnitStat.UnitList)
2023-09-12 07:41:11 +00:00
// {
2023-09-12 14:46:57 +00:00
// pirateUnitStat.MouseEnterHighlight();
2023-09-12 07:41:11 +00:00
// }
// }
//
// private void OnMouseExit()
// {
// if (AiStat.AiType == EAiType.ENEMY ||
// !mouseEnterUnitController || mouseEnterUnitController == unitSelection.SelectedUnitController) return;
//
2023-09-12 14:46:57 +00:00
// foreach (var pirateUnitStat in mouseEnterUnitController.pirateUnitStat.UnitList)
2023-09-12 07:41:11 +00:00
// {
2023-09-12 14:46:57 +00:00
// pirateUnitStat.ResetHighlight();
2023-09-12 07:41:11 +00:00
// }
//
// mouseEnterUnitController = null;
// }
2023-08-08 07:53:35 +00:00
#endregion
#region interface property and function
#region IAiStat
[field: Space(10f)]
[field: Title("AiStat")]
2023-09-12 14:46:57 +00:00
[field: SerializeField] public EnemyStat AiStat { get; set; } = new();
public float GetCurrentHp() => AiStat.CurrentHp;
public void SetCurrentHp(float value) => AiStat.CurrentHp = value;
public void TakeDamage(float attackerPower, float attackerShieldPenetrationRate, Vector3? attackPos = null)
{
if (attackPos != null && navMeshAgent.enabled && AiStat.AttackerType == EAttackerType.DEFENSE && !TargetTransform)
{
2023-09-04 07:31:04 +00:00
BeAttackedMovement((Vector3)attackPos);
}
// 회피 성공 체크
if (Random.Range(0, 100) < AiStat.AvoidanceRate)
{
// TODO : 회피 처리
return;
}
var finalDamage = Utils.CalcDamage(attackerPower, attackerShieldPenetrationRate, AiStat);
// 방패 막기 체크
if (finalDamage == 0f)
{
aiAnimator.SetTrigger(ShieldHash);
return;
}
var changeHp = Mathf.Max(AiStat.CurrentHp - finalDamage, 0);
SetCurrentHp(changeHp);
// 죽었는지 체크
if (changeHp == 0f)
{
RemoveIslandInfo();
StopAllCoroutines();
navMeshAgent.enabled = false;
myCollider.enabled = false;
hitBoxCollider.enabled = false;
2023-08-08 07:53:35 +00:00
var randomValue = Random.Range(0, 2);
aiAnimator.SetInteger(DeathTypeHash, randomValue);
// TODO : 죽었을 때 처리(죽는 애니메이션 이후 사라지는 효과 등)
aiAnimator.SetTrigger(DeathHash);
2023-08-08 07:53:35 +00:00
Invoke(nameof(DestroyObject), 3f);
return;
}
aiAnimator.SetTrigger(DamageHash);
}
#endregion
#region IFieldOfView
[field: Space(10f)]
[field: Title("FieldOfView")]
[field: SerializeField] public bool IsDrawGizmosInFieldOfView { get; set; } = true;
[field: SerializeField] public LayerMask TargetLayer { get; set; }
[field: SerializeField] public Collider[] ColliderWithinRange { get; set; } = new Collider[TARGET_MAX_SIZE];
[field: SerializeField] public Transform TargetTransform { get; set; }
protected const int TARGET_MAX_SIZE = 30;
public void DrawGizmosInFieldOfView()
{
if (!IsDrawGizmosInFieldOfView) return;
var myPos = transform.position;
Gizmos.color = Color.green;
2023-09-04 07:31:04 +00:00
Gizmos.DrawWireSphere(myPos, AiStat.ViewRange);
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(myPos, AiStat.DefenseRange);
if (!TargetTransform) return;
Debug.DrawLine(myPos, TargetTransform.position, Color.red);
}
public IEnumerator FindTargetInOffense()
{
while (true)
{
2023-09-04 07:31:04 +00:00
switch (AiStat.OffenseType)
{
2023-09-04 07:31:04 +00:00
case EOffenseType.NONE:
print("AiStat.OffenseType == NONE Error");
break;
2023-09-04 07:31:04 +00:00
case EOffenseType.NORMAL:
if (islandInfo.EnemyList.Count > 0)
{
2023-09-04 07:31:04 +00:00
SetNearestTargetInOffense(islandInfo.EnemyList);
}
else if (islandInfo.HouseList.Count > 0)
{
2023-09-04 07:31:04 +00:00
SetNearestTargetInOffense(islandInfo.HouseList);
}
break;
2023-09-04 07:31:04 +00:00
case EOffenseType.ONLY_HOUSE:
if (navMeshAgent.pathStatus == NavMeshPathStatus.PathPartial)
{
2023-09-04 07:31:04 +00:00
SetNearestTargetInOffense(islandInfo.TargetAllList);
}
else
{
if (islandInfo.HouseList.Count > 0)
{
2023-09-04 07:31:04 +00:00
SetNearestTargetInOffense(islandInfo.HouseList);
}
else if (islandInfo.EnemyList.Count > 0)
{
2023-09-04 07:31:04 +00:00
SetNearestTargetInOffense(islandInfo.EnemyList);
}
}
break;
default:
throw new ArgumentOutOfRangeException();
}
if (TargetTransform && navMeshAgent.enabled)
{
var distanceToTarget = Vector3.Distance(transform.position, TargetTransform.position);
navMeshAgent.isStopped = distanceToTarget <= navMeshAgent.stoppingDistance;
if (distanceToTarget > navMeshAgent.stoppingDistance)
{
navMeshAgent.SetDestination(TargetTransform.position);
}
}
yield return FindTargetWaitTime;
}
}
2023-09-04 07:31:04 +00:00
public IEnumerator FindTargetInDefense()
{
while (true)
{
switch (AiStat.DefenseType)
{
case EDefenseType.NONE:
print("AiStat.DefenseType == NONE Error");
break;
case EDefenseType.STRIKER:
SetNearestTargetInDefense(transform.position, AiStat.ViewRange);
break;
case EDefenseType.MIDFIELDER:
SetNearestTargetInDefense(transform.position, AiStat.ViewRange);
break;
case EDefenseType.DEFENDER:
2023-09-11 07:16:02 +00:00
SetNearestTargetInDefense(DefensePos, AiStat.DefenseRange);
2023-09-04 07:31:04 +00:00
break;
case EDefenseType.KEEPER:
SetNearestTargetInDefense(transform.position, AiStat.ViewRange);
break;
default:
throw new ArgumentOutOfRangeException();
}
if (TargetTransform && navMeshAgent.enabled)
{
var distanceToTarget = Vector3.Distance(transform.position, TargetTransform.position);
navMeshAgent.isStopped = distanceToTarget <= navMeshAgent.stoppingDistance;
if (distanceToTarget > navMeshAgent.stoppingDistance)
{
navMeshAgent.SetDestination(TargetTransform.position);
}
}
2023-09-04 07:31:04 +00:00
yield return FindTargetWaitTime;
}
}
public virtual void SetNearestTargetInOffense<T>(List<T> targetList)
{
if (targetList.Count <= 0) return;
var nearestTarget = targetList.OrderBy(t =>
{
2023-09-04 07:31:04 +00:00
var myPos = transform.position;
var targetTransform = (Transform)(object)t;
if (!targetTransform)
{
return float.MaxValue;
}
var targetCollider = targetTransform.GetComponent<Collider>();
if (!targetCollider)
{
return float.MaxValue;
}
2023-09-04 07:31:04 +00:00
var closestPoint = targetCollider.ClosestPoint(myPos);
return Vector3.Distance(myPos, closestPoint);
})
.FirstOrDefault();
if (nearestTarget == null) return;
TargetTransform = (Transform)(object)nearestTarget;
2023-09-04 07:31:04 +00:00
}
public virtual void SetNearestTargetInDefense(Vector3 centerPos, float range)
2023-09-04 07:31:04 +00:00
{
Array.Clear(ColliderWithinRange, 0, TARGET_MAX_SIZE);
var maxColliderCount = Physics.OverlapSphereNonAlloc(centerPos, range, ColliderWithinRange,
TargetLayer, QueryTriggerInteraction.Collide);
if (maxColliderCount <= 0)
{
TargetTransform = null;
return;
}
var nearestDistance = Mathf.Infinity;
Transform nearestTargetTransform = null;
for (var i = 0; i < maxColliderCount; i++)
{
var distanceToTarget = Vector3.Distance(transform.position, ColliderWithinRange[i].transform.position);
if (distanceToTarget >= nearestDistance) continue;
nearestDistance = distanceToTarget;
nearestTargetTransform = ColliderWithinRange[i].transform;
}
TargetTransform = nearestTargetTransform;
}
public virtual void UpdateLookAtTarget()
{
if (CanAttack())
{
navMeshAgent.updateRotation = false;
var targetPos = TargetTransform.position;
targetPos.y = transform.position.y;
transform.LookAt(targetPos);
}
else
{
navMeshAgent.updateRotation = true;
}
}
#endregion
#region IAiMover
[field: Space(10f)]
2023-08-16 05:40:33 +00:00
[field: Title("AiMover")]
[field: SerializeField] public bool IsCommanded { get; set; }
public void BeAttackedMovement(Vector3 attackPos)
{
2023-09-04 07:31:04 +00:00
switch (AiStat.DefenseType)
{
2023-09-04 07:31:04 +00:00
case EDefenseType.NONE:
print("AiStat.DefenseType == NONE Error");
break;
2023-09-04 07:31:04 +00:00
case EDefenseType.STRIKER:
Utils.SetCloseDestination(navMeshAgent, attackPos, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
break;
2023-09-04 07:31:04 +00:00
case EDefenseType.MIDFIELDER:
Utils.SetCloseDestination(navMeshAgent, attackPos, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
2023-09-04 07:31:04 +00:00
break;
case EDefenseType.DEFENDER:
2023-09-11 07:16:02 +00:00
if (Vector3.Distance(DefensePos, attackPos) <= AiStat.DefenseRange)
{
Utils.SetCloseDestination(navMeshAgent, attackPos, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
}
break;
2023-09-04 07:31:04 +00:00
case EDefenseType.KEEPER:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
public void CommandMove(Vector3 targetPos)
{
StartCoroutine(CommandMoveCoroutine(targetPos));
}
public IEnumerator CommandMoveCoroutine(Vector3 targetPos)
{
while (isAttacking)
{
yield return null;
}
if (Utils.SetCloseDestination(navMeshAgent, targetPos, 0.5f, 1f))
{
IsCommanded = true;
}
while (navMeshAgent.pathPending || navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance)
{
yield return CheckAgentArriveTime;
}
IsCommanded = false;
}
#endregion
#endregion
#region Custom function
2023-08-30 02:10:16 +00:00
private void InitComponent()
{
backpackContainer = Utils.GetComponentAndAssert<Transform>(transform.
Find("Bip001/Bip001 Pelvis/Bip001 Spine/Backpack_container"));
leftWeaponContainer = Utils.GetComponentAndAssert<Transform>(transform.
Find("Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 L Clavicle/Bip001 L UpperArm/Bip001 L Forearm/Bip001 L Hand/L_hand_container"));
leftShieldContainer = Utils.GetComponentAndAssert<Transform>(transform.
Find("Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 L Clavicle/Bip001 L UpperArm/Bip001 L Forearm/Bip001 L Hand/L_shield_container"));
headContainer = Utils.GetComponentAndAssert<Transform>(transform.
Find("Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 Neck/Bip001 Head/Head_container"));
rightWeaponContainer = Utils.GetComponentAndAssert<Transform>(transform.
Find("Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 R Clavicle/Bip001 R UpperArm/Bip001 R Forearm/Bip001 R Hand/R_hand_container"));
bodyContainer = Utils.GetComponentAndAssert<Transform>(transform.
Find("Body_container"));
flagContainer = Utils.GetComponentAndAssert<Transform>(transform.
Find("Flag_container"));
aiAnimator = Utils.GetComponentAndAssert<Animator>(transform);
navMeshAgent = Utils.GetComponentAndAssert<NavMeshAgent>(transform);
2023-09-12 14:46:57 +00:00
//myUnitController = Utils.GetComponentAndAssert<UnitController>(transform.parent);
2023-08-30 02:10:16 +00:00
myCollider = Utils.GetComponentAndAssert<CapsuleCollider>(transform);
lookAtConstraint = Utils.GetComponentAndAssert<LookAtConstraint>(flagContainer);
2023-08-30 02:10:16 +00:00
hitBoxCollider = Utils.GetComponentAndAssert<CapsuleCollider>(transform.Find("HitBox"));
2023-09-04 07:31:04 +00:00
unitSelection = Utils.GetComponentAndAssert<UnitSelection>(UnitManager.Inst.transform);
if (Camera.main != null)
{
var source = new ConstraintSource
{
sourceTransform = Camera.main.transform,
weight = 1f
};
lookAtConstraint.AddSource(source);
}
lookAtConstraint.constraintActive = true;
2023-08-30 02:10:16 +00:00
}
private void InitStart()
{
var getAiViewData = GetAiViewData(false);
InitViewModel(false);
FindMaterial();
2023-08-30 02:10:16 +00:00
SetLayer();
SetCloseWeapon(getAiViewData);
2023-08-30 02:10:16 +00:00
SetCurrentHp(AiStat.MaxHp);
SetMoveSpeed(AiStat.MoveSpd);
2023-09-04 07:31:04 +00:00
2023-09-11 07:16:02 +00:00
DefensePos = transform.position;
2023-08-30 02:10:16 +00:00
}
private void InitViewModel(bool isEditor)
2023-08-29 03:41:24 +00:00
{
var getAiViewData = GetAiViewData(isEditor);
SetActiveViewModel(backpackContainer, getAiViewData(AiStat.ViewIdx).Backpack);
SetActiveViewModel(leftWeaponContainer, getAiViewData(AiStat.ViewIdx).LeftWeapon);
SetActiveViewModel(leftShieldContainer, getAiViewData(AiStat.ViewIdx).LeftShield);
SetActiveViewModel(headContainer, getAiViewData(AiStat.ViewIdx).Head);
SetActiveViewModel(rightWeaponContainer, getAiViewData(AiStat.ViewIdx).RightWeapon);
SetActiveViewModel(bodyContainer, getAiViewData(AiStat.ViewIdx).Body);
SetActiveViewModel(flagContainer, getAiViewData(AiStat.ViewIdx).Flag);
}
2023-08-29 03:41:24 +00:00
private void SetCloseWeapon(GetAiViewDataDelegate getAiViewData)
{
if (getAiViewData(AiStat.ViewIdx).RightWeapon == -1) return;
2023-08-29 03:41:24 +00:00
closeWeapon = rightWeaponContainer.GetChild(getAiViewData(AiStat.ViewIdx).RightWeapon).AddComponent<CloseWeapon>();
2023-08-29 03:41:24 +00:00
closeWeapon.gameObject.layer = LayerMask.NameToLayer("Weapon");
2023-09-12 07:41:11 +00:00
//closeWeapon.SetAttackerAiType(AiStat.AiType);
closeWeapon.SetBoxCollider();
2023-08-29 03:41:24 +00:00
}
2023-09-12 14:46:57 +00:00
private GetAiViewDataDelegate GetAiViewData(bool isEditor) => isEditor ? DataManager.Inst.GetEnemyViewSoFromKey : DataManager.Inst.GetEnemyViewDictionaryFromKey;
2023-08-30 02:10:16 +00:00
#if UNITY_EDITOR
public void InitStartInEditor()
{
var getAiViewData = GetAiViewData(true);
2023-08-30 02:10:16 +00:00
InitComponent();
InitViewModel(true);
2023-08-30 02:10:16 +00:00
SetLayer();
SetCloseWeapon(getAiViewData);
2023-08-30 02:10:16 +00:00
SetCurrentHp(AiStat.MaxHp);
SetMoveSpeed(AiStat.MoveSpd);
}
#endif
public void ExecuteFindTarget()
{
2023-09-04 07:31:04 +00:00
switch (AiStat.AttackerType)
{
2023-09-04 07:31:04 +00:00
case EAttackerType.NONE:
print("AiStat.AttackerType == NONE Error");
break;
2023-09-04 07:31:04 +00:00
case EAttackerType.OFFENSE:
StartCoroutine(nameof(FindTargetInOffense));
break;
2023-09-04 07:31:04 +00:00
case EAttackerType.DEFENSE:
StartCoroutine(nameof(FindTargetInDefense));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
2023-08-29 03:41:24 +00:00
private void SetActiveViewModel(Transform container, int model)
{
foreach (Transform item in container)
{
if (!item.gameObject.activeSelf) continue;
item.gameObject.SetActive(false);
}
if (model != -1)
{
container.GetChild(model).gameObject.SetActive(true);
}
}
2023-09-11 07:16:02 +00:00
public virtual void Attack()
{
2023-09-11 07:16:02 +00:00
IsAttackCoroutine = true;
StartCoroutine(nameof(AttackAnimation));
}
2023-09-11 03:41:02 +00:00
protected virtual IEnumerator AttackAnimation()
{
2023-09-11 07:16:02 +00:00
closeWeapon.SetIsAttacked(false);
closeWeapon.SetAttackerStat(AiStat);
aiAnimator.SetTrigger(AttackHash);
2023-09-11 07:16:02 +00:00
while (isAttacking)
{
yield return null;
}
2023-09-11 07:16:02 +00:00
yield return new WaitForSeconds(AiStat.AtkCooldown);
IsAttackCoroutine = false;
}
protected virtual bool CanAttack()
{
2023-09-04 07:31:04 +00:00
switch (AiStat.AttackerType)
{
case EAttackerType.NONE:
print("AiStat.AttackerType == NONE Error");
return false;
case EAttackerType.OFFENSE:
if (!TargetTransform || !islandInfo.TargetAllList.Contains(TargetTransform)) return false;
break;
case EAttackerType.DEFENSE:
if (!TargetTransform) return false;
break;
default:
throw new ArgumentOutOfRangeException();
}
var targetInAttackRange = Vector3.Distance(transform.position, TargetTransform.position) <=
AiStat.AtkRange;
return targetInAttackRange;
}
private void FindMaterial()
{
var skinnedMeshRenderers = GetComponentsInChildren<SkinnedMeshRenderer>();
var meshRenderers = GetComponentsInChildren<MeshRenderer>();
foreach (var skin in skinnedMeshRenderers)
{
if (!skin.gameObject.activeSelf) continue;
skinMaterialList.Add(skin.material);
}
foreach (var skin in meshRenderers)
{
if (!skin.gameObject.activeSelf) continue;
skinMaterialList.Add(skin.material);
}
}
private void SetOutlineColor(Color color)
{
foreach (var skin in skinMaterialList)
{
skin.SetColor(OutlineColorHash, color);
}
}
private void RemoveIslandInfo()
{
2023-09-11 07:16:02 +00:00
if (islandInfo == null) return;
islandInfo.RemoveListElement(islandInfo.EnemyList, transform);
}
private void SetAgentIsStopped(bool value)
{
if (navMeshAgent.enabled)
{
navMeshAgent.isStopped = value;
}
}
2023-08-30 02:10:16 +00:00
protected virtual void SetLayer()
{
2023-09-12 07:41:11 +00:00
// switch (AiStat.AiType)
// {
// case EAiType.NONE:
// print("AiStat.AiType == NONE Error");
// break;
// case EAiType.PLAYER:
// gameObject.layer = LayerMask.NameToLayer("Player");
// hitBoxCollider.gameObject.layer = LayerMask.NameToLayer("HitBox");
// hitBoxCollider.gameObject.tag = "Player";
// TargetLayer = LayerMask.GetMask("Enemy");
// break;
// case EAiType.PIRATE:
// gameObject.layer = LayerMask.NameToLayer("Pirate");
// hitBoxCollider.gameObject.layer = LayerMask.NameToLayer("HitBox");
// hitBoxCollider.gameObject.tag = "Pirate";
// TargetLayer = LayerMask.GetMask("Enemy");
// break;
// case EAiType.ENEMY:
// gameObject.layer = LayerMask.NameToLayer("Enemy");
// hitBoxCollider.gameObject.layer = LayerMask.NameToLayer("HitBox");
// hitBoxCollider.gameObject.tag = "Enemy";
// TargetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate");
// break;
// default:
// throw new ArgumentOutOfRangeException();
// }
//
// if (AiStat.AttackerType == EAttackerType.OFFENSE)
// {
// TargetLayer |= LayerMask.GetMask("Props");
// }
2023-08-30 02:10:16 +00:00
}
2023-09-11 07:16:02 +00:00
public IslandInfo GetIslandInfo() => islandInfo;
public void SetIslandInfo(IslandInfo info) => islandInfo = info;
2023-09-04 07:31:04 +00:00
public void SetAttackerType(EAttackerType type) => AiStat.AttackerType = type;
public void SetOffenseType(EOffenseType type) => AiStat.OffenseType = type;
public void SetDefenseType(EDefenseType type) => AiStat.DefenseType = type;
public void SetCloseWeaponCanAttack(int boolValue) => closeWeapon.SetCanAttack(boolValue == 1);
public void ResetHighlight() => SetOutlineColor(defaultSkinColor);
public void MouseEnterHighlight() => SetOutlineColor(mouseEnterHighlightSkinColor);
public void SelectedHighlight() => SetOutlineColor(selectedSkinColor);
private void DestroyObject() => Destroy(gameObject);
public void OnAttacking(int boolValue) => isAttacking = boolValue == 1;
2023-08-08 07:53:35 +00:00
public NavMeshAgent GetNavMeshAgent() => navMeshAgent;
public Animator GetAnimator() => aiAnimator;
public void SetMoveSpeed(float value) => navMeshAgent.speed = value;
#endregion
}
}