이동 동기화 #2

Eunho Bae·2022년 6월 24일

이동 패킷 서버로 전송

MyPlayerController

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);
		}
	}

NetworkManager

	public void Send(IMessage packet)
	{
		_session.Send(packet);
	}

ServerSession

	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; // 클라이언트가 이미 이동시켰기 때문에 굳이 다시 한번 덮어씌어줄 필요는...?
	}

ObjectManager

public GameObject FindById(int id)
	{
		GameObject go = null;
		_objects.TryGetValue(id, out go);
		return go;
	}

추가

서버의 허락을 받지 않고 클라이언트에서 멋대로 움직이다보면 조금씩 틀어지는 경우 -> 서버 정보와 클라 정보와 비교해서 교정해줘야 한다. (서버쪽에 저장된 정보가 우선시)

profile
개인 공부 정리

0개의 댓글