[Unity][멀티플레이] #2. 플레이어 생성, 동기화
💡 해당블로그는 "Unity엔진과 Chat gpt를 활용한 멀티플레이 환경 구성 과정"에서 학습한 내용을3달이 지난 지금에서야복습 겸 스파르타 유니티 과제에 적용시키는 과정을 담았습니다.
1. 멀티플레이 환경
2. 포톤 기본 세팅
3. 포톤 연결 / 로비와 방 생성
4. 플레이어 생성
5. Agora를 사용한 실시간 카메라 연결
해당 포스터는 3번:포톤 연결 / 로비와 방 생성부터 작성되었습니다. 전 내용이 궁금하신 분들은 이전 블로그를 확인해 주세요.
이전 글 보러 가기 >
2025.02.19 - [Unity] - [Unity][멀티플레이어] #1. Photon을 유니티에 연동해 보자
[Unity][멀티플레이어] #1. Photon을 유니티에 연동해보자
💡 해당블로그는 "Unity엔진과 Chat gpt를 활용한 멀티플레이 환경 구성 과정"에서 학습한 내용을3달이 지난 지금에서야 복습 겸 스파르타 유니티 과제에 적용시키는 과정을 담았습니다. 1.
youcheachae.tistory.com
🎨 3. 포톤 연결 / 로비와 방 생성
- 전체적인 흐름
- PhotonManger 스크립트 생성
using Photon.Pun;
public class PhotonManager : MonoBehaviourPunCallbacks
{
// 싱글톤
private static PhotonManager instance = null;
public static PhotonManager Instnace { get => instance; }
[Header("===Info===")]
[SerializeField] string _roomVersion = "1.0.0";
[SerializeField] string _roomName = "BlackVillage";
[Header("===동기화 Player===")]
[SerializeField] private GameObject _player; // 생성할 플레이어 오브젝트
public GameObject photonPlayer => _player;
private void Awake()
{
if(instance == null)
instance = this;
else if( instance != this)
Destroy(instance);
DontDestroyOnLoad(instance);
}
}
□ MonoBehaviourPunCallbacks를 상속받아야 함.
□ 포톤은 Lobby - Room으로 이루어져 있음
■ 포톤 연결 후 Lobby에 연결
■ 룸생성 후 접속
- 포톤 서버 연결 함수
private void F_MasterClient()
{
PhotonNetwork.AutomaticallySyncScene = true;
// 게임버전 할당
PhotonNetwork.GameVersion = _roomVersion;
Debug.Log("포톤 서버 초당 데이터 통신 수 : " + PhotonNetwork.SendRate);
// ** 포톤 사용자들을 포톤 서버에 연결
if (!PhotonNetwork.IsConnected)
PhotonNetwork.ConnectUsingSettings(); // ** 포톤 서버 세팅 정보로
}
□ PhotonNetwork.ConnectUsingSettings()
■ 포톤의 서버 세팅 정보로 포톤에 연결
□ PhotonNetwork.AutomaticallySyncScene = true;
■ 마스터 클라이어언트가 LoadLevel 메서드 실행 시 , 즉 다른 씬으로 이동 시
■ 다른 멤버들도 마스터클라이언트가 있는 씬으로 자동 이동
■ false로 세팅하면 이동하지 않는다
- 서버의 마스터(나)가 서버에 접속 성공 시 콜백함수
public override void OnConnectedToMaster()
{
// MonoBehaviourPunCallbacks 의 OnConnected~함수를 오버라이딩
// 서버 마스터가 접속하면 메서드 실행
Debug.Log("포톤에 접속 성공 유무 : " + PhotonNetwork.IsConnected);
// 로비 접속 추가
PhotonNetwork.JoinLobby();
}
□ 서버 연결에 성공하면 OnConnectedToMater() 함수 실행
□ PhotonNetwork.JoinLobby();
■ 로비 입장 함수 실행
- 로비 접속 시 콜백함수
public override void OnJoinedLobby()
{
// 로비에 접속하면 실행
// Debug.Log("로비접속 " + PhotonNetwork.InLobby);
JointRoom();
}
□ 로비에 입장하면 OnJoinedLobby() 함수 실행
□ 방(Room)에 입장
- 방(Room) 생성 후 입장
private void JointRoom()
{
// 방 정보 생성
RoomOptions roomOptions = new RoomOptions();
roomOptions.MaxPlayers = 3;
roomOptions.IsOpen = true;
roomOptions.IsVisible = true;
// 생성 후 바로 입장
PhotonNetwork.JoinOrCreateRoom(_roomName , roomOptions , TypedLobby.Default);
// -> 방 이름 기준으로 작동함
// 즉 마스터클라이언트가 방을 만들면, 다음 접속자는 이름에 해당하는 방이 이미 있으니 거기로 접속
}
□ RoomOptions
■ 방 (room)을 만들 때 필요한 설정값들을 가지고 있음
□ PhotonNetwork.JoinOrCreateRoom()
■ 해당 이름 (_roomName)의 방이 없으면 → 새 방을 생성하고 입장
■ 해당 이름의 방이 있으면 → 기존 방에 입장
public override void OnCreatedRoom()
{
// 방 생성시 호출 (오버라이딩)
Debug.Log("방 생성 완료 : " + PhotonNetwork.CurrentRoom.Name );
}
public override void OnJoinedRoom()
{
// 방 입장 시 호출 (오버라이딩)
Debug.Log($"{PhotonNetwork.CurrentRoom.Name} 에 입장 / 방에 있는지 여부 : {PhotonNetwork.InRoom}" +
$" 인원 수 : {PhotonNetwork.CurrentRoom.PlayerCount}" );
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
// 방 접속 실패 시 호출 (오버라이딩)
Debug.Log($"JoinRoom Failed {returnCode} {message} / 방 없음 -> 생성시도중....");
JointRoom();
}
□ OnCreateedRoom()
■ 마스터클라이언트가 최초 접속했을 때 실행
□ OnJoinedRoom()
■ 방에 입장하면 호출
□ OnJoinRamdonFailed
■ 방에 입장 실패 시 호출
■ JointRoom() 다시 방 만들기 시도
- 실행
private void Awake()
{
if(instance == null)
instance = this;
else if( instance != this)
Destroy(instance);
DontDestroyOnLoad(instance);
// 게임시작 시 포톤 세팅
// 1. 포톤서버에 연결, 로비 생성 후 방 생성
F_MasterClient();
}
: PhotonManager의 Awake에서 실행한다.
🎨 4. 플레이어 생성
- 플레이어 생성
IEnumerator CreatePlayer()
{
// 3초 기다리기
yield return new WaitForSeconds(3);
// 입력받은 닉네임 가져오기
PhotonNetwork.NickName = UiManager.Instnace.F_InputName();
// 플레이어 생성
// PhotonNetwork의 Instantiate 사용
_player = PhotonNetwork.Instantiate("Player", new Vector3(0,0,0), Quaternion.identity);
if (_player == null)
{
Debug.Log("생성한 플레이어가 null");
yield break;
}
}
□ yield return new WaitforSeconde()
■ 서버 연결 + 로비생성 + 방 생성 후 바로 생성하는 것보다 혹시 모를 문제를 방지하기 위해서 3초 대기
□ PhotonNetwork.NickName
■ InputField에서 입력받은 닉네임으로 네트워크에 설정
□ PhotonNetwork.Instantiate
■ 네트워크상 동기화되는 오브젝트 (player) 생성
■ 생성 시 모든 네트워크 참가자에게 자동으로 생성됨
■ 각 오브젝트에 고유한 네트워크 ID가 부여됨
🔖 생성할 프리팹은 Resources폴더 하위에 있어야 한다
🔖 문자열로 검사하기 때문에 프리팹의 이름을 일치시켜 줘야 한다
🔖 프리팹에는 포톤뷰 컴포넌트, 트랜스폼 컴포넌트, 애니메이션 컴포넌트를 추가한다
- 로컬과 리모트
: 멀티플레이 게임에서는 내가 제어하는 플레이어 오브젝트만 제어해야 함!
: 게임을 플레이하는 주체에 따라 '로컬'과 '리모트'로 나뉨
🔖로컬(Local)
: 내가 직접 조작하는 캐릭터나 오브젝트
🔖리모트(Remote)
: 다른 사람이 조작하는 캐릭터
: 멀티플레이어에서, 나를 제외한 다른 사람이 조작하는 캐릭터는 모두 리모트 플레이어
PlayerMovement.cs
[Header("===Photon View")]
private PhotonView playerView;
private IEnumerator IE_PlayerMovenet()
{
while (true)
{
// 로컬체크 - 로컬이 아니면 움직임 x
if (!playerView.IsMine)
continue;
// 플레이어 움직임 코드
playerMove();
// 매프레임마다
yield return null;
}
}
□ 플레이어의 PhotonView의 IsMine 사용
■ 로컬이 아니면 플레이어 움직임 코드 실행 x
- 실행
private void Awake()
{
if(instance == null)
instance = this;
else if( instance != this)
Destroy(instance);
DontDestroyOnLoad(instance);
// 게임시작 시 포톤 세팅
// 1. 포톤서버에 연결, 로비 생성 후 방 생성
F_MasterClient();
// 2. 플레이어 생성
StartCoroutine(CreatePlayer());
}
: PhotonManager의 Awake에서 실행한다.
🎨 5. Agora를 사용한 실시간 카메라 연결
2025.02.21 - [Unity] - [Unity][멀티플레이] #3. Agora를 사용한 카메라 인식
[Unity][멀티플레이] #3. Agora를 사용한 카메라 인식
→💡 해당블로그는 "Unity엔진과 Chat gpt를 활용한 멀티플레이 환경 구성 과정"에서 학습한 내용을3달이 지난 지금에서야 복습 겸 스파르타 유니티 과제에 적용시키는 과정을 담았습니다. 1. 멀티
youcheachae.tistory.com
깃허브
https://github.com/kimYouChae/Sparta_Metaverse
GitHub - kimYouChae/Sparta_Metaverse
Contribute to kimYouChae/Sparta_Metaverse development by creating an account on GitHub.
github.com