Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
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
Archives
Today
Total
관리 메뉴

김산나

[멋쟁이사자처럼부트캠프 유니티 게임 개발 7기] 2026년 5월 27일 회고록 - Unity Netcode 2 본문

Unity Engine

[멋쟁이사자처럼부트캠프 유니티 게임 개발 7기] 2026년 5월 27일 회고록 - Unity Netcode 2

김산나 2026. 5. 27. 11:45

2026_05_27 강의 요약본

 

1. 네트워크 변수

네트워크로 동기화되는 변수. 선언 방법은 다음과 같다.

public class TempController : NetworkBehaviour
{
	// 네트워크에서 동기화되는 변수
 	NetworkVariable<int> randNum = new NetworkVariable<int>(1,
 	NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
	// 괄호 안 = Default 값, 읽을 수 있는 권한 범위, 쓸 수 있는 권한 범위
}

 

NetworkVariable<자료형>으로 선언한다.

권한을 직접 지정하지 않는 경우, 읽기는 Everyone, 쓰기는 Server(Host)가 기본으로 세팅된다.

 

* 자료형은 기본 형식(숫자), 벡터, 색상, 레이, enum...값을 바로 넣는 타입의 변수들, 구조체, 길이가 고정된 string을 전달할 수 있다. - FixedString32Bytes ~ FixedString4096Bytes까지.

 

    void Update()
    {        
        Debug.Log($"owner id: "+ OwnerClientId + "\nRandom number: "+ randNum.Value);

        if(!IsOwner) return; // 주인이 아니라면 하단 코드 실행 금지


        // T키를 입력 시 랜덤 숫자 추첨
        if(Input.GetKeyDown(KeyCode.T))
        {
            randNum.Value = Random.Range(0, 100);
        }     
    }

 

테스트 코드를 작성한다.

T키를 누르면 랜덤 숫자를 추첨한다.

 

권한 설정이 기본인 읽기는 Everyone, 쓰기는 Server인 경우, 호스트를 제외한 유저는 번호 추첨을 할 수 없다.

하지만 권한을 수정하여 NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner로 변경한다면

모든 유저가 수정한 것을 확인할 수 있다.

 

네트워크 변수는 서버의 유일한 변수를 생성하는 것이 아닌, 유저마다 다른 값을 갖는다.

 

플레이어 1은 39를 추첨했고, 플레이어 2는 35를 추첨했다.

 

* 네트워크 구조체

public class TempController : NetworkBehaviour
{

    struct SomeData : INetworkSerializable
    {
        public int someInt;
        public bool someBool;

        public void NetworkSerialize<T> (BufferSerializer<T> serializer) where T : IReaderWriter
        {
            serializer.SerializeValue(ref someInt);
            serializer.SerializeValue(ref someBool);
        }
    }
    NetworkVariable<SomeData> randNum = new NetworkVariable<SomeData>(new SomeData { someInt = 1, someBool = false },
    NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
    // 괄호 안 = Default 값, 읽을 수 있는 권한 범위, 쓸 수 있는 권한 범위

    void Update()
    {
        Debug.Log("owner id: "+ OwnerClientId + "\nRandom number: "+
        randNum.Value.someInt + "\nBool: " + randNum.Value.someBool);

        if(!IsOwner) return;
        if(Input.GetKeyDown(KeyCode.T))
        {
            randNum.Value = new SomeData { someInt = Random.Range(0, 100), someBool = true };
        }   
    }


}

 

 

 

 

플레이어 1, 2 둘 다 정상적으로 찍히는 걸 볼 수 있다.

 

 

* 네트워크 문자열 변수

    // 네트워크 변수 - String
    NetworkVariable<FixedString32Bytes> netString = new NetworkVariable<FixedString32Bytes>
    ("", NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);

 

...

void Update()
    {
        Debug.Log("String: " + netString.Value + "\nowner id: "+ OwnerClientId + "\nRandom number: "+
        randNum.Value.someInt + "\nBool: " + randNum.Value.someBool);
        
        ...

        if(Input.GetKeyDown(KeyCode.R))
        {
            netString.Value = "가나다라마바사";
        }
        
    }

 

 

 

2. RPC(Remote Procedure Call)

Host, Client가 다른 유저의 요소를 호출하기 위한 기술. 사용법은 다음과 같다.

 

    [Rpc(SendTo.Server)]
    private void TestServerRPC(int number, string msg, RpcParams rpcParams = default)
    {
        Debug.Log("called Owner ID" + OwnerClientId + "Received number " + number + "and message: " + msg
        + "sender client ID: " + rpcParams.Receive.SenderClientId);
    }

[Rpc(SendTo.대상)] ... 메서드 작성 ...

 

void Update()
{
        if(Input.GetKeyDown(KeyCode.R))
        {
            TestServerRPC(Random.Range(0, 100), "Hello Server!", new RpcParams());
        }
}

 

테스트 코드 작성.

 

위 예시 코드는 Server(Host)로만 전송하는 RPC 예제이다. 특정 유저에게 보내려면 어떻게 해야 할까?

 

    [Rpc(SendTo.SpecifiedInParams)] // 파라미터로 받을 대상 직접 지정
    void TestClientRpc(RpcParams rpcParams = default)
    {
        Debug.Log("called Owner ID" + OwnerClientId + "sender client ID: " + rpcParams.Receive.SenderClientId);
    }

 

SendTo.(대상) 대상에 특정 파라미터를 받겠다고 선언하고, 매개변수로 파라미터 값을 받으면 된다.

 

        ...
        
        if(Input.GetKeyDown(KeyCode.Alpha1))
        {
            TestClientRpc(RpcTarget.Single(0, RpcTargetUse.Temp));
            // 0번을 타겟으로 하겠다.
        }
        if(Input.GetKeyDown(KeyCode.Alpha2))
        {
            TestClientRpc(RpcTarget.Single(1, RpcTargetUse.Temp));
            // 1번을 타겟으로 하겠다.
        }
        if(Input.GetKeyDown(KeyCode.Alpha3))
        {
            TestClientRpc(RpcTarget.Single(2, RpcTargetUse.Temp));
            // 2번을 타겟으로 하겠다.
        }
        
        ...

0번 - 호스트
2번 - 두 번째로 접속한 유저

 

3번 - 세 번째로 접속한 유저

 

<응용>

특정 키를 눌러 플레이어 자신의 색상을 랜덤하게 변경한다.

 

[Rpc(SendTo.Everyone)]
void TestChangeColorRPC(Color color, RpcParams rpcParams = default)
{
    transform.GetChild(0).GetComponent<Renderer>().material.color = color;
}

void Update()
    {
    
    if(!IsOwner) return;
    
    if(Input.GetKeyDown(KeyCode.Alpha1))
        {
            if(OwnerClientId == 0)
            {
                Color randomColor = Random.ColorHSV();
                TestChangeColorRPC(randomColor);
            }
        }
        if(Input.GetKeyDown(KeyCode.Alpha2))
        {
            if(OwnerClientId == 1)
            {
                Color randomColor = Random.ColorHSV();
                TestChangeColorRPC(randomColor);
            }
        }
        if(Input.GetKeyDown(KeyCode.Alpha3))
        {
            if(OwnerClientId == 2)
            {
                Color randomColor = Random.ColorHSV();
                TestChangeColorRPC(randomColor);
            }
        }
    
    }

 

* IsOwner 판정을 통해 플레이어 자신의 오브젝트만 제어하도록 한다.

* Alpha0 vs KeyPad0: 전자는 키보드 상단 키패드이고, 후자는 텐키이다.

* Random.ColorHSV(): 랜덤 컬러 함수

* transform.GetChild(0).GetComponent<Renderer>().material.color = color

자식의 색상을 변경하는 코드. (3D 오브젝트 기준) 플레이어 오브젝트 구조가 다음과 같아 이렇게 짠다.

 

결과

플레이어가 특정 버튼을 누를 때, 자신의 캐릭터 색상만 변경할 수 있다.

 

 

===========================================================