💡 해당블로그는 "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

 

 

+ Recent posts