티스토리 뷰

[SyncVar]라는 Attribute가 있습니다.

이 어트리뷰트를 추가한 기본 데이터형(int, float, string...)의 변수는

네트워크 상에서 동기화됩니다.

(+추가) 다만, Server에서 Spawn을 통해 생성된 네트워크 객체에서만 작동합니다.

[SyncVar]가 추가된 변수가 서버에서 변경될 때만 동기화 작업이 이루어집니다.

[Command][Server] 어트리뷰트가 추가된 메서드에서 그 변수가 변경되면 되겠습니다.

물론 모든 클라이언트의 같은 인스턴스에서만 일어나는 일이겠습니다.

같은 인스턴스로 식별되기 위해선 NetworkIdentity가 필요할 것입니다.

여기서 값만 변경되면 심심하니 값이 바뀔 때 자동으로 호출되는 메서드도 설정할 수 있습니다.

[Hook] 어트리뷰트에 그 메서드를 추가하면 그 메서드는 동기화가 일어날 때마다 호출 됩니다.

다만 메서드는 매개변수로 [SyncVar]로 설정된 변수와 같은 타입의 변수 두 개가 필요합니다.

반드시.

첫 번째 인자값은 그 변수가 바뀌기 전의 값이고 두 번째 인자값은 그 변수가 바뀌고 난 후의 값입니다.

무슨 원린지는 모릅니다만 [Hook] 메서드가 호출 되면서 인자값이 자동으로 지정됩니다.

(+추가) SyncVar 속성의 변수 동기화는 모든 클라이언트에서 동시에 일어나지 않을 것입니다.

서버에서 값을 바꾼 후 ClientRPC 속성의 메서드를 실행해도

변수의 동기화보다 메서드의 실행이 먼저 이루어질 수 있습니다.

값이 바뀐 후 실행되어야할 메서드는 Hook에 등록하여 쓰길 바랍니다.

 

  1. 네트워크 객체라면? => NetworkIdentity 컴포넌트를 추가한다.
  2. [SyncVar] 를 사용하겠다면? => [Command][Server] 속성의 메서드에서 바꾼다. (=서버에서 바꾼다.)
  3. 변경될 때마다 호출할 메서드가 있다면? => 그 변수에 [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 는 한 세트

 

저는 그냥 외우겠습니다 ...

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함