PUN (Photon Unity Network)

유니티용으로 제작된 포톤 네트워크 엔진이다.

PUN의 기능 중 하나는 Photon Realtime 등 포톤의 여러 API를 유니티 컴포넌트에  랩핑하여 제공하는 것이다.

 

PUN 설치

샤샤삭 만들고 세팅하기

 

MonoBehaviourPunCallbacks

PUN만의 MonoBehaviour (PUN과 관련된 콜백 메소드를 제공)

 

Photon Unity Networking 2: MonoBehaviourPunCallbacks Class Reference

This class provides a .photonView and all callbacks/events that PUN can call. Override the events/methods you want to use. More... This class provides a .photonView and all callbacks/events that PUN can call. Override the events/methods you want to use. By

doc-api.photonengine.com

 

PhotonNetwork

포톤과 관련된 여러가지 기능을 제공 ( 매치메이킹, 방 생성, 방 접속 등 가능 )

 

주요 API

ConnectUsingSettings() 매치메이킹 서버에 접속한다.
PhotonSeverSettings 스크립터블 오브젝트에서 설정 가능
(나중에 AWS 서버를 이용하려면 IP 주소를 직접 입력해야 한다.)
CreateRoom() 방을 생성한다.
JoinRandomRoom() 현재 접속 가능한 방 중 임의의 방으로 접속한다.
LoadLevel() 방에 있는 모든 클라이언트를 특정 씬으로 이동시킨다.

 

 

LobbyManager

using Photon.Pun; // 유니티용 포톤 컴포넌트들
using Photon.Realtime; // 포톤 서비스 관련 라이브러리
using System.Collections;
using UnityEngine;
using UnityEngine.UI;

// 마스터(매치 메이킹) 서버와 룸 접속을 담당
public class LobbyManager : MonoBehaviourPunCallbacks // PUN만의 MonoBehaviour
{
    private static readonly string GAME_VERSION = "1"; // 게임 버전

    public Text connectionInfoText; // 네트워크 정보를 표시할 텍스트
    public Button joinButton; // 룸 접속 버튼

    // 게임 실행과 동시에 마스터 서버 접속 시도
    private void Start() 
    {
        // 접속에 필요한 정보를 설정한다.
        PhotonNetwork.GameVersion = GAME_VERSION;

        // 마스터 서버로 접속을 시도한다
        PhotonNetwork.ConnectUsingSettings();

        // UI 표시
        joinButton.interactable = false;
        setConnectInfoText("마스터 서버에 접속 중", true);
    }

    // 마스터 서버 접속 성공시 자동 실행
    public override void OnConnectedToMaster() 
    {
        // UI 표시
        joinButton.interactable = true;
        setConnectInfoText("마스터 서버에 접속되었습니다.");
    }

    // 마스터 서버 접속 실패시 자동 실행
    public override void OnDisconnected(DisconnectCause cause) 
    {
        PhotonNetwork.ConnectUsingSettings();
        DebugManager.Instance.DebugLog("접속실패 : " + cause.ToString());
        // UI 표시
        setConnectInfoText("접속 실패 : 재접속 시도 중", true);
    }

    void setConnectInfoText(string _text, bool _isLoading = false)
    {
        StopAllCoroutines();
        if (_isLoading)
        {
            StartCoroutine(CorConnect(_text));
        }
        else
        {
            connectionInfoText.text = _text;
        }
    }

    IEnumerator CorConnect(string _text)
    {
        while(true)
        {
            connectionInfoText.text = _text + ".";
            yield return new WaitForSeconds(0.2f);
            connectionInfoText.text = _text + "..";
            yield return new WaitForSeconds(0.2f);
            connectionInfoText.text = _text + "...";
            yield return new WaitForSeconds(0.2f);
        }
    }

    // 룸 접속 시도
    public void Connect() 
    {
        // 접속 버튼을 비활성화
        joinButton.interactable = false;

        // 서버에 접속중이냐
        if(PhotonNetwork.IsConnected)
        {
            setConnectInfoText("룸에 접속합니다!");

            // 랜덤룸에 접속을 실행
            PhotonNetwork.JoinRandomRoom();
        }
        else
        {
            PhotonNetwork.ConnectUsingSettings();
            // UI 표시
            setConnectInfoText("오프라인 : 접속 시도 중", true);
        }
        // 다시 마스터 서버에 재접속 시도
    }

    private static readonly RoomOptions ROOM_OPTIONS = new RoomOptions()
    {
        MaxPlayers = 4
    };

    // (빈 방이 없어)랜덤 룸 참가에 실패한 경우 자동 실행
    public override void OnJoinRandomFailed(short returnCode, string message) 
    {
        DebugManager.Instance.DebugLog("방 없음 : [" + returnCode + "] " + message);

        // 방 생성
        setConnectInfoText("방 생성중", true);
        PhotonNetwork.CreateRoom(null, ROOM_OPTIONS);
    }

    // 룸에 참가 완료된 경우 자동 실행
    public override void OnJoinedRoom() 
    {
        setConnectInfoText("방에 참가합니다");
        PhotonNetwork.LoadLevel("Main"); // 로드씬 대신 이거 사용함
    }
}

 

PhotonView

방에 있는 여러 게임 오브젝트 중 로컬과 리모트를 구분하고, 데이터 동기화 기능을 제공한다.

 

정적인 오브젝트를 제외하고 게임에서 돌아다니는 동적 오브젝트는 대부분 포톤 뷰가 필요하다.

포톤뷰가 없으면 동기화가 되지 않습니다. 누가 누군지 모르기 때문이다.

 

다른 클라이언트 캐릭터가 움직이면 동기화해주는 일을 얘가 해준댄다.

 

Synchronization

Off : 동기화 X, RPC만 사용할 경우

Reliable Delta Compressed : 받은 데이터를 비교해 같으면 보내지 않음

Unreliable : 계속 보냄 (유실될 수 있음)

Unreliable On Change : 변경이 있을 때 계속 보냄 (유실될 수 있음)

 

Observed Components

PhotonView 컴포넌트가 관측할 컴포넌트는 Observed Components 리스트에 할당하면 된다.

단, IPunObservable 인터페이스를 상속한 컴포넌트만 관측할 수 있다.

 

데이터 동기화는 IPunObservable.OnPhotonSerializeView()에서 제공

 

 

기본 제공 컴포넌트

- PhotonTransformView : 트랜스폼 동기화 제공

- PhotonAnimatorView : 애니메이터 동기화 제공

- PhotonRigidbodyVie : 리지드바디 동기화 제공

 

Photon Transform View

Position, Rotation, Scale 동기화를 체크한다.

불필요한 정보를 체크하면 네트워크 낭비가 발생하니 주의!

 

Photon Animator View

Disabled : 동기화하지 않는다.

Discrete : 초당 10회 동기화

Continuous : 매 프레임마다 동기화

 

Photon Rigidbody View

리지드바디 동기화인데 Transform이랑 같이 쓰면 동기화가 이상해 질 수 있대요

트랜스폼만 동기화해도 충분하지 않을까 싶습니다.

 

IPunObservable

내가 만든 컴포넌트 하고 싶으면

MonoBehaviourPun

- PhotonView 컴포넌트 제공

- PhotonView 컴포넌트가 추가 되어 있어야 함

 

PhotonView.IsMine

내껀지 아닌지. 로컬과 리모트 구분이 가능했다.

 

RPC

 

 

728x90

+ Recent posts