ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 유니티 스팀 멀티 연동하기 - 3. 플레이어 및 변수 연동
    Unity 2023. 10. 13. 21:30
    728x90

    [유니티 스팀 멀티 연동하기 - 2. 로비]

     

    변수를 연동하는 방법은 간단하다.

    이미 이전 글에서도 사용했었지만, SyncVar 어트리뷰트를 사용하면 된다.

    이전 장에서 작성했던 PlayerObjectController 스크립트에서 플레이어의 이름을 공유하는 기능을 추가하도록 변경한다.

    플레이어 이름은 스팀에서 설정한 이름을 가져오도록 한다.

     

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Mirror;
    using Steamworks;
     
    public class PlayerObjectController : NetworkBehaviour
    {
        #region MEMBER_BASE
        [SyncVar]
        public int ConnectionID;
        [SyncVar]
        public int PlayerIdNumber;
        [SyncVar]
        public ulong PlayerSteamID;
        [SyncVar(hook = nameof(PlayerNameUpdate))]
        public string PlayerName;
     
        private CustomNetworkManager manager;
        private CustomNetworkManager Manager
        {
            get
            {
                if (manager != null)
                {
                    return manager;
                }
                return manager = CustomNetworkManager.singleton as CustomNetworkManager;
            }
        }
     
        #endregion
     
     
        private void Start()
        {
            DontDestroyOnLoad(this.gameObject);
        }
     
        #region ON_CREATE
     
        public override void OnStartAuthority()
        {
            CmdSetPlayerName(SteamFriends.GetPersonaName().ToString());
            gameObject.name = "LocalGamePlayer";
        }
     
        public override void OnStartClient()
        {
            Manager.GamePlayers.Add(this);
        }
     
        public override void OnStopClient()
        {
            Manager.GamePlayers.Remove(this);
        }
     
        [Command]
        private void CmdSetPlayerName(string playerName)
        {
            this.PlayerNameUpdate(this.PlayerName, playerName);
        }
     
        public void PlayerNameUpdate(string OldValue, string NewValue)
        {
            if(isServer)
            {
                this.PlayerName = NewValue;
            }
            if(isClient)
            {
               
            }
        }
     
     
     
        #endregion
     
    }
    cs

    위의 변수들과는 다르게, 훅 기능을 사용해서 기존값에서 변동이 있을 때 변경하도록 하는 것이다.

    OnStartAuthority()는 자신의 플레이어가 시작했을 때 발동하는 메소드인데, 이때 Command 어트리뷰트를 단 CmdSetPlayerName()을 실행하면서 로비의 모든 사람이 플레이어 이름을 공유받게 된다.

     

     

    다음으로는 이동의 구현이다.

    PlayerObject에서 필요한 컴포넌트

    이동의 경우 Network Transform 컴포넌트가 있어 쉽게 구현할 수 있다.

    다른 플레이어와 Transform 값을 공유하려면 Network Transform을 넣으면 된다.

    Network Transform의 경우, Sync Position, Sync Rotation, Sync Scale의 체크박스를 통해 어느것을 연동하고, 하지 않을지를 정할 수 있다. 컴포넌트의 맨 아래에 Sync Direction은 'Client To Server'로 맞춘다.

     

    Network Transform이 네트워크 기능을 맡고 있기 때문에, 이동 구현의 경우 싱글 게임과 구현 방법이 거의 같다.

    아래의 코드처럼 PlayerMovementController 스크립트를 작성한다.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Mirror;
    using UnityEngine.SceneManagement;
    public class PlayerMovementController : NetworkBehaviour
    {
        public float Speed = 1f;
        void Update()
        {
            if(SceneManager.GetActiveScene().name == Constant.SCENE_GAME)	//Constant.SCENE_GAME은 현재 씬 이름에 맞게 바꿀 것
            {
                if(isLocalPlayer)//예전에는 isOwned였으나, 현재는 바뀜)
                    Move();
            }
        }
        public void SetPosition()
        {
            transform.position = new Vector3(Random.Range(-2, 2), Random.Range(-2, 2));
        }
        public void Move()
        {
            float x = Input.GetAxisRaw("Horizontal");
            float y = Input.GetAxisRaw("Vertical");
            Vector3 dir = new Vector3(x, y);
            transform.position += dir * Speed * Time.deltaTime;
        }
    }

     

    isLocalPlayer 조건문 부분만 유의하면 된다.

    자신의 플레이어일 때만 움직이게 해야 하기 때문이다.

    작성한 스크립트는 PlayerObject 프리팹에 컴포넌트로 추가한다.

    완전한 PlayerObject의 모습

     

    728x90

    댓글

Designed by Tistory.