반응형

 

개발단에 가입하여 베르의 게임 개발 유튜브를 지원해주세요!

https://www.youtube.com/channel/UC9j3...

 

리소스 패키지 : https://drive.google.com/file/d/1jwGm...

 

안녕하세요! 여러분들과 함께 게임 개발을 공부하는 베르입니다!

이번 영상에서는 임포스터로 의심되는 플레이어에게 투표하고 추방하는 기능을 만들어 봅시다!

 

사용 엔진 버전 : 2019.4

 

타임라인

0:00 인트로

0:12 회의 UI 배치

2:56 플레이어 패널 띄우기

6:57 플레이어 패널 선택 기능 만들기

10:00 아웃트로

스크립트

인트로

안녕하세요. 여러분들과 함께 게임 개발을 공부하는 베르입니다.

이번에는 신고 이후에 플레이어들끼리 투표하고 가장 많은 표를 받은 플레이어를 추방하는 기능을 만드는 과정을 진행해보겠습니다.

회의 UI 배치

작업에 들어가기에 앞서 영상 하단의 링크에서 리소스 패키지를 다운로드 받아서 프로젝트에 임포트해줍니다.

리소스 임포트가 완료된 다음에는 회의 UI를 배치해보겠습니다.

먼저 Canvas 오브젝트 아래에 Image 게임오브젝트를 생성하고 화면 전체를 덮도록 세팅한 다음 색을 투명하게 만들어줍니다.

그 아래에는 임포트한 리소스들을 이용해서 실제 게임 화면과 유사하게 배치해줍니다.

그리고 플레이어 패널을 만들어야 합니다.

패널을 만들고 플레이어 이미지를 올린 다음 닉네임을 표시할 텍스트를 추가해줍니다.

그리고 빈 게임오브젝트를 추가하고 Horizontal Layout Group 컴포넌트와 Content Size Fitter 컴포넌트를 붙여줍니다.

그리고 Horizontal Layout Group의 Child Alignment는 Middle Left로 변경하고 Content Size Fitter의 프로퍼티는 Min Size로 변경해줍니다.

그리고 이 레이아웃 그룹 오브젝트의 Pivot X 값을 0으로 맞춰줍니다.

그러면 이 레이아웃 그룹 오브젝트 밑에 다른 플레이어가 투표했음을 표시하는 이미지를 추가하면 제대로 정렬되어서 추가되는 모습을 볼 수 있습니다.

그 다음에는 빈 게임오브젝트도 추가해서 그 아래에 투표 버튼과 취소 버튼도 올려줍니다.

그리고 투표했을 때 표시되는 UI와 죽은 플레이어에게 표시되는 부가 UI까지 올려줍니다.

플레이어 패널을 완성한 다음에는 빈 게임오브젝트를 만들고 Grid Layout Group 컴포넌트를 붙여줍니다.

그리고 Sell Size를 348x63으로 변경하고 플레이어 패널을 복제해서 2열 5행으로 배치되게 크기를 맞추고 간격을 조절해줍니다.

그리고 그 아래쪽에 Skip vote 버튼과 투표를 스킵한 플레이어를 보여주는 UI를 만들어줍니다.

투표를 스킵한 플레이어를 보여주는 UI를 만들 때는 플레이어 패널에서 다른 플레이어가 투표했음을 보여주는 UI와 똑같이 만들어주면 됩니다.

기본적인 배치를 마친 다음에는 만든 플레이어 패널과 투표 표시용 캐릭터 이미지를 프리팹으로 만들어주고 배치되어 있는 오브젝트는 삭제해줍니다.

그리고 Skipped Voting UI도 숨겨줍니다.

플레이어 패널 띄우기

이제 이 Meeting UI의 기능을 차례대로 만들어보겠습니다.

먼저 플레이어 패널에 붙일 MeetingPlayerPanel 스크립트를 생성하고 스크립트 에디터를 엽니다.

스크립트 에디터가 열리고 나면 스크립트의 상단에 UnityEngine.UI 네임스페이스를 using 선언해줍니다.

그리고 멤버 변수로 캐릭터 이미지 색을 바꾸는데 쓰일 Image 타입의 characterImg 변수와 닉네임을 표시하는데 쓰일 Text 타입의 nicknameText 변수, 죽은 플레이어를 표시할 때 사용될 GameObject 타입의 deadPlayerBlock과 신고자를 표시하기 위한 reporterSign 변수를 추가해줍니다.

그리고 어떤 플레이어의 패널인지 구분하기 위한 용도로 IngameCharacterMover 타입의 targetPlayer 변수도 만들어줍니다.

그 다음에는 SetPlayer 함수를 만들어서 characterImg의 머티리얼을 인스턴싱하고 매개변수로 받아온 캐릭터를 저장한 뒤에 캐릭터 이미지의 색을 바꾸고 닉네임을 세팅해줍니다.

그리고 임포스터인 플레이어가 다른 임포스터 플레이어의 패널을 볼 때는 이름이 빨간색으로 표시되도록 만들어줍니다.

그리고 패널의 대상이 되는 플레이어가 죽은 상태라면 플레이어 패널을 가리는 회색 패널이 켜지도록 만들어줍니다.

마지막으로는 해당 플레이어가 신고자라면 확성기 모양의 이미지가 활성화되도록 해야하는데 관련 변수가 없는 상태이니 IngameCharacterMover 클래스로 이동해서 bool 타입으로 isReporter 변수를 추가하고 SyncVar 어트리뷰트를 붙여줍니다.

그리고 아래 쪽에 있는 CmdReport 함수에서 isReporter 변수를 true로 변경하게 만들어줍니다.

다시 MeetingPlayerPanel 스크립트로 돌아와서 targetPlayer가 isReporter라면 reporterSign을 활성화시키도록 코드를 작성합니다.

코드를 모두 작성한 다음에는 저장하고 에디터로 돌아가서 Meeting Player Panel 오브젝트에 작성한 컴포넌트를 붙여줍니다.

그리고 각 프로퍼티를 할당해줍니다.

잠시 앞에서 빼먹은 확성기 모양의 신고자 표시 이미지를 추가하고 비활성화한 뒤 프로퍼티에 할당해줍니다.

그 다음에는 MeetingUI라는 이름으로 C# 스크립트를 생성하고 스크립트 에디터를 엽니다.

스크립트 에디터가 열리고 나면 스크립트의 상단에 UnityEngine.UI 네임스페이스를 using 선언해줍니다.

그리고 멤버 변수로는 플레이어 패널 프리팹을 담고 있을 GameObject 타입의 playerPanelPrefab 변수와 생성된 플레이어 패널들의 부모 오브젝트가 될 Transform 타입의 playerPanelsParent 변수, 그리고 생성된 플레이어 패널들을 저장하고 있을 List<MeetingPlayerPanel> 타입의 meetingPlayerPanels 변수를 선언해줍니다.

변수 선언을 끝낸 다음에는 Open 함수를 만들고 내 캐릭터의 패널을 먼저 만들어서 배치해주고 그 후에 FindObjectsOfType 함수로 다른 플레이어들을 찾아서 각 플레이어의 패널을 만들어 줍니다.

그 다음에는 IngameUIManager 스크립트로 이동해서 MeetingUI를 캐싱해서 접근하기 쉽게 만들어줍니다.

그리고 GameSystem 스크립트로 이동해서 StartMeeting_Coroutine 함수를 만들고 3초 후에 Report UI를 닫고 Meeting UI를 열도록 코드를 작성합니다.

그리고 이 StartMeeting_Coroutine 함수를 RpcSendReportSign 함수에서 호출하도록 만들어 줍니다.

코드를 모두 작성한 다음에는 저장하고 에디터로 돌아갑니다.

에디터로 돌아온 다음에는 Meeting UI 오브젝트에 작성한 컴포넌트를 붙이고 프로퍼티를 할당해줍니다.

그리고 Canvas 오브젝트에 붙어있는 IngameUIManager 컴포넌트에 MeetingUI를 캐싱해줍니다.

작업을 끝낸 다음에는 게임을 빌드합니다.

빌드가 완료되면 게임을 실행하고 테스트합니다.

시체를 발견하고 리포트 버튼을 누르면 리포트 UI가 뜬 뒤에 Meeting UI가 뜨고 죽은 플레이어는 어두운 색으로 표시되고 신고한 플레이어에게는 확성기 마크가 뜬 모습을 확인할 수 있습니다.

패널 선택 기능 만들기

이제 플레이어 패널을 선택하는 기능을 만들 차례입니다.

플레이어 패널을 선택했을 때 투표를 위한 버튼을 뜨게 해야합니다.

MeetingPlayerPanel 스크립트를 엽니다.

그리고 GameObject 타입으로 투표 버튼 그룹을 컨트롤할 voteButtons 변수를 선언하고 패널을 클릭했을 때 동작할 OnClickPlayerPanel 함수를 만들어줍니다.

이 함수에서는 먼저 voteButtons를 활성화시키도록 코드를 작성해줍니다.

코드를 작성한 다음에는 저장하고 에디터로 돌아갑니다.

그리고 프리팹에서 Vote Buttons 프로퍼티에 Player Panel 프리팹 아래에 있는 Vote Buttons 게임오브젝트를 할당해줍니다.

그 다음에는 Player Panel 오브젝트에 Button 컴포넌트를 붙인 다음 Transition을 None으로 변경하고 On Click 이벤트에 Meeting Player Panel의 OnClickPlayerPanel 함수를 등록해줍니다.

작업을 마치면 게임을 빌드해서 테스트 합니다.

회의 창이 뜬 이후에 플레이어 패널을 클릭해보면 투표를 위한 체크 버튼과 X 버튼이 뜨는 모습을 볼 수 있습니다.

그런데 지금은 다른 플레이어 패널을 선택했을 때 앞에서 선택한 플레이어 패널의 버튼이 사라지지도 않고 죽은 플레이어도 선택해서 투표를 할 수 있습니다.

그리고 죽은 플레이어도 다른 플레이어에게 투표할 수 있죠.

스크립트로 돌아가서 이 부분들을 수정해보겠습니다.

먼저 죽은 플레이어의 패널이 클릭되지 않도록 하는 부분은 SetPlayer 함수에서 처리하면 됩니다.

deadPlayerBlock을 활성화하기 위해서 판정한 값을 isDead 변수에 따로 저장해서 사용하도록 코드를 수정합니다.

그리고 isDead 값을 GetComponet 함수로 가져온 버튼의 interactable에 넣어줍니다.

그 다음은 한 패널을 선택했을 때 다른 패널의 선택을 해제하는 것입니다.

이것을 위해서는 다른 패널에 접근이 가능해야하는데 생성된 패널들은 MeetingUI에서 가지고 있으니 그쪽을 통해서 접근하는 것이 좋습니다.

먼저 MeetingPlayerPanel 클래스에 Unselect 함수를 만들어서 voteButtons를 비활성화 시키도록 만들어줍니다.

그 다음에는 MeetingUI 클래스로 이동해서 SelectPlayerPanel 함수를 만들고 선택한 패널을 제외한 다른 패널을 비활성화시키도록 코드를 작성합니다.

그리고 다시 MeetingPlayerPanel 클래스의 OnClickPlayerPanel 함수로 이동해서 MeetingUI의 SelectPlayerPanel 함수를 호출하도록 만들어줍니다.

마지막으로 죽은 플레이어가 투표를 하지 못하게 막기 위해서는 OnClickPlayerPanel 함수에서 플레이어가 죽은 상태라면 투표 기능이 동작하지 못하게 만들어줍니다.

코드를 모두 작성한 다음에는 저장하고 에디터로 돌아갑니다.

그리고 프리팹의 Vote Buttons 아래에 있는 Cancel Button을 선택하고 On Click 이벤트에 Unselect 함수를 등록해줍니다.

작업을 모두 마치면 게임을 빌드합니다.

그리고 게임을 실행해서 테스트해보면 한 패널을 선택하고 다른 패널을 선택하면 이전에 선택한 다른 패널의 선택이 취소되고 죽은 플레이어의 패널은 선택되지 않는 것을 볼 수 있습니다.

그리고 X 버튼을 누르면 패널 선택이 취소되는 모습도 볼 수 있습니다.

마지막으로 죽은 플레이어는 다른 플레이어를 선택할 수 없는 모습도 볼 수 있습니다.

아웃트로

이번 영상에서는 회의에서 임포스터로 의심되는 플레이어에게 투표해서 추방하는 기능을 만들기 위해 회의 UI를 만들고 플레이어 패널을 선택하는 기능을 만들어 보았습니다.

이상 베르의 게임 개발 유튜브였습니다. 감사합니다.

반응형

+ Recent posts