protected override void MoveToNextPos()
{
CreatureState prevState = State;
Vector3Int prevCellPos = CellPos;
base.MoveToNextPos();
if (prevState != State || CellPos != prevCellPos)
{
C_Move movePacket = new C_Move();
movePacket.PosInfo = PosInfo;
Managers.Network.Send(movePacket);
}
}
public void Send(IMessage packet)
{
_session.Send(packet);
}
public void Send(IMessage packet)
{
string msgName = packet.Descriptor.Name.Replace("_", string.Empty);
MsgId msgId = (MsgId)Enum.Parse(typeof(MsgId), msgName);
ushort size = (ushort)packet.CalculateSize();
byte[] sendBuffer = new byte[size + 4];
Array.Copy(BitConverter.GetBytes((ushort)(size + 4)), 0, sendBuffer, 0, sizeof(ushort));
Array.Copy(BitConverter.GetBytes((ushort)msgId), 0, sendBuffer, 2, sizeof(ushort));
Array.Copy(packet.ToByteArray(), 0, sendBuffer, 4, size);
Send(new ArraySegment<byte>(sendBuffer));
}
MyPlayerController에서 현재 플레이어의 상태 또는 위치가 변경되었다면 이동 패킷을 만들고 Send해준다. 그 패킷은 NetworkManager의 Send 함수로 받아와서 ServerSession의 Send로 넘어가는데 이곳에서 직렬화되어 서버로 전송될 것이다.
서버에서 변경된 이동 패킷을 받고 서버에서 내 좌표를 이동 패킷을 토대로 갱신한 후 다시 클라이언트로 쏴주는데 이때 S_MoveHandler에서 받은 패킷을 처리하게 된다.
public static void S_MoveHandler(PacketSession session, IMessage packet)
{
S_Move movePacket = packet as S_Move;
ServerSession serverSession = session as ServerSession;
GameObject go = Managers.Object.FindById(movePacket.PlayerId);
if (go == null)
return;
CreatureController cc = go.GetComponent<CreatureController>();
if (cc == null)
return;
cc.PosInfo = movePacket.PosInfo; // 클라이언트가 이미 이동시켰기 때문에 굳이 다시 한번 덮어씌어줄 필요는...?
}
public GameObject FindById(int id)
{
GameObject go = null;
_objects.TryGetValue(id, out go);
return go;
}
서버의 허락을 받지 않고 클라이언트에서 멋대로 움직이다보면 조금씩 틀어지는 경우 -> 서버 정보와 클라 정보와 비교해서 교정해줘야 한다. (서버쪽에 저장된 정보가 우선시)