

도망치기의 기본적인 개념은 피해야 하는 물체( 여기선 초록색 원통 ) 을 발견했을 때 Agent에서 초록색 원통까지의 벡터 "V" 을 구하고 그 반대 방향인 "-V" 로 이동시키는 것이다.
도망칠때는 두가지 속성을 고려할 수 있다.
피하고자 하는 물체와 어느정도 가까워졌을때 도망치기 시작할것인지

물체와 어느정도 떨어지고 나서 도망치기를 멈출 것인지

먼저 피하고자 하는 물체를 편하게 화면에 배치하기 위해
public class DropBadThing : MonoBehaviour
{
public GameObject obstacle;
public Action<Vector3> callDetectNewObstacle;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
// MousePosition 값으로 Ray 발사
RaycastHit hitInfo;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// Ray가 무언가에 맞았을 경우
if (Physics.Raycast(ray.origin, ray.direction, out hitInfo))
{
// 피해야할 물체 생성
Instantiate(obstacle, hitInfo.point, obstacle.transform.rotation);
// agent를 하나씩 불러와 도망가게 하는 함수 호출
callDetectNewObstacle?.Invoke(hitInfo.point);
}
}
}
}
다음과 같은 코드를 작성하였다.
마우스 좌클릭을 하면 Ray을 발사해 Ray에 맞은 바닥면의 좌표에 피하고자 하는 오브젝트를 생성하는 것이다.
Action 을 생성하고 Agent 들이 이를 구독하게 해서 Obstacle이 생성 됐을때 Agent 들이 도망가도록 할 것이다.

아래는 Agent에 들어있는 코드이다.
// Action 구독
dropBadThing = GameObject.Find("DropBadThing").GetComponent<DropBadThing>();
dropBadThing.callDetectNewObstacle += DetectNewObstacle;
DropBadThing 에 있는 Action을 구독하도록 하였다.
이제 DropBadThing에서 Obstacle 을 생성하면 DetectNewObstacle() 함수가 자동으로 실행될 것이다.
public void DetectNewObstacle(Vector3 position)
{
if (Vector3.Distance(position, transform.position) < detectionRadius)
{
// 도망칠 최종 위치 계산
Vector3 fleeDirection = (transform.position - position).normalized;
Vector3 newGoal = transform.position + fleeDirection * fleeRadius;
// 경로 계산
NavMeshPath path = new NavMeshPath();
agent.CalculatePath(newGoal, path);
// 경로가 유효한지 확인
if (path.status != NavMeshPathStatus.PathInvalid)
{
agent.SetDestination(path.corners[path.corners.Length - 1]);
animator.SetTrigger("isRunning");
agent.speed = 10;
agent.angularSpeed = 500;
}
}
}
위의 코드가 Agent 들이 Obstacle을 피하게 하는 코드이다.
Obstacle과 Agent 와의 거리를 구하고 detectionRadius 보다 작으면 도망을 간다.
도망치는 방향은 현재위치에서 Obstacle의 위치를 뺀 단위벡터이고
최종 도망칠 지점은 현재 위치에 도망칠 방향 * 도망칠 거리를 곱한 값이다.
그 다음 새로운 경로를 설정해 그곳으로 달려가는데,
이때 경로가 유효하지 않을 수 있으므로 ( 그 쪽에 땅이 없다거나 )
유효할때만 실행하도록 하였다.

Obstacle이 생성될때 한번만 도망치는 함수가 실행되기 때문에 그 이후로는 캐릭터들이 피하지 않는다.