이번에는 지난 강좌에 이어서 투표로 결정된 추방자가 추방되는 연출을 추가하고 추방된 플레이어가 죽는 기능을 추가해보도록 하겠습니다.
본 작업에 들어가기 전에 영상 하단의 링크에서 리소스를 다운로드 받아서 임포트해줍니다.
추방 UI 배치
바로 직전 강좌에서는 투표 직후에 누가 표를 많이 받았는지 보여주는 결과까지 구현했으니 이제 투표 결과로 표를 많이 받은 플레이어를 추방하는 UI를 추가할 차례입니다.
Gameplay 씬에서 Canvas 오브젝트 아래에 이미지 오브젝트를 하나 생성하고 Ejection UI 라는 이름을 붙여줍니다.
그리고 이 이미지가 화면 전체를 덮도록 만들어주고 색을 검은 색으로 만들어 줍니다.
그 다음에는 이 이미지 아래에 텍스트 오브젝트를 만들고 글자 색과 글자 크기를 적당하게 지정해줍니다.
그리고 이미지 오브젝트를 하나 더 생성하고 방금 전에 임포트한 이미지를 넣어주고 머티리얼과 위치를 설정해줍니다.
마지막으로 추방된 플레이어 이미지가 날아갈 경로의 왼쪽 끝과 오른쪽 끝을 표시하는 오브젝트를 배치합니다.
추방 UI 기능 구현
UI 배치를 마친 다음에는 기능을 만들 차례입니다.
EjectionUI라는 이름으로 C# 스크립트를 생성하고 스크립트 에디터를 엽니다.
스크립트 에디터가 열리고 나면 먼저 스크립트 상단에 UnityEngine.UI 네임스페이스를 using 선언해줍니다.
그리고 EjectionUI 클래스의 멤버 변수로 Text 타입의 ejectionResultText과 Image 타입의 ejectionPlayer를 선언해줍니다.
그 다음에는 추방된 플레이어 이미지가 날아갈 경로의 왼쪽 끝과 오른쪽 끝 위치를 담을 RectTransform 타입의 left와 right 변수를 선언합니다.
먼저 Start 함수를 만들고 ejectionPlayer 이미지의 머티리얼을 인스턴스화 해줍니다.
그 다음에는 Open 함수를 만들고 추방당할 플레이어가 있는지를 뜻하는 bool 타입의 isEjection, 추방당한 플레이어의 색상을 표현할 EPlayerColor 타입의 ejectionPlayerColor, 추방당한 플레이어가 임포스터인지 알려주는 bool 타입의 isImposter, 남아있는 임포스터의 수를 알려주는 int 타입의 remainImposterCount를 매개변수로 선언해줍니다.
이 함수에서는 먼저 isEjection 값에 따라서 출력될 텍스트를 만들어 주고 난 다음 오브젝트를 활성화시켜줍니다.
그 다음에는 ShowEjectionResult_Coroutine 함수를 만듭니다.
여기서는 글자가 순서대로 촤라락 보여지는 기능을 만들기 위해서 텍스트를 앞부분과 뒷부분으로 나눠줄 겁니다.
먼저 추방되는 플레이어의 여부에 따라서 플레이어 이미지의 색을 결정해줍니다.
그 다음에는 추방되는 캐릭터 이미지를 회전시키면서 날아가도록 코드를 작성합니다.
그리고 적당한 딜레이를 주면서 글자를 순서대로 출력하도록 만들어 줍니다.
코루틴 함수를 모두 작성한 다음에는 이 코루틴 함수를 Open 함수에서 호출하도록 만들어줍니다.
마지막으로 Close 함수를 만들어서 EjectionUI를 닫도록 코드를 작성합니다.
그 다음 작업으로는 투표가 끝난 이후에 이 EjectionUI를 호출해줘야 합니다.
우선 이 EjectionUI로 접근하기 쉽도록 IngameUIManager로 이동해서 EjectionUI를 캐싱해서 프로퍼티로 불러올 수 있도록 만들어 줍니다.
그 다음에는 GameSystem 스크립트를 열고 MeetingProcess_Coroutine 함수로 이동합니다.
이 코루틴 함수의 아래에 CalculateVoteResult_Coroutine 함수를 만들어 줍니다.
CalculateVoteResult_Coroutine 함수에서는 투표 결과를 계산해야 하는데 먼저 어느 플레이어가 가장 많은 표를 받았는지 확인해야 합니다.
플레이어들이 받은 표를 계산하여 정렬시키기 위해 IComparer 인터페이스를 상속받아서 CharacterVoteComparer라는 이름으로 클래스를 만들어줍니다.
IComparer 인터페이스를 상속받아서 Compare 함수를 구현하면 배열을 빠르게 정렬할 수 있습니다.
Comparer를 만든 다음에는 CalculateVoteResult_Coroutine 함수로 돌아가서 System.Array.Sort 함수에 players 배열과 방금 만든 CharacterVoteComparer를 넣어서 플레이어들을 받은 표 순서대로 정렬해줍니다.
그리고 남은 임포스터 수를 구해두고 제일 처음에는 표를 가장 많이 받은 플레이어의 받은 표 수와 스킵 표 수를 비교합니다.
스킵 표 수가 가장 많이 받은 표 수보다 많거나 같다면 플레이어는 추방당하지 않습니다.
그리고 가장 많은 표를 받은 플레이어와 2순위 플레이어가 동률인 경우도 추방이 이루어지지 않습니다.
마지막으로 스킵 표와 2순위 표보다 1순위 표가 많은 경우에는 1순위 플레이어를 추방해야 합니다.
이 CalculateVoteResult_Coroutine 함수는 서버에서 호출될 예정이기 때문에 클라이언트에서 EjectionUI를 열도록 만들어둘 RpcOpenEjectionUI 함수를 만들고 ClientRpc 어트리뷰트를 붙여줍니다.
그리고 여기서는 IngameUIManager를 통해서 EjectionUI에 접근해서 Open 함수를 호출해줍니다.
그 다음에는 CalculateVoteResult_Coroutine 함수로 돌아가서 각 상황에 맞게 RpcOpenEjectionUI 함수를 호출해줍니다.
RpcOpenEjectionUI 함수를 호출한 다음에는 플레이어가 추방당하는 분기에서 추방당한 플레이어를 죽음 처리해줘야 합니다.
Dead 함수를 호출하면 될 것 같은데, 현재 이 Dead 함수는 크루원이 임포스터에게 죽는 것을 전제로만 동작하게 되어 있으니 조금 수정이 필요해보입니다.
Dead 함수로 이동해서 매개변수에 bool 타입의 isEject 매개변수를 추가해주고 시체를 만드는 부분을 if문으로 묶어서 추방으로 죽은게 아닐 때만 동작하도록 만들어줍니다.
그리고 아래의 RpcDead 함수에도 같은 매개변수를 추가하고 KillUI가 isEject가 아닐 때만 호출되도록 수정해줍니다.
그리고 이 Dead 함수를 수정함으로써 발생하는 에러 역시 모두 수정해줍니다.
수정이 모두 끝나면 CalculateVoteResult_Coroutine 함수로 돌아가서 가장 많은 표를 받은 플레이어의 Dead 함수를 호출해주고 사망한 크루원의 시체들을 찾아서 제거해줍니다.
추방 작업이 끝나고나면 플레이어들이 다시 테이블 근처에 원형으로 배치되도록 만들어줘야 합니다.
GameReady 코루틴 함수를 보면 캐릭터들을 원형 테이블 근처에 배치하는 코드가 있을 겁니다.
이 코드를 블럭 선택해서 우클릭하고 [빠른 작업 및 리팩터링] 항목을 선택해서 [메서드 추출]로 새 함수로 만들어 줍니다.
그리고 이 함수를 CalculateVoteResult_Coroutine 함수에서 호출해줍니다.
그 다음에는 클라이언트에서 EjectionUI를 닫게 만들어줄 RpcCloseEjectionUI 함수를 만들고 ClientRpc 어트리뷰트를 붙여준 다음 EjectionUI의 Close 함수를 호출하게 만들어줍니다.
그리고 다시 플레이어의 캐릭터가 움직일 수 있게 myCharacter의 IsMoveable을 true로 바꿔줍니다.
완성된 RpcCloseEjectionUI 함수는 CalculateVoteResult_Coroutine 함수에서 모든 작업이 끝나고 일정 시간이 지나면 호출되게 만들어줍니다.
그리고 CalculateVoteResult_Coroutine 함수를 MeetingProcess_Coroutine 함수의 제일 아래에서 호출해줍니다.
아 마지막으로 MeetingUI가 닫히도록 만들어주기 위해서 MeetingUI 스크립트로 이동해서 Close 함수를 만들어주고 GameSystem의 RpcOpenEjectionUI 함수에서 호출해줍니다.
코드를 모두 작성한 다음에는 저장하고 에디터로 돌아갑니다.
씬 세팅과 테스트
에디터로 돌아온 다음에는 EjectionUI 오브젝트에 방금 생성한 컴포넌트를 부착하고 프로퍼티를 할당해줍니다.
그리고 캔버스에 붙어있는 IngameUIManager에 EjectionUI를 캐싱해줍니다.
작업이 끝난 다음에는 게임을 빌드해줍니다.
빌드가 완료되면 게임을 실행하고 테스트합니다.
테스트 해보면 아무도 추방하지 않은 경우, 임포스터가 아닌 플레이어를 추방했을 경우, 임포스터인 플레이어를 추방했을 경우, 모두 다른 문구가 나오는 것을 볼 수 있습니다.
아웃트로
이번에는 어몽어스 게임에서 투표 후에 플레이어가 추방되는 UI 연출과 그 처리를 해보았습니다.
이 강좌는 시청자 여러분들의 시청과 후원으로 제작되었습니다.
이상 베르의 게임 개발 유튜브였습니다. 감사합니다.
[유니티 어필리에이트 프로그램]
아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.
이런 방식으로 3개의 숫자로 버전을 표시하는 방식을 시맨틱 버전 분류법, 번역하면 유의적 버전 분류법이라고 합니다.
이 3개의 숫자 중에 첫 번째 숫자를 메이저(Major) 버전이라고 하고 이전 버전과 호환이 되지 않게 기능이 바뀌거나 추가되면 변경되는 숫자입니다.
두 번째 숫자는 마이너(Minor) 버전이라고 하고 이전 버전과 호환되면서 새로운 기능이 추가되면 변경되는 숫자입니다.
그리고 세 번째 숫자는 패치(Patch) 버전이라고 하고 이전 버전과 호환되면서 버그를 수정한 것이라면 변경되는 숫자입니다.
최신 버전의 유니티 엔진은 메이저 버전을 연도로 표시합니다.
이 부분은 앞에서 이야기 했듯이 유니티 측에서 매년 새로운 혁신을 이루어 내겠다는 포부로 볼 수 있지만, 약간의 문제는 업데이트 일정이 조금씩 밀리면서 연도 버전과 실제 연도가 일치하지 않는 경우가 현재 발생하고 있습니다.
이 버전 불일치 문제는 유니티 측에서도 인지하고 있고, 업데이트 일정을 조절해서 맞출 예정이라고 합니다.
그리고 두 번째 숫자인 마이너 버전은 유니티 5까지는 일관성이 없었지만 2017~2019까지는 1~4 사이의 숫자를 사용했습니다.
이 마이너 버전 1은 아직 에디터가 안정화되지 않은 베타 버전으로 안정화 단계에 따라서 버전이 올라가고 가장 안정화된 상태에서 장기 지원을 하는 버전에 버전 넘버 4를 붙여줍니다.
그리고 2020 버전이 이후에는 연도와 버전 넘버의 불일치를 되돌리기 위해 1~3까지만 버전 넘버를 사용하여 버전 넘버 3을 장기 지원 버전으로 하도록 변경했습니다.
그리고 마지막 패치 버전은 유니티 에디터에 자잘한 버그를 수정할 때마다 계속해서 올라가도록 되어 있습니다.
이런 버전 분류 방식으로 인해서 게임 개발 중인 유니티 프로젝트의 에디터 버전을 올릴 때는가급적이면 패치 버전과 마이너 버전까지만 올리도록 하고 메이저 버전을 바꿔야 한다면 프로젝트를 반드시 백업한 뒤에 버전을 올려서 문제가 없는지 확인해야 합니다.
LTS
그 다음으로 살펴볼 부분은 LTS입니다.
유니티 허브에서 다른 버전의 에디터를 설치하기 위해서 에디터 설치 버튼을 눌러보면 2020.3, 2019.4, 2018.4 버전 뒤에 LTS 라는 약자가 붙어있습니다.
버전 뒤에 붙어있는 이 LTS는 Long Term Support의 약자로 우리 말로는 장기 지원 버전이라고 합니다.
이런 장기 지원 버전은 연도 버전이 바뀐 이후에도 해당 연도의 LTS 버전이 최초로 릴리스된 날짜로부터 2년간 계속해서 매월 업데이트됩니다.
이런 식으로 장기 지원 버전을 만들어서 계속 업데이트를 해주는 이유는 이미 예전 버전의 에디터로 계속해서 진행해오던 프로젝트가 유니티 에디터의 바뀐 메이저 버전을 따라 무작정 버전을 올리면 어떤 문제가 발생할지 알 수 없기 때문에 이전 버전으로 개발하는 개발자들이 최대한 안정적으로 개발을 이어나갈 수 있게 하기 위해서 입니다.
그리고 유니티 엔진은 끊임없이 업데이트되는데, 버전 넘버링 중에 가장 앞자리인 연도 버전이 바뀔 때마다 유니티는 가장 많은 변화를 겪게 됩니다.
하지만 이 연도 버전이 처음 나온 시점인 1버전이나 2버전에서는 새로운 기능이 대거 들어와서 엔진이 조금 불안정한 상태가 됩니다.
그래서 새로운 연도 넘버링의 엔진은 곧바로 게임 개발에 사용하는 것보다는 새 버전의 엔진에 들어오는 기능을 테스트 해보는 용도로 사용하는 것이 좋습니다.
그리고 정식으로 게임을 개발할 때는 가장 최신의 LTS 버전인 에디터를 설치해서 개발하는 것을 추천합니다.
아웃트로
이번 영상에서는 유니티의 버전 넘버링과 LTS에 대해서 알아보았습니다.
이 강좌는 여러분들의 시청과 후원으로 제작되었습니다.
이상 베르의 게임 개발 유튜브였습니다. 감사합니다.
[유니티 어필리에이트 프로그램]
아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.