지난 벽 피하기에서는 가중치에 의한 행위를 섞었다. 가만 가중치에 의한 행위는 가중치가 큰 행위가 가중치가 가장 작은 행위를 희미하게 만들기에 행위를 섞기에는 충분하지 못하다. 그래서 고순위부터 저순위까지 순차적으로 적용되는 우선순위 기반의 행위 섞기가 필요하다. 이건 기본 골조인 AgentBehaviour와 Agent 클래스를 변경해야한다. AgentBehaviour.cs // 모든 행위의 기본 클래스 public class AgentBehaviour : MonoBehaviour { public GameObject target; // 에이전트가 주시하고 있는 대상 protected Agent agent; // 행위를 조작할 에이전트 public float weight = 1.0f; // 행위 가중치 p..
Unity/Unity_AI
1. 벽 피하기 (AvoidWall) 이 행위는 정면으로 레이를 쏘고 레이에 히트가 있다면 해당 히트의 법선 벡터로 회피 행동을 수행합니다. 단순 벽을 향하면 팅겨져 나오기만 하기에 다른 행위와 섞어서 사용해야 의미가 있습니다. AvoidWall.cs // 벽을 회피합니다. public class AvoidWall : Seek { public float avoidDistance; // 벽과 충돌하려 할때 벽에게서 멀어지는 거리 public float lookAhead; // 내가 가는 방향의 레이 길이 public override void Awake() { base.Awake(); target = new GameObject(); // 실제로 따라가게 될 타겟 } public override Steerin..
1. 대상 회피(AvoidAgent) 피해야할 모든 대상을 순회하기에 연산량이 많습니다. 모든 대상의 위치와 방향, 속도를 이용해서 자신과 충돌할지 안할지를 체크합니다. 첫번째로 충돌할 대상을 찾은뒤 해당 대상에서 멀어지는 행동을 반복합니다. // 대상을 회피한다. public class AvoidAgent : AgentBehaviour { public float collisionRadius = 0.4f; GameObject[] targets; // 회피할 오브젝트들 void Start() { // 회피할 대상은 'Agent' 태그가 붙은 게임 오브젝트 (Agent 컴포넌트가 있어야함) targets = GameObject.FindGameObjectsWithTag("Agent"); } // 회피할 에이전..
1. 경로 추적하기(PathFollower) 경로를 추적하기 위해서는 에이전트가 추적할 경로가 필요하다. 경로는 출발지점과 도착지점을 가지는 데이터와 해당데이터를 관리하는 경로 클래스가 있다. PathSegment.cs // 경로를 나타내는 데이터 타입 public class PathSegment { public Vector3 a; // 출발 지점 public Vector3 b; // 도착 지점 public PathSegment() : this(Vector3.zero, Vector3.zero) { } public PathSegment(Vector3 a, Vector3 b) { this.a = a; this.b = b; } } Path.cs // 경로를 관리하는 클래스 public class Path : ..
1. 주변 배회 (Wander) 에이전트가 무작위 지점으로 배회할 수 있도록 만든다. 우선 디버그용으로 Align의 디버그 함수들을 수정합니다. 디버그용 라인을 그리는 함수라 안해줘도 무방 // 회전각을 통한 바라보는 방향을 구합니다. protected Vector3 DirFromAngle(float angle) { angle += transform.eulerAngles.y; return new Vector3(Mathf.Sin(angle * Mathf.Deg2Rad), 0, Mathf.Cos(angle * Mathf.Deg2Rad)); } // 회전각을 보기좋게 디버그 라인으로 만듭니다. protected void DrawDebugLine(float angle, Color color, float Dist..
1. 도착 (Arrive) 방향 계산 후 도착 반경과 점차 느려지는 반경을 통해 속도 값을 전속력에서 0까지 조절합니다. public class Arrive : AgentBehaviour { public float targetRadius; // 멈춰 서야하는 반경 public float slowRadius; // 멈출때까지 점차 느려질 반경 public override Steering GetSteering() { Steering steering = new Steering(); Vector3 direction = target.transform.position - transform.position; // 방향은 Agnet가 타겟을 바라보는 방향 float distance = direction.magnitud..
1. 예상 추적 (Pursue) 원래 예상 추적이라고하지 않지만 Seek과의 차이를 두기위해 예상 추적이라고 한다. 왜 예상이 붙나면 대상 에이전트의 속도와 예상시간을 두어 대상이 도착할 위치로 추적하기 때문이다. 다만 이또한 거리 계산이 없어서 대상을 지나친다. // 예상 추적 행동 public class Pursue : Seek { public float maxPrediction; // 최대 예상시간 private GameObject targetAux; // 타겟 보조 오브젝트 private Agent targetAgent; // 타겟 에이전트 public override void Awake() { base.Awake(); targetAgent = target.GetComponent(); // 타겟이..
1. 추적 (Seek) 대상 오브젝트를 추적하는 가장 기본적인 행위이다. 에이전트의 가속도 값을 가져온뒤 정규화 후 에이전트의 이동 벡터에 계속해서 더해주기 때문에 에이전트의 이동 벡터가 에이전트의 최대속도까지 도달하는것을 볼 수 있다. 다만 거리 계산이 따로 없어 대상을 지나친다. // 추적 행동 public class Seek : AgentBehaviour { public override Steering GetSteering() { Steering steering = new Steering(); steering.linear = target.transform.position - transform.position; // 방향은 Agnet가 타겟을 바라보는 방향 steering.linear.Normaliz..
아래의 기본 골자를 통해 앞으로의 행위들을 만들게 된다. 행위가 하는 행동이 많아질수록 계속해서 변경될 예정 1. Steering.cs 에이전트의 이동 및 회전을 저장하기 위한 데이터 유형 // Agent의 이동 및 회전 값을 가지고 있다. public class Steering { public float angular; public Vector3 linear; public Steering() { angular = 0.0f; // 회전값 linear = new Vector3(); // 어디로 이동할지 } } 2. AgentBehaviour.cs 에이전트를 조작하는 행위의 기본 클래스 // 모든 행위의 기본 클래스 public class AgentBehaviour : MonoBehaviour { publi..