ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TIL] 14주차 5일 트러블슈팅 ( State가 많이 늘어나면서 생긴 문제들 )
    개발일지/스파르타 코딩클럽 부트캠프 2024. 7. 19. 22:19

     

    최종프로젝트 진행중

    정말 많은 버그가 있었지만, 애니메이션 관련된 버그는 진짜 다 부수고싶다..

    오늘은 그에대한 트러블 슈팅이다.

     

    캐릭터가 마나가 부족할 때 스킬을 못쓰게 하는 방법

     

    이 문제는 애니메이션 관련은 아니지만 맞기도한게 스테이트 머신으로의 진입을 막아야 하는데

    스킬마다의 스테이트는 다른데 마나도 달라서 고민하던 차에

    if(stateMachine.Player.healthSystem.CurrentMana < stateMachine.Player.playerEquipSkill[0].MPCost)
    {
        stateMachine.ChangeState(stateMachine.IdleState);
    }

    진입을 막는것이 아닌 아예 스킬 애니메이션 실행 전에 IdleState로 돌려버리는 방법으로

    해결했다.

     

    스킬 슬롯 스왑문제

     protected virtual void AddInputActionCallbacks()
     {
         if(UIManager.Instance.onUI) return;
         if (stateMachine.Player.isSkillActive) return;
    
         PlayerController input = stateMachine.Player.Input;
         input.PlayerActions.Movement.canceled += OnMovementCanceled;
         input.PlayerActions.Jump.started += OnJumpStarted;
         input.PlayerActions.Attack.performed += OnAttackPerformed;
         input.PlayerActions.Attack.canceled += OnAttackCanceled;
         input.PlayerActions.Dodge.started += OnDodgeStarted;
         input.PlayerActions.FirstSkill.started += OnFirstSkillStarted;
         input.PlayerActions.SecondSkill.started += OnSecondSkillStarted;
         input.PlayerActions.ThirdSkill.started += OnThirdSkillStarted;
         input.PlayerActions.SkillSlotSwap.started += OnSkillSlotSwap;
     }
    
     protected virtual void RemoveInputActionCallbacks()
     {
         PlayerController input = stateMachine.Player.Input;
         input.PlayerActions.Movement.canceled -= OnMovementCanceled;
         input.PlayerActions.Jump.started -= OnJumpStarted;
         input.PlayerActions.Attack.performed -= OnAttackPerformed;
         input.PlayerActions.Attack.canceled -= OnAttackCanceled;
         input.PlayerActions.Dodge.started -= OnDodgeStarted;
         input.PlayerActions.FirstSkill.started -= OnFirstSkillStarted;
         input.PlayerActions.SecondSkill.started -= OnSecondSkillStarted;
         input.PlayerActions.ThirdSkill.started -= OnThirdSkillStarted;
         input.PlayerActions.SkillSlotSwap.started -= OnSkillSlotSwap;
     }

    현재 플레이어의 인풋 관리에서

    스킬 슬롯 스왑버튼을 RemoveInputActionCallbacks()에서 빼주지않으면

    애니메이션이 제대로 실행이 안되고 빼면 로직이 실행이 안됐는데

    bool값의 잘못된 위치로 인해 생긴 문제였다.

     

    원래는 bool값 변수가 PlayerBaseState에 있었는데

    보다시피 스테이트가 아주 많은데

    이 모든 스테이트가 PlayerBaseState를 상속받기 때문에

    모든 스테이트에서 bool값이 무궁무진하게 변하면서 생긴 문제였는데

    왜 상속받았기 때문에 상속받은 State들에도 bool값이 존재할거라는 생각을 못했는지 ....

     

    일단 그래서 bool값의 위치를 Player.cs로 옮겨준 뒤

    protected virtual void OnSkillSlotSwap(InputAction.CallbackContext context)
    {
        if (stateMachine.Player.firstSkillSlot == true)
        {
            stateMachine.Player.firstSkillSlot = false;
            UIManager.Instance.ui.skillUI.SkillSlotMover();
            Debug.Log("Switched to Second Skill Slot, firstSkillSlot: " + stateMachine.Player.firstSkillSlot);
        }
        else if (!stateMachine.Player.firstSkillSlot)
        {
            stateMachine.Player.firstSkillSlot = true;
            UIManager.Instance.ui.skillUI.SkillSlotMover();
            Debug.Log("Switched to First Skill Slot, firstSkillSlot: " + stateMachine.Player.firstSkillSlot);
        }
    }

    코드를 살짝 리펙토링해서 문제를 해결했다.

     

    스킬 사용중에 스왑 + 스킬을 빠르게 누르다보면 어쩌다가 캐릭터가 굳어버리는 문제

     

    이 문제는 애니메이터 확인을 했을 때 SkillState에서 빠져나오지 못하고 갇혀있었는데

    이부분은 튜터님과 한시간을 살펴봤다.. 덕분에 야근하셨다..(죄송합니다)

     

    계속해서 디버깅을 하던 결과 

     

     public override void Update()
     {
         if (stateMachine.Player.firstSkillSlot == true)
         {
             if (stateMachine.Player.IsAnimationFinished(stateMachine.Player.playerEquipSkill[0].AnimationName))
             {
                 stateMachine.ChangeState(stateMachine.IdleState);
             }
         }
         else
         {
             if (stateMachine.Player.IsAnimationFinished(stateMachine.Player.playerEquipSkill[3].AnimationName))
             {
                 stateMachine.ChangeState(stateMachine.IdleState);
             }
         }
         
     }

    해당 Update문에서 스킬 슬롯 스왑 유무에 따라서 IsAnimationFinished를 실행시켜 현재 애니메이션이 끝났는지 감지해준 후 끝났다면 IdleState로 돌아가는 코드가 돌아가고 있었는데

     

    현재 사용하는 스킬과 다른 스킬이 검사가 되는 경우가 계속 찍혔다

     

    public bool IsAnimationFinished(string animationName)
    {
        AnimatorStateInfo currentState = Animator.GetCurrentAnimatorStateInfo(0);
        return currentState.IsName(animationName) && currentState.normalizedTime >= 1f;
        //
    }

    이게 원래 코드였는데

    굳이 애니메이션의 이름을 확인할 이유가 없다고 판단하여

     

    public bool IsAnimationFinished(string animationName)
    {
        AnimatorStateInfo currentState = Animator.GetCurrentAnimatorStateInfo(0);
        return  currentState.normalizedTime >= 1f;
        //currentState.IsName(animationName) &&
    }

    이 부분을 빼 주었다. 그 후

    SkillState안에 New State를 만들어서 Entry에서 스킬로 바로가지않게 했고, New State에서 @Skill파라미터가 False일 시에 IdleState로 돌아가는 트렌지션을 만들었다.

     

    근데 그랬더니 스킬이 끝날때 한 번씩 걸리는 느낌이 있어서.. New State 속도를 100으로 바꿔서 해결했다.

     

    그 후에 그에 맞춰서 코드 리펙토링까지 ..

Designed by Tistory.