유니티 Photon Fusion2 네트워킹(Host Mode) 기본 사용법 정리

반응형

유니티 Photon Fusion2 네트워킹(Host Mode) 기본 사용법 정리

Photon Fusion 2 SDK를 활용하여 유니티 네트워킹 구현 기초 예시(NetworkRunner, NetworkBehaviour, INetworkInput)
https://doc.photonengine.com/ko-kr/fusion/current/tutorials/host-mode-basics/1-getting-started

1)게임을 시작하면 GUI에서 두가지 버튼을 표시. 두가지 버튼은 클릭했을때 각각 Host 또는 Client ( GameMode.Host, GameMode.Client) 로써 퓨전 시뮬레이션 시작을 구현하는 사용자 지정 함수를 호출(StartGame())

 

 

2)async void StartGame(GameMode mode) 함수에서  Host, Client 모두 NetworkRunner 인스턴스를 생성하고 현재 씬의 네트워크 씬 정보를 생성하고  _runner.StartGame(new StartGameArgs() 함수를 실행.

지정한 파라미터로 로컬 퓨전 시뮬레이션(Fusion Runner)를 시작(Gamemode에 따라서 세션을 시작 또는 참가), Host, Client 차이는 오직 GameMode 할당(Host, Client)

runner.StartGame(new StartGameArgs()
{
 GameMode = mode,
 SessionName = "TestRoom",
 Scene = scene,
 SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
});

 

플레이어가 세션에 참여 또는 연결을 종료할때마다 OnPlayerJoined 또는 OnPlayerLeft함수가 호출.

두 함수는 NetworkRunner가 네트워크 이벤트를 알리기 위해 호출하는 콜백 집합 인터페이스인 INetworkRunnerCallbacks 인터페이스에 정의된 콜백 함수


OnPlayerJoined
세션에 새로운 플레이어가 접속하면 public void OnPlayerJoined(NetworkRunner runner, PlayerRef player) 함수가 호출.
runner가 Host(runner.IsServer)이면 접속한 플레이어의 Prefab을 생성하고 NetworkObject를 딕셔너리에 추가

(기본적으로 사용자가 접속할때마다 모든 장치 앱에서 OnPlayerJoined 함수가 호출되지만 오직 Host 유형만 player 프리팹을 생성하고 네트워크객체 NetworkObject를 딕셔너리 목록에 추가 )

 

NetworkObject networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player);

Spawn함수의 player(PlayerRef) 파라미터를 지정하여 접속한 사용자의 해당 플레이어에게 객체(Prefab)의 입력 권한을 부여
(Host가 생성, Client가 컨트롤)

 

-Client 유형 runner가 접속할때 필요한 기능을 OnPlayerJoined 함수에 추가 작성가능

 

 

public void OnInput(NetworkRunner runner, NetworkInput input)
로컬 플레이어의 입력을 네트워크로 전달하기 위한 OnInput() 콜백 구현. Fusion이 매 틱(tick)마다 자동 호출. 
이 함수는 각 사용자의 로컬 장치 앱에서 실행 및 입력을 받아들임

runner - 현재 네트워크 실행 객체
input - 네트워크에 전달할 입력 컨테이너

if (Input.GetKey(KeyCode.W))
모든 로컬 사용자가 각각 입력 수집
Host - 장치 입력을 받아들임
Client A - 장치 입력을 받아들임
Client B - 장치 입력을 받아들임

input.Set(data);
사용자 입력 데이터 var data = new NetworkInputData(); 를 Fusion에 전달(Fusion 입력 시스템에 등록, Host에게 자동 전송됨)

 

플레이어 입력을 저장하기위한 사용자 정의 구조체는 네트워크 입력 데이터라는 표식(marker interface)이 필요( INetworkInput 인터페이스를 상속)

 

플레이어 프리팹에 새로운 Player 스크립트 추가(프리팹은 NetworkObject 객체를 포함)

NetworkBehaviour를 상속 - NetworkBehaviour 는 네트워크용 MonoBehaviour

FixedUpdateNetwork() 를 구현 - 유니티 MonoBehaviour 상속 클래스들은 업데이트함수  Update()  를 구현하고 Fusion는 FixedUpdateNetwork() 를 구현( Tick 기반 동기화). Host와 Client 간의 동기화가 일어나는 지점


public class Player : NetworkBehaviour
public override void FixedUpdateNetwork()
{
}

public override void FixedUpdateNetwork()

Fusion의 네트워크 틱 기반 업데이트 루프(동기화)로 매 네트워크 틱(Fusion Network Tick) 마다 호출

Unity의 MonoBehavour에 존재하는 업데이트 루프인 Update(), FixedUpdate() 와 실행되는 시간 기준이다름.

FixedUpdateNetwork() 실행은 모든 NetworkObject에서 같은 Tick 기준으로 수행

 

 

if (GetInput(out NetworkInputData data))
같은 Network Tick 시점에서 입력 권한(Input Authority)를 가진 플레이어는 true를 반환하고 직접 이동을 계산 및 수행. 입력 권한이 없는 다른 플레이어 객체는 false를 반환. 

 

예를들어 사용자가 앱에 두번째로 접속(player2) 씬에 3명의 플레이어가 접속하여 3개의 player 객체가 존재(player1, player2, player3) 
OnPlayerJoined 함수의  NetworkObject networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player); 에서 해당 사용자가 접속할때 특정 네트워크 객체(NetworkObject) 및 플레이어(PlayerRef, player2)에게 입력권한을 부여했기때문에 씬에 존재하는 다른 플레이어(player1, player3)의 업데이트 루프 if (GetInput(out NetworkInputData data)) 에서는 false를 반환.

 

Fusion 동기화 시스템이 다른 플레이어 위치를 업데이트

동일 Network Tick 시점에 다른 플레이어 객체(State Authority)의 상태 변화는 NetworkTransform(객체 위치, 회전, 크기), NetworkCharacterController(캐릭터 이동) 등의 NetworkObject 및 NetworkBehaviour 기반 컴포넌트에 의해 상태 동기화됨.

 

순서
runner.StartGame(new StartGameArgs()
OnPlayerJoined()
NetworkObject networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player);
OnInput()
if (Input.GetKey(KeyCode.W))
input.Set(data);
FixedUpdateNetwork()
if (GetInput(out NetworkInputData data))

반응형

댓글

Designed by JB FACTORY