프로젝트를 네트워크로 래핑했다.
예전에 책에서 UNet을 사용하라고 했었는데
다시 검색해보니까 UNet은 deprecated.. 새로 개발중이라고 한다. 그래서 어쩔 수 없이 네트워크 에셋을 사용했다.
에셋은 Photon2인데 몇시간 전에 관련 기초 정리를 작성해두었다.
https://jjahoolikeapple.tistory.com/28?category=931545
[Unity] Network : Photon2 정리 - 1
메치메이킹 방식의 네트워크 게임 정리 1. 로비 씬에서의 설정 로비에서 여러 설정을 해주는데 기본 설정은 아래와 같다 public class LobbyManager : MonoBehaviourPunCallbacks { private string gameVersion =..
jjahoolikeapple.tistory.com
플레이어의 이동과 애니메이션을 래핑해서 리스닝서버 형식으로 서버를 구축하게 해놨다.
그러면 이제 로비에서 입력한 닉네임을 메인 게임상에서 캐릭터 머리 위에 띄우고 다른 플레이어들의 닉네임도 확인할 수 있어야한다.
일단 Lobby scene의 TextInputField의 text값을 Main scene에 넘겨주어야한다.
public static string playerName;
public GameObject InputField;
유니티 내에서 컴포넌트의 프롭스로 넘겨주고 그 InputField의 text를 playerName에 담아둔다
당연히 다른 씬에서 playerName을 사용해야 하기에 static으로 선언했다.
라고 생각했었는데 Photon 라이브러리를 살펴보니 NickName 기능이 있었다.
그래서 아예 위의 전역변수가 필요하지가 않다.
사실 전역변수를 최대한 쓰지 않아야 한다.
아무튼 저 LOGIN 버튼을 누를 때 로컬플레이어의 닉네임을 설정해줘야한다.
public void Connect()
{
joinButton.interactable = false; // 중복 접속 막아야함.
PhotonNetwork.LocalPlayer.NickName = InputField.GetComponent<TMP_InputField>().text;
// 연결 됐으면
if (PhotonNetwork.IsConnected)
{
connectionInfoText.text = "룸에 접속 중...";
PhotonNetwork.JoinRandomRoom();
}
else
{
connectionInfoText.text = "마스터 서버와 연결되지 않음... 재접속 시도 중";
PhotonNetwork.ConnectUsingSettings();
}
}
포톤네트워크에서 로컬로 있는 옵젝의 닉네임을 받아서 넣어준다.
그러면 메인씬으로 이동해도 로컬 옵젝의 props로 닉네임이 있으니 캔버스에 띄워주기만 하면 된다.
캔버스를 만들고 캐릭터 내부로 넣어준다.
이동과 회전 모두 캐릭터를 기준으로 해야하니깐!
그리고 캔버스의 Render Mode 를 Screen Space에서 World Space로 변경해주어야한다.
캔버스는 UI 담을때 카메라에 항상 뜨게 하는데, World Space로 바꾸어주면 월드 내에서 특정 위치에서 보이게 해줄 수 있다.
그리고 캔버스와 캔버스 하위에 있는 Text의 크기를 적당히 줄여주고 머리위에 올리게 Y position을 적절하게 놔준다.
그러면 이쁘게 잘 올라간다.
나는 유니티에서 TextMeshPro를 쓰는데 일반 캔버스 Text보다 퀄리티가 좋고 뭐 기능들이 몇개 더 있다.
https://docs.unity3d.com/kr/2019.4/Manual/com.unity.textmeshpro.html
TextMesh Pro - Unity 매뉴얼
docs.unity3d.com
폰트는 한글로 따로 설정해서 text에 입혀줘야하는데 폰트관련은 나중에 또 포스팅 할 예정이다.
아무튼 이제 로컬에서는 잘뜨는데 이걸 네트워크와 연결해줘야한다.
각각의 플레이어들의 닉네임을 설정해줘야하는데
using UnityEngine;
using TMPro;
using Photon.Pun;
public class PlayerName : MonoBehaviourPun
{
[SerializeField] private TextMeshProUGUI playerName;
void Start()
{
if (photonView.IsMine) { playerName.text = PhotonNetwork.LocalPlayer.NickName; }
SetName();
}
private void SetName() => playerName.text = photonView.Owner.NickName;
}
이 스크립트를 캐릭터 Prefab에 컴포넌트로 넣어주고
캐릭터 하위에 넣어준 캔버스의 TextMeshProUGUI를 유니티내에서 컴포넌트 props로 넣어준다.
SerializeField는 다른 스크립트에서 접근불가능하지만 유니티 inpector창에는 마치 public인 것처럼 오브젝트를 props로 넣어주게끔 해주는 기능이다. 간단히 private으로 하고싶은데 오브젝트를 연결해줄 때 사용한다.
그리고나서 로컬이면 로비에서 로컬에 넣어준 닉네임을 그대로 사용하면되고
아니라면 각자 클라이언트의 닉네임을 넣어주면된다.
다시한번 네트워크는 평행세계이다.
나에게 뜨는게 다른 세계에서도 떠야하고, 다른 세계에서 뜨는게 나에게도 떠야한다.
네트워크를 손대면서 이게 가장 헷갈렸는데 월드가 여러개가 있다는걸 계속 생각하면서 개발해야한다.
그런데 위처럼 개발하고 게임을 실행시켜보면 다른 캐릭터의 닉네임이 해당 캐릭터의 방향으로 고정되어있어서
그 캐릭터의 뒤에서 닉네임을 바라보면 닉네임이 거꾸로 보인다.
그래서 각자의 닉네임들이 로컬의 카메라를 바라보게끔 만들어줘야한다.
using UnityEngine;
public class NameCanvasSetting : MonoBehaviour
{
private Transform mainCameraTransform;
private void Start()
{
mainCameraTransform = Camera.main.transform;
}
private void LateUpdate()
{
transform.LookAt(transform.position + mainCameraTransform.rotation * Vector3.forward, mainCameraTransform.rotation * Vector3.up);
}
}
이 스크립트를 캔버스에 넣어주면 해당 캔버스는 로컬의 카메라를 바라보게된다.
그러면 어떤 플레이어의 닉네임이든지 항상 플레이 하는 나를 바라보게 되므로 캐릭터들을 어디서 바라보든 항상 정면으로 닉네임을 읽을 수 있다.
서버가 리스닝 방식인데 전용서버 방식으로 만들고 싶은데 비용도 들고 해서 서버 구조를 계속 생각해봐야겠다.
'UNITY > 학교 메타버스' 카테고리의 다른 글
학교 메타버스 게임 - 3 : 미니맵 (0) | 2021.06.10 |
---|---|
[Unity] 학교 메타버스 게임 만들기 - 1 : 빛 설정 (0) | 2021.05.31 |