유니티/서버

미러 동기화 예제 코드

유니티세상 2025. 6. 16. 17:42

C 누르면 옷 스왑

 



    using Mirror;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;


    public class CharacterCustomize : NetworkBehaviour
    {
        [SerializeField] private SkinnedMeshRenderer outerwearMesh;
        [SerializeField] private List<Mesh> outerwearList;


        // SyncVar를 사용한 방법 - 자동 동기화
        [SyncVar(hook = nameof(OnOuterwearIndexChanged))]

        private int index = 0;

        public void Update()
        {
            if(Input.GetKeyDown(KeyCode.C))
            {
                Set();
            }
        }

        // UI 버튼에서 호출할 메서드 (클라이언트에서 실행)
        public void Set()
        {
            if(isOwned)
            {
                // 클라이언트에서 서버로 명령 전송
                CmdChangeOuterwear();
            }
               

        }

        // 서버에서 실행되는 Command
        [Command]
        public void CmdChangeOuterwear()
        {
            index++;

            if (index >= outerwearList.Count)
            {
                index = 0;
            }

            Debug.Log($"Server: Outerwear index changed to {index}");
        }

        // SyncVar Hook - 값이 변경될 때 모든 클라이언트에서 자동 호출
        private void OnOuterwearIndexChanged(int oldIndex, int newIndex)
        {
            Debug.Log($"index{oldIndex} and {newIndex}");

            if (outerwearList.Count > 0 && newIndex < outerwearList.Count)
            {
                outerwearMesh.sharedMesh = outerwearList[newIndex];
                Debug.Log($"Client: Outerwear changed to index: {newIndex}");
            }
        }

 

 


최종정리

[SyncVar]만 써도 되는 경우

  • 데이터 값의 동기화만 필요할 때
  • 내부 로직에만 쓰이고, 표시되지도 않고, 동작도 트리거하지 않을때

 

 

[SyncVar] Hook을 써야 하는 경우

  • UI를 즉시 업데이트해야 할 때
  • 애니메이션/사운드/이펙트를 즉각 반응시키고 싶을 때
  • 어떤 값이 바뀌었을 때만 뭔가 동작하게 하려면 Hook이 필요함

 

Hook의 예시

변화를 비교하기 위해 이전값과 현재값을 가지고 있음

[SyncVar(hook = nameof(OnHealthChanged))]
private int health;

void OnHealthChanged(int oldValue, int newValue)
{
    healthBar.SetValue(newValue); // 클라이언트 UI 업데이트
}

 

[ClientRpc] / [TargetRpc]를 써야 하는 경우

 

동기화가 아닌 즉시 행동이 필요한 경우

 

  • 애니메이션 재생
  • 효과음/이펙트 실행
  • 특정 조건에서만 실행되어야 하는 로직 등

행동을 클라이언트가 직접 수행해야 하므로 SyncVar로는 안 됨.

여러 값/복합적인 동작을 동시에 처리해야 할 경우

SyncVar는 하나의 변수에만 적용됩니다.  여러 변수/복잡한 로직을 한 번에 보내려면 ClientRpc가 효율적

특정 클라이언트에게만 호출할 때( 비공개 메시지, 개인 상태 갱신 등)