유니티 스팀 멀티 연동하기 - 3. 플레이어 및 변수 연동
변수를 연동하는 방법은 간단하다.
이미 이전 글에서도 사용했었지만, 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()을 실행하면서 로비의 모든 사람이 플레이어 이름을 공유받게 된다.
다음으로는 이동의 구현이다.
이동의 경우 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 프리팹에 컴포넌트로 추가한다.