ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20230928 플레이어 버그와 최적화
    기록 2023. 9. 28. 16:40

    문제 상황1)

    바라보는 방향과, 이동 방향이 일치하지 않는 문제점

    이와같이 바라보는 방향과 실제 움직이는 방향이 다른 문제가 발생한다.

     

     

    플레이어가 가지고 있는 방향값 중

    NextForwardDir와 MoveDir이 일치하지 않아 발생한다.


    NextForwardDir 가 존재하는 이유는 플레이어가 바라보는 방향을 변경할 때 Lerp로 변경하길 원해서 ForwardDir를 만들면서 추가하였는데

    실제 MoveDir이 최종 NextForwardDir이 되기때문에 존재의 필요성을 느끼지 못하게 되었다.

     

    해결1)

    이동 방향(MoveDir)과 바라봐야 하는 방향(NextForwardDir)을 통일한다.

    또한 ForWardDir이 방향에 대한 input이 있는경우만 변경되기 때문에 모든 Update에서 지속적으로 적용되도록 하였다.


    결과)

    이동방향과 바라보는 방향이 달라 이상한 액션이 생기는 버그가 사라졌다.

     

     


    문제 상황2) 

    방향의 입력 값이 일부 씹히는 문제

     

    void Player::CheckInput(float _DeltaTime)
    {
    	// Falling Check
    	float4 PlayerGroundPos = GetTransform()->GetWorldPosition();
    	float4 CollPoint = float4::ZERO;
    	if (true == m_pCapsuleComp->RayCast(PlayerGroundPos, float4::DOWN, CollPoint, 2000.0f))
    	{
    		float4 PPos = GetTransform()->GetWorldPosition();
    		if (PPos.y > CollPoint.y + 60.0f)
    		{
    			SetNextState(PlayerState::FALLING);
    			return;
    		}
    	}
    
    	// Attack Check
    	// special state input
    	StateInputDelayTime -= _DeltaTime;
    	if (StateInputDelayTime > 0.0f)
    	{
    		return;
    	}
    	if (true == GameEngineInput::IsDown("PlayerRoll")) // roll antmation inter이 필요함
    	{
    		SetNextState(PlayerState::ROLL);
    		return;
    	}
    	if (true == GameEngineInput::IsPress("PlayerLBUTTON"))
    	{
    		SetNextState(PlayerState::BASE_ATT);
    		return;
    	}
    	if (true == GameEngineInput::IsPress("PlayerRBUTTON"))
    	{
    		SetNextState(PlayerState::SKILL);
    		return;
    	}
    	if (true == GameEngineInput::IsPress("PlayerMBUTTON"))
    	{
    		SetNextState(PlayerState::CHARGE_ATT);
    		return;
    	}
    
    	// Move Check
    	// move state input
    	float4 Dir = float4::ZERO;
    	if (true == GameEngineInput::IsPress("PlayerLeft"))
    	{
    		Dir += float4::LEFT; // 0 -90 0
    	}
    	if (true == GameEngineInput::IsPress("PlayerRight"))
    	{
    		Dir += float4::RIGHT; // 0 90 0
    	}
    	if (true == GameEngineInput::IsPress("PlayerUp"))
    	{
    		Dir += float4::FORWARD; // 0 0 0
    	}
    	if (true == GameEngineInput::IsPress("PlayerDown"))
    	{
    		Dir += float4::BACK; // 0 180 0
    	}
    
    	if (false == Dir.IsZero()) //  방향 입력이 있다면
    	{
    		SetNextState(PlayerState::WALK);
    		//DirectionUpdate(_DeltaTime);
    		MoveDir = Dir.NormalizeReturn();
    		MoveUpdate(PlayerMoveSpeed);
    	}
    	else // 방향 입력이 없다면 IDLE
    	{
    		if (false == StateChecker && GetCurState<PlayerState>() == PlayerState::WALK)
    		{
    			StateChecker = true;
    			return;
    		}
    		else
    		{
    			SetNextState(PlayerState::IDLE);
    		}
    	}
    }

    현재 state 체크 순서는

    1. FALLING

    2. ROLL, BASE_ATT, SKILL, CHARGE_ATT, 

    3. WALK, IDLE

    순서로 체크하고 state가 변경되면  return하도록 만들었다.

     

    3번에서 방향값을 입력받기 때문에 1,2에서 값을 입력받으면 무시된다.

    해결2)

    1,2,3 을 세개의 함수로 분리한다

     

    => FALLING

    => WALK

    => ROLL,BASE_ATT, SKILL, CHARGE_ATT

    void Player::CheckFalling()
    {
    	// Falling Check
    	float4 PlayerGroundPos = GetTransform()->GetWorldPosition();
    	float4 CollPoint = float4::ZERO;
    	if (true == m_pCapsuleComp->RayCast(PlayerGroundPos, float4::DOWN, CollPoint, 2000.0f))
    	{
    		float4 PPos = GetTransform()->GetWorldPosition();
    		if (PPos.y > CollPoint.y + 60.0f)
    		{
    			SetNextState(PlayerState::FALLING);
    			return;
    		}
    	}
    }
    void Player::CheckDirInput(float _DeltaTime)
    {
    	float4 Dir = float4::ZERO;
    	if (true == GameEngineInput::IsPress("PlayerLeft"))
    	{
    		Dir += float4::LEFT; // 0 -90 0
    	}
    	if (true == GameEngineInput::IsPress("PlayerRight"))
    	{
    		Dir += float4::RIGHT; // 0 90 0
    	}
    	if (true == GameEngineInput::IsPress("PlayerUp"))
    	{
    		Dir += float4::FORWARD; // 0 0 0
    	}
    	if (true == GameEngineInput::IsPress("PlayerDown"))
    	{
    		Dir += float4::BACK; // 0 180 0
    	}
    
    	if (false == Dir.IsZero()) //  방향 입력이 있다면
    	{
    		SetNextState(PlayerState::WALK);
    		MoveDir = Dir.NormalizeReturn();
    		MoveUpdate(PlayerMoveSpeed);
    	}
    	else // 방향 입력이 없다면 IDLE
    	{
    		if (false == StateChecker && GetCurState<PlayerState>() == PlayerState::WALK)
    		{
    			StateChecker = true;
    			return;
    		}
    		else
    		{
    			SetNextState(PlayerState::IDLE);
    		}
    	}
    }
    void Player::CheckStateInput(float _DeltaTime)
    {
    	if (true == GameEngineInput::IsDown("PlayerRoll")) // roll antmation inter이 필요함
    	{
    		SetNextState(PlayerState::ROLL);
    	}
    	else if (true == GameEngineInput::IsPress("PlayerLBUTTON"))
    	{
    		SetNextState(PlayerState::BASE_ATT);
    	}
    	else if (true == GameEngineInput::IsPress("PlayerRBUTTON"))
    	{
    		SetNextState(PlayerState::SKILL);
    	}
    	else if (true == GameEngineInput::IsPress("PlayerMBUTTON"))
    	{
    		SetNextState(PlayerState::CHARGE_ATT);
    	}
    }

    우선순위에 해당하는 State가 최종 NextState가 될수 있도록 CheckState를 정한다.

    StateInput함수가 최종 NextState가 된다면 CheckDirInput정한 MoveUpdate가 동작하지 않도록  FSM Start에 코드를 추가하였다.

     

    결과)

    방향에 대한 입력값과 state변경에 대한 입력값이 동식에 적용된다.

    댓글

Designed by Tistory.