본 포스트는 베르님의 Make the 어몽어스를 정리한 포스트입니다.
https://www.youtube.com/watch?v=t9IeIbaucao&list=PLYQHfkihy4Aw6QjsZqwwbD4ihpwvm7N0U&index=6
이번 시간에는 게임 대기실 UI를 만들도록 하겠습니다.
먼저 베르님이 이번 강의에서 공유해주신 자료를 다운받은 후 해당 리소스들을 import 해줍니다.
https://drive.google.com/file/d/1T4GTu87h62y0fhWVN_y6OJDU8ZVUDefX/view
저번 시간에는 방 만들기에 대한 작업을 진행하였습니다. 이번에는 방 접속 기능을 구현해보겠습니다. 먼저 Online UI 스크립트를 엽니다. 먼저 Mirror 네임스페이스를 using 선언한다음 다음의 코드를 추가합니다.
public void OnClickEnterGmaeRoomButotn(){
if(nicknameInputField.text != ""){ // 닉네임 필드가 비어있지 않는 경우에만
// 방만들기로 넘어감
var manager = AmongUsRoomManager.singleton;
manager.StartClient(); // 클라이언트 시작
}
else{
nicknameInputField.GetComponent<Animator>().SetTrigger("On"); // 입력 강조 애니메이션 실행
}
}
이후 입장하기 버튼의 On click()에 방금 작성한 OnClickEnterGmaeRoomButotn() 함수를 지정해줍니다.
Online UI > Private > Button
해당 기능(네트워크 관련)이 제대로 작동하는지 테스트하기 위해 여러 프로그램을 실행해야 합니다. (같은 프로젝트 여러 개를 열어둘수는 없기에 게임을 빌드하여 테스트합니다.)
게임을 전체 화면으로 실행하게 되면 클라이언트와 호스트의 창을 보기가 힘들기 때문에 Build settings에서 Player settings를 킨 다음 Player의 Resolution and Presentation에서 Full Screen Window를 Windowed로 변경해줍니다.
설정을 마치고 게임을 build한 후 여러개를 실행하여 방을 만들고 입장하는 기능을 테스트할 수 있습니다.
GameRoomScene을 열어준 후 배경을 검은색으로 변경하기 위해 Main Camera의 Environment에서 Skybox를 Solid Color로 변경하고 색을 검은색으로 지정합니다.
다음으로 앞서 다운로드 받았던 리소스들 중 sprite_ship을 hierarchy 창에 드래그하여 오브젝트로 추가합니다. 추가하면 이미지가 검은색으로 보이는 것을 확인할 수 있는데 이를 보이게 하고자 광원을 추가합니다.
Light > 2D > Global Light 2D (Experimental)
이후 sprite_ship의 order in layer를 -32768로 변경한 후 다른 리소스들을 배치합니다. (이때 노트북을 상자 위로 올리기 위해 상자의 order in layer를 -100으로 설정합니다.) 리소스들의 경우 크기와 위치를 조절하여 다음과 같이 배치합니다.
먼저 빈 canvas를 생성합니다. 메인 메뉴의 캔버스와 setting을 맞추기 위해서 UI Scale Mode를 Scale With Screen Size로 변경한 후 reference resolution을 1024x768로 변경합니다. 그리고 Match 값을 1로 변경합니다.
https://docs.unity3d.com/kr/current/Manual/script-CanvasScaler.html
왼쪽에는 커스텀 설정 text를 배치하고 다음과 같이 기본적인 UI를 배치해줍니다.
세팅 버튼을 눌렀을 때 뜰 UI를 만들기 위해 Canvas에서 빈 오브젝트를 생성한 후 앵커를 stretch-stretch로 변경하고 left, top, right, bottom을 모두 0으로 설정합니다.
- 앵커: 부모의 Rect Transform에 고정
https://docs.unity3d.com/kr/530/Manual/UIBasicLayout.html
다음으로 배경으로 사용할 background image를 하나 생성합니다. 위와 동일하게 앵커를 변경하여 화면 전체를 덮도록 만듭니다. 그리고 이미지의 색상에서 알파 값을 0으로 만들어 투명하게 만듭니다.
이후 Panel(Pattern005)과 버튼(Pattern001)들을 생성하여 다음과 같이 UI를 배치합니다.
지금부터는 세팅 기능을 구현해보겠습니다. 현재 게임 나가기와 돌아가기를 제외하면 메인 메뉴 scene의 setting UI와 굉장히 유사합니다. 따라서 대기실 세팅 UI가 메인 메뉴 세팅 UI를 상속하도록 하겠습니다.
먼저 이전에 Main Menu Scene에서 만들었던 settings의 animator controller를 component로 붙여줍니다.
이때 주의할 점은 애니메이션을 재활용할 때 게임 오브젝트의 이름이 같아야 합니다.
그 다음 GameRoomSettingUI 스크립트를 생성한 후 Setting UI의 컴포넌트로 추가합니다. 컴포넌트로 붙인 후 해당되는 버튼을 스크립트 컴포넌트의 버튼 프로퍼티에 할당해줍니다.
(+ 추가로 component가 붙여지지 않는 경우 스크립트 class 명이랑 해당 스크립트명이 같은지 확인해야합니다.)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameRoomSettingUI : SettingsUI
{
public void ExitGameRoom(){
var manager = AmongUsRoomManager.singleton;
if(manager.mode == Mirror.NetworkManagerMode.Host){ // host라면 stop host
manager.StopHost();
}
else if(manager.mode == Mirror.NetworkManagerMode.ClientOnly){ // client라면 stop client
manager.StopClient();
}
}
}
다음으로 해당 버튼들의 On Click() event로 Set Control Mode를 설정한 후 Mouse에는 0, KeyboardMouse에는 1을 설정합니다.
Background에는 Button component를 추가하고 Background와 Return Game Button에 On Click() 이벤트로 Close 함수를 설정합니다. Exit Game Button의 On Click()에는 ExitGameRoom 함수를 설정합니다.
이렇게 Setting UI 작업이 모두 마치면 해당 UI를 보이지 않게 만든 후 Game room의 setting button에 On Click() 이벤트로 Settings UI가 켜지게 만듭니다. (SetActive, 체크)
게임을 2개 빌드하여 실행해보면 정상적으로 동작하는 것을 확인할 수 있으나, 방을 만든 호스트가 게임을 나가는 경우 해당 방에 들어온 클라이언트들도 동시에 나가지는 것을 확인할 수 있습니다. 이 부분은 서버 역할을 하는 호스트의 연결이 끊어졌을 때, 호스트의 역할을 다른 클라이언트로 옮기는 host migration 기능을 구현해야합니다. 이 기능은 구현하는데 상당히 까다롭기 때문에, 지금은 서버 역할을 하는 호스트가 게임 도중 접속을 종료하지 않는다고 가정하고 진행합니다.