유니티 연동

ㅋㅋ·2022년 11월 4일

csharp게임서버

목록 보기
16/16

서버에서 사용하던 더미 클라이언트 코드를 유니티에 넣었을 때,

유니티 정책 및 유니티, 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: 특정 좌표로 이동 요청


  • player manager
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) 범위의 임의 위치로 주기적으로 이동

0개의 댓글