Mirror Networking

[Mirror Networking] SyncVar

오락쟁이의 블로그 2025. 1. 10. 19:42

Mirror Networking에서는 Attribute를 이용해 간편하게 Network Message를 주고 받을 수 있습니다.

 

만약 Network Message에 대해 알고 싶으시면 아래 글을 읽어 주세요.

https://orakjaengi.tistory.com/entry/Mirror-Networking-Network-Message%EB%9E%80

 

[Mirror Networking] Network Message란?

목차 1. Network Message란? 2. Network Message 사용법  2-1. NetworkMessage를 상속하는 구조체 혹은 클래스를 생성  2-2. 서버나 클라이언트에서 메시지를 등록  2-3. 메시지에 데이터를 담고 메시지를 발송  2

orakjaengi.tistory.com

 

목차
1. SyncVar란?
2. 사용법
3. hook

 

SyncVar란?

SyncVar는 Mirror Networking에서 서버와 클라이언트 간 변수 값을 동기화하기 위해 사용되는 Attribute입니다. 변수 값을 변경하면, 해당 변경 사항이 자동으로 모든 클라이언트 혹은 서버에 동기화되도록 만듭니다.

  • 기본 동작:
    SyncVar로 선언된 변수의 값을 변경하면, Mirror가 이를 자동으로 모든 클라이언트 혹은 서버에 전송하여 변수 값을 업데이트합니다.
  • 제한 사항
    • SyncVar는 필드에만 적용됩니다. 프로퍼티에는 사용할 수 없습니다.
    • 주로 간단한 데이터 타입(int, float, string, bool 등)에 사용됩니다.

 

사용법

1. SyncVar 선언

using Mirror;
using UnityEngine;

public class Player : NetworkBehaviour
{
    [SyncVar]
    public int hp = 100;
}

2. 변수 값 변경

SyncDirection의 값을 통해 클라이언트에서 변경한 값을 서버에 동기화할 것인지 서버에서 변경한 값을 모든 클라이언트에 동기화할 것인지 정할 수 있습니다.

  • Client To Server일 경우
    • 클라이언트에서 값을 변경하면 서버에서도 값이 변경되며, 다른 클라이언트들의 값은 바뀌지 않습니다.
    • 서버에서 변경된 값이 클라이언트에 반영되지 않습니다.
  • Server To Client일 경우
    • 서버에서 값을 변경하면 모든 클라이언트에서도 값이 변경됩니다.
    • 클라이언트에서 변경된 값이 서버에 반영되지 않습니다.
using Mirror;
using UnityEngine;

public class Player : NetworkBehaviour
{
    [SyncVar]
    public int hp = 100;
    
    public void Damaged(int damage)
    {
        hp -= damage;
    }
}

 

hook

hook이란?

SyncVar가 클라이언트나 서버에서 동기화될 때, 특정 로직을 실행하고 싶다면 hook 메서드를 사용할 수 있습니다. hook은 SyncVar의 값이 변경될 때 호출되는 콜백 함수로, 변경된 값을 기반으로 UI 업데이트나 추가 처리를 수행할 수 있습니다.

  • 형식
    • [SyncVar(hook = "MethodName")]으로 설정합니다.
  • 제약
    • 메서드의 매개변수는 반드시 (oldValue, newValue) 형식이어야 합니다.
using Mirror;
using UnityEngine;
using UnityEngine.UI;

public class Player : NetworkBehaviour
{
    [SyncVar(hook = nameof(OnHpChanged))]
    public int hp;
    private int maxHp = 100;
    public Slider hpBar;
    
    public override void OnStartClient()
    {
        base.OnStartClient();

        hp = maxHp;   
    }
    
    public void Damaged(int damage)
    {
        hp -= damage;
    }
    
    private void OnHpChanged(int oldHp, int newHp)
    {
        hpBar.value = (float)newHp / maxHp;
    }
}