방프리
21.04.10 Nodejs Socket.IO를 이용한 Unity 통신 (응용편) 본문
이제 접속이 되었다는 로그를 확인하였으니 데이터 송,수신을 통해서 플레이어 동기화를 진행해보자.
포톤도 공부해보고 있는데 PUN 모델을 기준으로 설명하면 간단하게 다음과 같다.
어렵게 생각할 필요 없이 서버는 각각의 클라이언트에서 보내준 데이터를 받고 그대로 다른 클라이언트들에게
데이터를 보내주는 역할만 한다.
서버코드는 다음과 같다.
const socketIO = require('socket.io')(5000);
console.log('Server Start : port 5000');
socketIO.on('connection', function(socket) {
console.log(`Player Connected : ${socket.id}`);
//플레이어의 위치가 수정되면
socket.on('PlayerMove', function (args) {
//나를 제외한 모든 다른 유저들에게 나의 위치값을 전송한다.
socket.broadcast.emit('OtherPlayerMove', socket.id, args);
});
//내가 접속되었다면 다른 유저들에게 내가 접속함을 알린다.
socket.broadcast.emit('OtherPlayerConnect', socket.id);
socket.on('disconnect', function() {
console.log('Player Disconnected');
//내가 접속을 끊으면 다른 유저들에게 내가 로그아웃함을 알린다.
socket.broadcast.emit('OtherPlayerDisconnected', socket.id);
});
});
클라이언트에서 유저가 접속 후 다른 클라이언트에서도 위치와 애니메이션이 동기화 되는 것을 구현해보자.
public class GameManager
{
[SerializeField] private GameObject playerPrefabs = null;
private List<GameObject> playerCharacters = new List<GameObject>();
//플레이어 스폰 타이밍은 적절히 해주자.
public void SpawnPlayer(string name)
{
var player = Instantiate(playerPrefabs, Vector3.zero, Quaternion.identity, null) as GameObject;
player.gameObject.name = name;
playerCharacters.Add(player);
}
}
public class PlayerController
{
private SocketIOManager socketIOManager = null;
private int currentPlayerAnim = 0;
private void Start()
{
socketIOManager = SocketIOManager.Instance;
}
private void Update()
{
//.... 플레이어 움직임, 애니메이션 업데이트
socketIOManager.SendTransformAndAnimationData(this.transform, currentPlayerAnim);
}
}
public class PacketTransformData
{
public Vector3 position;
public Quaternion rotation;
public Vector3 scale;
public int animationNumber;
}
public class SocketIOManager
{
public static SocketIOManager Instance = null;
private SocketManager socketManager = null;
private void Awake()
{
Instance= this;
}
private void Start()
{
SocketOptions options = new SocketOptions();
options.AutoConnect = false;
socketManager = new SocketManager(new System.Uri(address), options);
socketManager.Open();
socketManager.Socket.On<ConnectResponse>(SocketIOEventTypes.Connect, OnConnected);
socketManager.Socket.On<ConnectResponse>(SocketIOEventTypes.Disconnect, OnDisconnected);
}
public void SendTransformAndAnimationData(Transform trans, int animNumber)
{
var CopyTransData = new PacketTransformData();
CopyTransData.position = trans.position;
CopyTransData.rotation = trans.rotation;
CopyTransData.scale = trans.localScale;
CopyTransData.animationNumber = animNumber;
string sendJson = JsonUtility.ToSJson(CopyTrans);
socketManager.Socket.Emit("PlayerMove", sendJson);
}
}
자.... 내용이 길지만 그다지 어렵진 않다. 플레이어를 스폰 후에 Update마다 변경되는 위치 및 애니메이션 값을
Json형태로 직렬화(데이터들을 하나의 Byte 배열 또는 문자열로 만드는 것)하여 그대로 웹 서버에 보내고
웹 서버에서는 그대로 다른 클라이언트들에 뿌리고 다른 클라이언트들은 데이터를 보낸 유저의 소켓 ID를 통해
전달받은 데이터를 역직렬화 시킨 후 변화를 주는 것이다.
원래는 새로 들어온 유저가 현재 접속해있는 모든 소켓 유저들의 상태값을 받아서 표현해주고 싶었으나....
그럴 경우 한 번에 굉장히 큰 양의 패킷이 생성될 것 같기도 했고, Update 구문에서 계속 위치와 상태값을 보내주니
굳이 필요성을 느끼지 못했다.
하지만 방을 생성하여 플레이하는 게임에서는 기존에 접속해 있는 유저들의 상태값을 알아야 하기 때문에
이 부분은 조금 더 공부해보아야겠다.
'Server&Network > Node.js' 카테고리의 다른 글
21.03.27 Nodejs Socket.IO를 이용한 Unity 통신 (연결편) (0) | 2021.03.27 |
---|
Comments