내일배움캠프 116일차 - 최종프로젝트 6일차: RTS 장르에서 건물을 짓는 법
RTS 장르에서 건물을 짓는 법
개요
| 스타크래프트1의 프로브가 건물을 짓는 방식. 영역을 확보하면 자동으로 건설된다. |
여기서부터는 보편적인 RTS장르에 대입해서 건설기능을 가진 지휘관을 '일꾼'으로 치환해서 설명하기로 한다.
일꾼과 유닛의 이동
일반적인 RTS장르에서는 '유닛'이라는 캐릭터에게 명령을 내려 행동을 취하게 할 수 있다. 가장 일반적인 이동의 작동 방식에 대해 알아보도록 하자.
| 이동좌표와 유닛 |
RTS장르는 거의 대부분이 캐릭터를 직접적으로 조작해 이동하는 것이 아닌 "명령"을 내려 이동을 유도한다. 그렇기 때문에 이동 시 델타시간 단위로 이동값을 계산해 움직이는 것이 아닌 목적지를 지정해 AI컨트롤러에게 좌표를 전송, 이동을 지시한다.
때문에 이동을 하기 위해 필요한 매개변수는 목적지가 되는 벡터좌표값이 될 것이다.
| 이동조작 시 EnhancedInput을 통해 실행되는 함수 |
| 이동 지시 함수의 일부 |
일꾼의 건설위치 선점
여기까지는 유닛들의 공통적인 이동방법을 구현한 것이다. 이제는 일꾼이 '건설'을 하기 위해 어떻게 움직여야 하는지 정해야 할 때다.
| 스타크래프트의 건설방식 |
스타크래프트의 경우에는 일꾼이 건물을 지을때는 건설좌표 중심까지 이동해 건설을 시작할 수있다. 하지만 언리얼 엔진에서는 건물과 겹치기 때문에 물리오류가 발생할 가능성이 있으므로 건물과 겹치지 않는 위치까지 이동 후 건물을 건설할 예정이다.
우선, 일꾼이 지을 건물을 임의로 정하고 지정 건물의 메시에 맞게 크기를 계산하고, 이를 토대로 건설을 위해 일꾼이 이동할 위치를 선점해보자.
건물의 메시 바운드를 GetBounds()를 가져와 박스를 그려보면 위 사진처럼 건물의 크기를 반영하게 된다. 여기서 일꾼이 건설을 하기 위해 건물과 겹치지 않으면서 건물과 가장 가까운 곳으로 이동을 하기 위한 방법의 수는 다음과 같다.1) 캐릭터가 건설구역 밖에 있다. // FBox.Intersect(CharacterBox) == false
이 경우 간단하다. 캐릭터를 건설구역의 중심으로 이동하면서 건설구역과 인접한 곳에서 이동을 멈추고 건설을 시작하면 된다.
다만, 이동 중 캐릭터와 건설경계 간의 거리를 계산하기 위해서는 건물의 Bound를 FBox로 치환해줄 필요가 있다.
FBox로 변환된 바운드는 GetClosetPointTo()라는 함수를 사용할 수 있는데, 이 함수는 임의좌표로부터 경계에 가장 가깝게 맞닿아있는 좌표를 반환해준다. 캐릭터의 현재좌표와 반환된 좌표의 거리를 계산해 일정 거리 내에 있으면 '건설할 수 있다'고 판단하는 것이다.하지만 바로 사용하기에는 무리가 있는데, FBox는 AABB(Axis-Aligned Bounding Box) 충돌형식을 채용하고 있으므로 만약 건물이 회전값이 존재한다면 실제 건설가능 좌표를 반환할 가능성은 낮다.
이에 대한 해결법은 뒤에서 설명하도록 한다.
2) 캐릭터가 건설구역 안에 있다. // FBox.IsInsideOrOn(CharacterPos) == true
※ FBox.IsInsideOrOn() 사용 시 캐릭터의 실제좌표가 건물경계보다 밑에 있을 수 있으므로 캐릭터 Z값을 조금 더해서 검사하는 것이 좋다.
캐릭터가 건설구역 내에 있을 경우, 건설 시 건물과 겹칠 우려가 있으므로 경계 밖과 가장 가까운 방향으로 이동을 하면서, 겹치지 않으면서 인접한 곳에 도달 시 건설을 시작하면 된다.이 경우 FBox의 GetClosetPointTo()를 사용할 수는 없다. 이미 FBox에 인접해 있다고 판단해 내부 좌표 그대로 반환하기 때문이다.
박스의 로컬좌표
댓글
댓글 쓰기