이동 동기화 #3

Eunho Bae·2022년 6월 24일

버그 수정

  1. 시작하자마자 제자리 걸음을 하는 버그
  2. 벽 바로 옆에서 이동하다가 방향을 벽쪽으로 틀어버리면 다른 클라이언트에서 계속 이동하던 방향으로 이동

위 두가지 버그를 수정하고자 한다.

두번째 버그

먼저 두번째 버그는 계속 Moving 상태이면서 CellPos가 변하지 않았기 때문에 if(prevState != State || CellPos != prevCellPos) 이 부분에서 계속 false가 나서 이동 패킷을 서버로 전송하지 못했기 때문에 발생한 버그였다.

따라서 CreatureController에서 _updated bool 변수를 둔 후 CellPos, State, Dir 셋 중 하나가 변경될 경우 true로 만들고 CheckUpdateFlag() 함수로 갱신이 되야할 상황을 체크해주는 방식으로 변경하였다.

CreatureController

protected bool _updated = false;

	public Vector3Int CellPos 
	{ 
		get
		{
			return new Vector3Int(PosInfo.PosX, PosInfo.PosY, 0);
		}

		set
		{
			if (PosInfo.PosX == value.x && PosInfo.PosY == value.y)
				return;

			PosInfo.PosX = value.x;
			PosInfo.PosY = value.y;
			_updated = true;
		}
	}

	protected Animator _animator;
	protected SpriteRenderer _sprite;

	public virtual CreatureState State
	{
		get { return PosInfo.State; }
		set
		{
			if (PosInfo.State == value)
				return;

			PosInfo.State = value;
			UpdateAnimation();
			_updated = true;
		}
	}

	protected MoveDir _lastDir = MoveDir.Down;
	public MoveDir Dir
	{
		get { return PosInfo.MoveDir; }
		set
		{
			if (PosInfo.MoveDir == value)
				return;

			PosInfo.MoveDir = value;
			if (value != MoveDir.None)
				_lastDir = value;

			UpdateAnimation();
			_updated = true;
		}
	}

MyPlayerController

protected override void MoveToNextPos()
	{
		if (Dir == MoveDir.None)
		{
			State = CreatureState.Idle;
			CheckUpdateFlag();
			return;
		}

		Vector3Int destPos = CellPos;

		switch (Dir)
		{
			case MoveDir.Up:
				destPos += Vector3Int.up;
				break;
			case MoveDir.Down:
				destPos += Vector3Int.down;
				break;
			case MoveDir.Left:
				destPos += Vector3Int.left;
				break;
			case MoveDir.Right:
				destPos += Vector3Int.right;
				break;
		}

		if (Managers.Map.CanGo(destPos))
		{
			if (Managers.Object.Find(destPos) == null)
			{
				CellPos = destPos;
			}
		}

		CheckUpdateFlag();
	}

	void CheckUpdateFlag()
    {
		if(_updated)
        {
			C_Move movePacket = new C_Move();
			movePacket.PosInfo = PosInfo;
			Managers.Network.Send(movePacket);
			_updated = false;
		}
    }

첫번째 버그

CreatureController

	protected virtual void Init()
	{
		_animator = GetComponent<Animator>();
		_sprite = GetComponent<SpriteRenderer>();
		Vector3 pos = Managers.Map.CurrentGrid.CellToWorld(CellPos) + new Vector3(0.5f, 0.5f);
		transform.position = pos;

		State = CreatureState.Idle;
		Dir = MoveDir.None;
		CellPos = new Vector3Int(0, 0, 0);
		UpdateAnimation();
	}

클라이언트 쪽에서 처음 초기화할때 직접적으로 초기화시켜줌으로써 실행하자마자 제자리 걸음을 하는 버그를 해결할 수 있다.

세번째 버그

세번째 버그는 A 플레이어가 벽을 보고 계속 움직이다가 멈추면, B플레이어 화면에서 A플레이어가 무조건 아래쪽으로 방향을 전환해버리는 버그가 생겼다. 이 버그는 PositionInfo에서 _positionInfo = value;에서 생긴 버그로, 이 부분만 실행하게 되면 Dir에서 _lastDir가 갱신되는 부분이 누락되어 버리게 된다. 따라서 아래와 같이 바꿔주도록 한다.

public PositionInfo PosInfo
	{
		get { return _positionInfo; }
		set
		{
			if (_positionInfo.Equals(value))
				return;

			CellPos = new Vector3Int(value.PosX, value.PosY, 0);
			State = value.State;
			Dir = value.MoveDir;
		}
	}

네번째 버그

플레이어가 나갔는데 사라지지 않는 버그.
이 버그는 ObjectManager에서 Dictionary에서만 삭제해주었기 때문이다.

	public void Remove(int id)
	{
		GameObject go = FindById(id);
		if (go == null)
			return;

		_objects.Remove(id);
		Managers.Resource.Destroy(go);
	}
	public void Clear()
	{
		foreach (GameObject obj in _objects.Values)
			Managers.Resource.Destroy(obj);
		_objects.Clear();
	}
profile
개인 공부 정리

0개의 댓글