Weekly I Learned - 5th Week [커뮤니티 게임 만들기]
이번 프로젝트는 커뮤니티 게임의 기본 형태를 구성해 보는 것이었다.
이전에는 그냥 프로젝트 만 올렸었으나, 이번 WIL 부터는 어떻게 제작하였는지도 함께 서술해 볼까 한다.
[Git URL: https://github.com/lsu0503/ProjectSpartaTown.git]
GitHub - lsu0503/ProjectSpartaTown: ProjectSpartaTown
ProjectSpartaTown. Contribute to lsu0503/ProjectSpartaTown development by creating an account on GitHub.
github.com
구현한 내용 [주요한 요소만]
- 전체적인 구성
- Input System을 이용한 플레이어 캐릭터 조작.
- Collider와 Event Action을 이용한 맵 표시 전환.
- Collider를 이용한 간단한 대화 시스템.
※ 전체적인 알고리즘 구조를 서술하기에, 코드를 별개로 기입하지는 않았습니다.
전체적인 구성
- 타일 맵을 이용한 2D 필드 제작
- 캐릭터 구성(객체 + 데이터 + 애니메이션)
- Animator Override Controller를 이용한 에니메이터 규격화
- 카메라 이동 로직 구현
Input System을 이용한 캐릭터 조작
Input System은 유니티 제공[기본 패키지 X]의 패키지로, Package Manager를 통해서 Import 해야지 쓸 수 있는 기능이다.
Hierarchy 상의 오브젝트에 Player Input 컴포넌트를 올리고 거기에 Input Actions 파일을 넣으면 해당 객체가 제작자가 Input Actions에서 규정한 입력을 활용할 수 있게 되며, 이를 MonoBehavior로 작성된 C# 스크립트 컴포넌트로 사용하는 방식이다.
입력을 활용할 때는 [XXCondition]이라는 항목을 입력에 대한 반응으로 둔다고 했을 때, OnXXCondition(val value) 메소드를 사용하면 된다.
본 프로젝트에서는 Player 캐릭터와 Camera에 사용되고 있는데, 구체적으로는 다음과 같다.
- Player 캐릭터
- wasd를 통한 입력을 Vector2 값으로 치환하여 해당 방향으로 이동한다.
- 마우스 위치를 입력값으로 받아서, 해당 위치를 바라보도록 캐릭터의 방향이 바뀐다.
- 현재 접근한 캐릭터가 있다면 E를 이용해서 대화가 가능하다.
- Camera
- 기본적으로 Player 캐릭터의 위치를 중범으로 활용한다.
- 단, 마우스가 Player 캐릭터에서 일정 거리 벌어진 경우에는 마우스 방향으로 소폭 이동한다.
이를 구현하기 위해서 하술할 Event Action 구조를 활용하였다.
Collider와 Event Action을 이용한 맵 표시 전환
Event Action은 사실, Event와 Action을 함께 쓰는 것을 이야기한 것이다.
둘 다 델리게이트의 일종으로, 각자 다음과 같은 특성을 지닌다.
※ 수정사항: Event가 복수의 함수를 등록할 수 있는 건 DeligateChaining이라는 델리게이트 기본 기능에 의한 것이다. 때문에, Event가 아니더라도 deligate라면 복수 함수를 등록할 수 있다.
[등록은 += 연산자를, 해제는 -=연산자를 사용한다.]
[만약 반환값이 있는 deligate를 복수 함수가 등록된 상태에서 사용하면, '마지막 함수의 반환값'이 도출된다.]
- Event
- 직접적인 할당과 현재 클래스 이외의 클래스에서의 호출은 불가능하다.
- Action
- 반환 타입이 void(없음)인 메소드에만 사용 가능한 제네릭 델리게이트.
- 매개변수를 0~16개 가질 수 있다.
- [추가] Func
- Action과 유사하게 매개변수를 0~16개 가질 수 있는 제네릭 델리게이트.
- 단, Action과는 반대로 반환 타입이 void가 아닌 메소드에만 사용 가능하다.
이러한 특성을 이용해서 event Action<parameter>으로 선언하면 parameter(인수)가 동일한 함수라면 모두 등록해서 함수 한 번에 등록된 함수 전체를 호출, 처리할 수 있는 구조가 된다.
이를 통해 Player 캐릭터의 Collider가 지역의 Cillider(Trigger)에 접촉한 경우, GameManager가 가지고 있는 event Action을 이용해서 Field의 ID와 비교, ID가 동일한 필드 만 활성화 하고 나머지는 비활성화 시키는 구성으로 제작하였다.
단, 복도는 -1값을 parameter로 넘겨서 모든 Field를 활성화 시키도록 구성했다.
Collider를 이용한 간단한 대화 시스템
의외로 간단하게 구성된 기능.
Collider로 NPC가 Trigger 되면, 해당 NPC의 DialogContainer(이야기 보따리) 컴포넌트를 가지고 있다가, 상술한 Input System으로 상호작용 입력이 들어오면 소지 중인 DialogContainer의 대화를 출력하는 방식으로 구성되어 있다.
단, 이 때 Collider는 캐릭터 보다 넓으면서 Trigger 상태여야 하므로, Player 캐릭터의 하위 객체로 작성했다.
마무리하며
전체적으로 event에 대해서 충실하게 익힐 수 있었던 기회가 아니었나 싶습니다.
아직 버그 검출이 익숙하지 않아서 대부분의 시간이 버그 잡는 데에 쓰였고, 정작 그렇게 찾은 버그는 그저 단순한 실수였던 지라, 이런 부분에 대해서는 더욱 익숙해져야 한다는 느낌도 함께 받았습니다.