플레이어를 쫓아다니는 몬스터 AI 구현
2024. 7. 4. 19:17ㆍUnity/Unity 학습정리
- StatMachine분리
- 분리를 하지 않았을 때 문제점
- 대부분의 기능을 공유하는 두 클래스에서 상속을 받았을때 BaseMonster의 상속도 받는 다는 부분이다.
- 하지만 PartnerMonster는 플레이어를 따라다니고 멀어지면 추적한다.
- EnemyMonster는 플레이어가 가까워지면 추적하고 멀어지면 다시 원래 자리로 돌아간다.
- 해결방법
public MonsterStateMachine(BaseMonster monster)
{
Monster = monster;
if (Monster.GetType() == typeof(PartnerMonster))
{
Debug.Log(Monster.GetType());
IdleState = new PartnerMonsterIdleState(this);
WalkState = new PartnerMonsterWalkState(this);
}
else if(Monster.GetType() == typeof(EnemyMonster))
{
IdleState = new EnemyMonsterIdleState(this);
WalkState = new EnemyMonsterWalkState(this);
}
DefaultState = new MonsterDefaultState(this);
AttackState = new MonsterAttackState(this);
BasicAttackState = new MonsterBasicAttackState(this);
SkillState = new MonsterSkillState(this);
HitState = new MonsterHitState(this);
}
각자 가져야하는 State를 들어오는 타입에 따라서 State를 꽃아주는 방식으로 구현
AIHandler
파트너 몬스터는 적 몬스터와 플레이어를 둘 다 탐지하고 StateMachine에 탐지 정보를 넘겨주어야한다.
- Player를 탐지 했을 때는 따라가야하는 정보를 주고
- Enemy를 탐지 했을 때는 공격하는 State로 전이
public class ParnterMonsterAIHandler : BaseMonsterAIHandler
{
private float _enemyDetectRange = 5f;
//적 몬스터 타겟
protected override void Start()
{
base.Start();
_detectRange = 2.5f;
}
//적을 탐지 로직
protected override void UpdateEnemyTarget()
{
base.UpdateEnemyTarget();
Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, _enemyDetectRange, _EnemyTarget);
if (colliders.Length > 0)
{
float closetDistance = Mathf.Infinity;
Transform closetTarget = null;
foreach (Collider2D collider in colliders)
{
float distanceToTarget = Vector2.Distance(transform.position, collider.transform.position);
//타겟이 반경안에 있다면
if (distanceToTarget < closetDistance)
{
closetDistance = distanceToTarget;
closetTarget = collider.transform;
}
if (closetTarget != null)
{
if ((1 << closetTarget.gameObject.layer) == LayerMask.GetMask("Enemy"))
{
EnemyTargetTransform = closetTarget;
}
}
else
{
//Agent.ResetPath();
EnemyTargetTransform = null;
}
}
}
else
{
EnemyTargetTransform = null;
}
}
//플레이어 탐지로직
protected override void UpdatePlayerTarget()
{
base.UpdatePlayerTarget();
Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, _detectRange, _playerTarget);
if (colliders.Length > 0)
{
float closetDistance = Mathf.Infinity;
Transform closetTarget = null;
foreach (Collider2D collider in colliders)
{
float distanceToTarget = Vector2.Distance(transform.position, collider.transform.position);
//타겟이 반경안에 있다면
if (distanceToTarget < closetDistance)
{
closetDistance = distanceToTarget;
closetTarget = collider.transform;
}
if (closetTarget != null)
{
//타겟이 플레이어라면
if ((1 << closetTarget.gameObject.layer) == LayerMask.GetMask("Player"))
{
TargetTransform = closetTarget;
//Agent.SetDestination(TargetTransform.position);
}
}
else
{
//Agent.ResetPath();
TargetTransform = null;
}
}
}
else
{
TargetTransform = null;
}
}
}
PartnerMonster 기준 일정한 원의 탐지 영역을 만들고 Layer를 체크해 정보를 전달해준다.
'Unity > Unity 학습정리' 카테고리의 다른 글
Unity - 몬스터 모드 변경 (0) | 2024.07.11 |
---|---|
Unity - Interface로 원하는 동작 해보기 (0) | 2024.07.10 |
FSM StateMachine 상속 (0) | 2024.07.01 |
Unity - Behaviour Tree (1) (0) | 2024.06.25 |
Unity - FSM(Finite State Machine)(3) (0) | 2024.06.20 |