서버에서 사용하던 더미 클라이언트 코드를 유니티에 넣었을 때,
유니티 정책 및 유니티, C# 버전에따라 정상적으로 동작하지 않는 코드들이 있을 수 있음
BitConverter.TryWriteBytes(), Span, ReadOnlySpan 등등...
=> 해당 부분들을 다른 방법을 찾아 대체해야 함
또한 유니티에서는 메인 스레드를 제외한 다른 스레드에서는 유니티 엔진에 접근하는 것이 불가능함
=> 패킷을 받은 후 패킷을 큐에 쌓아두고 오브젝트가 꺼내 쓰는 방식으로 구현
<packet name="S_BroadcastEnterGame">
<int name="playerId"/>
<float name="posX"/>
<float name="posY"/>
<float name="posZ"/>
</packet>
<packet name="C_LeaveGame">
</packet>
<packet name="S_BroadcastLeaveGame">
<int name="playerId"/>
</packet>
<packet name="S_PlayerList">
<list name="player">
<bool name="isSelf"/>
<int name="playerId"/>
<float name="posX"/>
<float name="posY"/>
<float name="posZ"/>
</list>
</packet>
<packet name="C_Move">
<float name="posX"/>
<float name="posY"/>
<float name="posZ"/>
</packet>
<packet name="S_BroadcastMove">
<int name="playerId"/>
<float name="posX"/>
<float name="posY"/>
<float name="posZ"/>
</packet>
S_BroadcastEnterGame: 플레이어가 룸에 들어오면 모든 플레이어에게 이를 알림
S_BroadcastLeaveGame: 특정 플레이어가 룸에서 나가는 것을 모든 플레이어에게 알림
S_PlayerList: 룸에 입장한 플레이어에게 현재 룸에 있는 플레이어 리스트를 보내줌
S_BroadcastMove: 특정 플레이어의 위치 변화를 다른 플레이어들에게 알림
C_LeaveGame: 클라이언트가 룸에서 나간다고 서버로 알림
C_Move: 특정 좌표로 이동 요청
public void Add(S_PlayerList packet)
{
if (_playerObject == null)
{
_playerObject = Resources.Load<GameObject>("Player");
}
for (int i = 0; i < packet.players.Count; i++)
{
GameObject go = GameObject.Instantiate(_playerObject);
if (packet.players[i].isSelf)
{
MyPlayer myPlayer = go.AddComponent<MyPlayer>();
_myPlayer = myPlayer;
_myPlayer.PlayerID = packet.players[i].playerId;
}
else
{
Player player = go.AddComponent<Player>();
player.PlayerID = packet.players[i].playerId;
_players.Add(packet.players[i].playerId, player);
}
go.transform.position
= new Vector3(packet.players[i].posX, packet.players[i].posY, packet.players[i].posZ);
}
}
public void LeaveGame(S_BroadcastLeaveGame leavePacket)
{
if (_myPlayer.PlayerID == leavePacket.playerId)
{
GameObject.Destroy(_myPlayer.gameObject);
_myPlayer = null;
}
else if (_players.TryGetValue(leavePacket.playerId, out var player))
{
player.gameObject.SetActive(false);
GameObject.Destroy(player.gameObject);
}
}
public void EnterGame(S_BroadcastEnterGame enterPacket)
{
if (_myPlayer.PlayerID == enterPacket.playerId)
{
return;
}
if (_playerObject == null)
{
_playerObject = Resources.Load<GameObject>("Player");
}
GameObject go = GameObject.Instantiate(_playerObject);
Player player = go.AddComponent<Player>();
_players.Add(enterPacket.playerId, player);
go.transform.position
= new Vector3(enterPacket.posX, enterPacket.posY, enterPacket.posZ);
}
public void Move(S_BroadcastMove movePacket)
{
Player target;
if (movePacket.playerId == _myPlayer.PlayerID)
{
target = _myPlayer;
}
else if (_players.TryGetValue(movePacket.playerId, out var player))
{
target = player;
}
else
{
return;
}
target.transform.position
= new Vector3(movePacket.posX, movePacket.posY, movePacket.posZ);
}
Add: 룸에 입장하여 플레이어 리스트를 받고 플레이어 오브젝트들을 씬에 추가
LeaveGame: 룸에서 특정 플레이어가 나갈 시 씬에서 플레이어를 제거
EnterGame: 다른 플레이어가 룸에 들어올 시 씬에 플레이어 추가
Move: 플레이어 오브젝트를 해당 좌표에 위치 시킴

501개의 클라이언트들이 (-50 ~ 50, -50 ~ 50) 범위의 임의 위치로 주기적으로 이동