

▲현재 씬에 네트워크 기능 추가

Instantiate(playerPrefab, spawnPoint, Quaternion.identity);
- 현재 클라이언트 ( 내 PC )에서만 생성
Runner.Spawn(playerPrefab, spawnPoint, Quaternion.identity);
- 네트워크 전체에 동기화되어 생성

using UnityEngine;
using Fusion;
public class PlayerSpawner : SimulationBehaviour, IPlayerJoined
// └ 네트워크 구동에 필요한 메서드 사용하고 싶다면 이걸 상속
{
[SerializeField] GameObject playerPrefab;
[SerializeField, Range(0, 10)] float spawnRandomLocation;
[SerializeField] float spawnHeight;
// 플레이어가 참여되면 이게 호출됨
public void PlayerJoined(PlayerRef player)
{
//Debug.Log(player.PlayerId);
// 참여한 플레이어가 로컬 플레이어가 아니라면 return
if(player != Runner.LocalPlayer)
{
return;
}
// 랜덤 위치 뽑아내기
Vector3 spawnPoint = new Vector3(Random.Range(-spawnRandomLocation, spawnRandomLocation), spawnHeight, Random.Range(-spawnRandomLocation, spawnRandomLocation));
//Instantiate(playerPrefab, spawnPoint, Quaternion.identity); // 이거는 진짜 내 로컬 컴퓨터에서만 보이게
// 네트워크에 영향이 없는 것과 있는 것을 잘 구분해야 함
Runner.Spawn(playerPrefab, spawnPoint, Quaternion.identity); // 이거는 네트워크 전체에 동기화되어 생성
// RPC , 리모트 프로시저 콜
}
}
public override void FixedUpdateNetwork()
- Photon Fusion이 네트워크 틱 ( Tick ) 마다 호출해주는 업데이트 함수
using UnityEngine;
using Fusion;
using UnityEngine.InputSystem;
public class PlayerMovement : NetworkBehaviour
{
public override void FixedUpdateNetwork()
{
// 캐릭터를 조종하면 된다. 이 스크립트를 단 애들이 싹 다 움직일 예정
if(!HasInputAuthority) // 누구 것인지 항상 체크, 마스터 클라이언트인지도 중요
{
return;
}
if(Keyboard.current.wKey.isPressed)
{
// 이동
// 아까 네트워크 트랜스폼 컴포넌트 달아놨기 때문에, 이동한 위치가 동기화됨
}
}
}
FixedUpdateNetwork 메서드 안에서 이동시킬 때
로컬은 입력값이 생기면 바로 이동할텐데 이 때 렉이 걸리면 서버와 위치 데이터가 다를텐데
이때는 코드를 어떻게 작성해야 하는지?

Update 에서 바로 이동처리를 하지 않고 이동 값만 저장해놓은 다음
FixedUpdateNetwork 에서 이동을 처리한다
using UnityEngine;
using Photon.Pun; // 펀 관련된 기능을 쓸 예정
using Photon.Realtime;
using System.Collections;
// 네트워크에 적합하게끔 뜯어고침
public class Launcher : MonoBehaviourPunCallbacks
{
string gameVersion = "1"; // 게임 켤때, 버전 안맞으면 못키게 해야해서 지정
private void Awake()
{
PhotonNetwork.AutomaticallySyncScene = true; // 방장이 씬을 바꾸면 다른 모든 클라들도 씬이 같이 바뀌는 옵션
// 이 파일은 모든 파일에 싹 다 들어있음
}
private void Start()
{
PhotonNetwork.GameVersion = gameVersion; // 시작과 동시에, 현재 빌드의 버전 정보를 포톤네트워크 객체에 기억시킴
PhotonNetwork.ConnectUsingSettings(); // 우리가 스크립터블 오브젝트에 적어둔 앱아이디 정보들이 담긴 내용으로 서버 연결 시도
// 서버 연결을 할 예정
// 서버 연결 성공 여부를 들어야함
}
// OnCollision처럼, 조건을 만족하면 알아서 콜백 메서드들이 호출된다
public override void OnConnectedToMaster()
{
Debug.Log("펀 마스터 서버 연결 성공");
PhotonNetwork.JoinLobby(); // 로비는 방에 들어가기 전에 대기하는 공간. 다양한 방 목록을 받아올 수 있다.
// 다양한 방 목록을 받아올 수 있다.
// 얼마나 걸릴지 모른다
//PhotonNetwork.JoinRoom();
//PhotonNetwork.JoinRandomRoom();
PhotonNetwork.JoinLobby();
//if(PhotonNetwork.IsConnectedAndReady) // 준비가 되면 이거 해라
//{
// PhotonNetwork.JoinRandomOrCreateRoom();
//}
StartCoroutine(ConnectToRoom());
}
IEnumerator ConnectToRoom()
{
yield return new WaitUntil(() => PhotonNetwork.IsConnectedAndReady);
}
public override void OnJoinRoomFailed(short returnCode, string message)
{
Debug.Log(returnCode + message);
// 혹은 팝업을 띄운다던지
//PhotonNetwork.CreateRoom(null, new Photon.Realtime.RoomOptions());
PhotonNetwork.CreateRoom(null, new RoomOptions { MaxPlayers = 4 }); // 방을 만들면 방장은 누구?
// 크리에이트 룸 하게 되면, 방 만들고, 방장이 되어버림
}
public override void OnJoinedRoom() // 리액션, 콜백
{
Debug.Log("방에 들어왔습니다.");
}
public override void OnJoinedLobby() // 로비 참여 완료시, 알아서 호출되는 기능
{
Debug.Log("로비 들어왔습니다");
}
}
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using Photon.Pun;
public class PlayerNameInputField : MonoBehaviour
{
InputField inputField;
const string playerNamePrefKey = "PlayerName";
void Start()
{
string defaultName = string.Empty;
inputField = GetComponent<InputField>();
if (inputField != null)
{
if(PlayerPrefs.HasKey(playerNamePrefKey))
{
defaultName = PlayerPrefs.GetString(playerNamePrefKey);
inputField.text = defaultName;
}
}
PhotonNetwork.NickName = defaultName; // 포톤 네트워크 상에서 이 플레이어의 닉네임이 될 것
}
public void SetPlayerName(string value)
{
if(string.IsNullOrEmpty(value))
{
Debug.Log("플레이어 이름이 비어있습니다.");
return;
}
PhotonNetwork.NickName = value;
PlayerPrefs.SetString(playerNamePrefKey, value);
}
}

using Photon.Pun; //펀 관련된 기능을 쓰려면 붙임
using Photon.Realtime;
using System.Collections;
using UnityEngine;
//네트워크에 적합하게끔 뜯어고침
public class Launcher : MonoBehaviourPunCallbacks
{
private void Awake()
{
PhotonNetwork.AutomaticallySyncScene = true; //방장이 씬을 바꾸면 다른 모오오오든 클라들도 씬이 같이 바뀌는 옵션
}
public void ConnectedToServer() // 임의로 작성한 메서드
{
PhotonNetwork.ConnectUsingSettings();
}
public override void OnConnectedToMaster()
{
Debug.Log("펀 마스터 서버 연결 성공");
PhotonNetwork.JoinRandomOrCreateRoom();
}
public override void OnJoinedRoom() //리엑션, 콜백
{
Debug.Log("방에 들어왔습니다");
Debug.Log("환영합니다" + PhotonNetwork.NickName + "님");
}
// 플레이어가 들어왔을 때 자동으로 호출되는 메서드
public override void OnPlayerEnteredRoom(Player newPlayer)
{
Debug.Log(newPlayer.NickName + "님이 방에 입장하셨습니다.");
}
}
'📖TIL' 카테고리의 다른 글
| 260107 네트워크 게임플레이 (0) | 2026.01.07 |
|---|---|
| 260106 (0) | 2026.01.06 |
| 260105 CS기초 리비전 (0) | 2026.01.05 |
| 260105 네트워크 (0) | 2026.01.05 |
| 251230 (0) | 2025.12.30 |