2021-05-27~28 개발일지
근접형 버섯 몬스터 AI 제작하기
일반적인 근접형 몬스터라고 한다면 간단하게는
1. Circle 콜라이더2D 붙여서 안에 들어오면 쫓아가기
2. Physics2D.Overlap~~ 작성하여 Player Layer들어오면 쫓아가기 등이 있는데
오늘은 이것들을 좀 더 탐구해보겠습니다
하여 타 게임들을 조금 분석해보자면
1. Dead Cells
데드셀의 제일 기본적인 몬스터로는 아무래도 요놈이 있겠죠
이름이 좀비더군요
공격 패턴
1. 플레이어와의 거리가 멀다면 뛰어들며 공격
2. 플레이어와의 거리가 가깝다면 할퀴기
플레이어 인식 방법
플레이어가 같은 플랫폼에 들어오면 우선 인식 상태가 되는 것 같습니다.
플레이어가 같은 플랫폼으로 들어왔을 땐 우선 제자리에 멈추는 동작을 취합니다.
이후엔 플레이어와의 거리에 따라 근접공격 or 점프공격의 행동을 하더군요
1. 플레이어가 같은 플랫폼에 들어왔다면 => 인식 상태 (제자리에 멈춤)
2.1. 플레이어가 사다리에 매달리는 등 공격할 수 없는 위치에 있을 경우 => Idle or 가던 길 감
3.1. 플레이어와의 거리가 근거리 공격범위보다 작다면 => 할퀴기 공격
3.2. 플레이어와의 거리가 원거리 공격범위보다 작다면 => 뛰어드는 공격
4. 원거리 공격범위보다 멀리있을 경우 => 플레이어 방향으로 이동
또 공격 범위 안에 있지만 공격불가이유(플랫폼 밖에 플레이어 존재, 사다리에 매달려있음)가 있을 경우 Idle상태로 대기하는 것 같다.
Idle상태로 계속 대기하는 경우도 있고 그냥 가던 길 가는 경우도 있는데 정확하게 무엇으로 나뉘는지는 잘 모르겠다
추측해보자면, 플레이어가 인식 범위 안에 들어와서
플레이어 방향으로 이동 중
플레이어가 공격할 수 없는 위치로 간다면 Idle상태로 대기하게 되는 듯 하다.
=> 현재 상태별로 플레이어 인식 방법이나 범위가 다를 수 있다.
+ 낮은 벽을 사이에 두고 있어도 플레이어가 근접공격 내에 있다면 공격한다
Idle상태로 대기는 플레이어가 일정 거리 이상으로 멀어질때 까지 계속 진행되는 듯 한데
이럴 땐 그냥 인식상태를 벗어나 기본동작으로 나가는게 좋을 것 같다.
데드셀 게임 플레이상 왔다갔다 한번 하면 풀리니 플레이상 불편한 점은 없긴 하다.
또 한가지 행동이 있다면 기본적으로 땅의 끝, 벽을 만나면 Idle상태로 2초정도 가만히 있는다.
지금까지 본걸 토대로 생각해보면
인식 상태가 되는 조건: 적의 뒤 인식 거리, 앞 인식 거리 안에 플레이어가 들어왔을 때
좀비의 앞, 뒤 인식 거리, 근거리 공격 거리, 원거리 공격 거리 존재
이제 버섯 AI를 위해 여기서 고려해야할건
1. 플레이어가 같은 플랫폼에 들어왔는지 어떻게 체크할 것인가
2. 플레이어가 공격할 수 없는 위치에 있다는 건 어떻게 체크할 것인가
플레이어가 같은 플랫폼에 들어왔는지 어떻게 체크할 것인가
지금 당장 생각나는건 이정도..?
1.1. 적의 앞, 뒤 인식 거리에 플레이어 들어옴
1.2. 적의 아래 타일부터 플레이어 아래 타일까지 순차검색, 중간에 Ground Tile이 없다면 return
왼쪽이나 오른쪽 방향으로 타일 순차 검색이 가능할지는 구글링이 필요할 것 같다.
적 아래 타일부터 타일 offset만큼 이동하면서 플레이어 아래 타일까지만 검색하면 될듯 한데..
타일맵 검색 참고 링크
https://forum.unity.com/threads/tilemap-tile-positions-assistance.485867/
https://mrbinggrae.tistory.com/68
1.3. 플레이어 위치까지 Ground가 이어져있다면 플레이어 방향으로 이동
플레이어가 공격할 수 없는 위치에 있다는 건 어떻게 체크할 것인가
플레이어가 공격 거리 안에 있더라도 위 플랫폼에 있다던지 하면 공격을 하지 않아야한다
1.1. 공격 가능 각도를 정해놓는다
1.2. 공격 가능 범위 안에 플레이어가 있다면 플레이어와의 각도 계산
2.1. 공격 가능 각도 안이라면 공격
2.2. 공격 가능 각도 밖이라면 가던 길 감
플레이어와 적 사이의 각도를 구해보자!
두 벡터 사이의 각도를 구하는건 어렵지 않다.
두 벡터 사이의 각도를 0~360도로 표현할건지 0~90도로 표현할건지는 하고싶은대로 하면 된다
두 벡터를 빼서 해당 벡터의 Angle을 구하는 공식은 결과가 -180 ~ 180도로 나온다
resultVector = A - B;
angle = Mathf.Atan2(resultVector.y, resultVector.x) * Mathf.Rad2Deg;
이외에 내적을 이용하여 Acos으로 각도구하는 법도 있고 (0 ~ 180도)
Quaternion.FromToRotation 함수를 이용하여 구하는 법, (0 ~ 360도)
Vector3.Angle이나 (0 ~ 180도)
Vector3.SignedAngle을 사용하는 방법 등이 있다. (-180 ~ 180도)
하지만 굳이 각도를
공격 이후엔
작성 ing~