티스토리 뷰
[SyncVar]라는 Attribute가 있습니다.
이 어트리뷰트를 추가한 기본 데이터형(int, float, string...)의 변수는
네트워크 상에서 동기화됩니다.
(+추가) 다만, Server에서 Spawn을 통해 생성된 네트워크 객체에서만 작동합니다.
[SyncVar]가 추가된 변수가 서버에서 변경될 때만 동기화 작업이 이루어집니다.
[Command]나 [Server] 어트리뷰트가 추가된 메서드에서 그 변수가 변경되면 되겠습니다.
물론 모든 클라이언트의 같은 인스턴스에서만 일어나는 일이겠습니다.
같은 인스턴스로 식별되기 위해선 NetworkIdentity가 필요할 것입니다.
여기서 값만 변경되면 심심하니 값이 바뀔 때 자동으로 호출되는 메서드도 설정할 수 있습니다.
[Hook] 어트리뷰트에 그 메서드를 추가하면 그 메서드는 동기화가 일어날 때마다 호출 됩니다.
다만 메서드는 매개변수로 [SyncVar]로 설정된 변수와 같은 타입의 변수 두 개가 필요합니다.
반드시.
첫 번째 인자값은 그 변수가 바뀌기 전의 값이고 두 번째 인자값은 그 변수가 바뀌고 난 후의 값입니다.
무슨 원린지는 모릅니다만 [Hook] 메서드가 호출 되면서 인자값이 자동으로 지정됩니다.
(+추가) SyncVar 속성의 변수 동기화는 모든 클라이언트에서 동시에 일어나지 않을 것입니다.
서버에서 값을 바꾼 후 ClientRPC 속성의 메서드를 실행해도
변수의 동기화보다 메서드의 실행이 먼저 이루어질 수 있습니다.
값이 바뀐 후 실행되어야할 메서드는 Hook에 등록하여 쓰길 바랍니다.
- 네트워크 객체라면? => NetworkIdentity 컴포넌트를 추가한다.
- [SyncVar] 를 사용하겠다면? => [Command] 나 [Server] 속성의 메서드에서 바꾼다. (=서버에서 바꾼다.)
- 변경될 때마다 호출할 메서드가 있다면? => 그 변수에 [Hook]을 추가하고 원하는 메서드를 등록한다.
아래는 사용법.
using UnityEngine;
using Mirror;
public class Player : NetworkBehaviour
{
[SyncVar(hook = nameof(OnHealthChanged))]
public int health;
private void OnHealthChanged(int oldValue, int newValue)
{
Debug.Log($"Health changed from {oldValue} to {newValue}");
}
[Command]
public void CmdTakeDamage(int damage)
{
if (!isServer) return;
health -= damage;
if (health < 0) health = 0;
}
}
안전하게 서버에서만 값 변경이 이뤄지도록 if (!isServer) return; 을 사용하는 게 좋습니다.
NetworkIdentity, SyncVar, Hook, Command 는 한 세트
저는 그냥 외우겠습니다 ...
'유니티 > Mirror' 카테고리의 다른 글
[Room Scene] ReadyToBegin에서 ServerChangeScene까지 (0) | 2024.09.01 |
---|---|
GPT) Mirror의 콜백 함수를 순서대로 정리'해줘' (0) | 2024.08.29 |
[Unity Mirror] Do not use Start ! (0) | 2024.08.28 |