본문 바로가기
개발/Unity 내일배움캠프 TIL

Unity3D FSM으로 플레이어 캐릭터 조작 구현하기 (3)

by 석시 2023. 10. 10.



저번 게시글까지 FSM으로 플레이어 캐릭터 조작을 구현하기 위한 기본 State 클래스를 구성하는 부분까지는 완성을 했었다.

Unity3D FSM으로 플레이어 캐릭터 조작 구현하기 (2)
State Machine 만들기땅에 붙어 있을 때 상태 구현하기PlayerSO 만들기Player 오브젝트 설정Animator 설정 저번 글에서는 Input Action을 스크립트로 접근하는 법과 Player Animation을 FSM으로 구현하기 위한 기본 세팅을 마쳤었다. Unity3D FSM으로 플레이어 캐릭터 조작 구현하기 (1)프로젝트 세팅Input System으로 기본적인 이동 구현하기Input Actions와 오브젝트 연결하기플레이어에 애니메이션을 받도록 하는 스크립트 작성FSM 구성하기플레이어에 대한 상태 정보 구현하기 플레이어 이동 구현 방식에는 여러 가지가 있지만, 구현해야 하는 이동 상황이 많아지면 주로 사용하는 것이 바로 FSM(Finite State Machine)이다. FSM은 상..
https://seoksii.tistory.com/57

이번엔 그 기본 State를 상속받아 Idle 외의 다른 상태를 구현해보자.


기존 코드 수정

우선 기존의 코드를 약간 수정해야 한다.

  • PlayerBaseState.cs 수정
    using UnityEngine.InputSystem;
    
    protected virtual void AddInputActionsCallbacks()
    {
        PlayerInput input = stateMachine.Player.Input;
        input.PlayerActions.Movement.canceled += OnMovementCanceled;
        input.PlayerActions.Run.started += OnRunStarted;    }
    
    protected virtual void RemoveInputActionsCallbacks()
    {
        PlayerInput input = stateMachine.Player.Input;
        input.PlayerActions.Movement.canceled -= OnMovementCanceled;
        input.PlayerActions.Run.started -= OnRunStarted;
    
    }
    
    protected virtual void OnRunStarted(InputAction.CallbackContext context)
    {
    
    }
    
    protected virtual void OnMovementCanceled(InputAction.CallbackContext context)
    {
    
    }

  • PlayerStateMachine.cs 수정
    // States
    public PlayerIdleState IdleState { get; }
    public PlayerWalkState WalkState { get; }
    public PlayerRunState RunState { get; }
    
    public PlayerStateMachine(Player player)
    {
        this.Player = player;
    
        IdleState = new PlayerIdleState(this);
        WalkState = new PlayerWalkState(this);
        RunState = new PlayerRunState(this);
    
        MainCameraTransform = Camera.main.transform;
    
        MovementSpeed = player.Data.GroundedData.BaseSpeed;
        RotationDamping = player.Data.GroundedData.BaseRotationDamping;
    }

    PlayerWalkStatePlayerRunState는 일단 스크립트를 만들어주자.

  • PlayerGroundedState.cs 수정
    protected override void OnMovementCanceled(InputAction.CallbackContext context)
    {
        if(stateMachine.MovementInput == Vector2.zero)
        {
            return;
        }
    
        stateMachine.ChangeState(stateMachine.IdleState);
    
        base.OnMovementCanceled(context);
    }
    
    protected virtual void OnMove()
    {
        stateMachine.ChangeState(stateMachine.WalkState);
    }

  • PlayerIdleState.cs 수정
    public override void Update()
    {
        base.Update();
    
        if(stateMachine.MovementInput != Vector2.zero)
        {
            OnMove();
            return;
        }
    }


Walk, Run 상태 추가

이제 각각의 상태에 따른 기능을 구현해주자.

  • PlayerWalkState.cs
    using UnityEngine.InputSystem;
    
    public class PlayerWalkState : PlayerGroundedState
    {
        public PlayerWalkState(PlayerStateMachine playerStateMachine) : base(playerStateMachine)
        {
        }
    
        public override void Enter()
        {
            stateMachine.MovementSpeedModifier = groundData.WalkSpeedModifier;
            base.Enter();
            StartAnimation(stateMachine.Player.AnimationData.WalkParameterHash);
        }
    
        public override void Exit()
        {
            base.Exit();
            StopAnimation(stateMachine.Player.AnimationData.WalkParameterHash);
        }
    
        protected override void OnRunStarted(InputAction.CallbackContext context)
        {
            base.OnRunStarted(context);
            stateMachine.ChangeState(stateMachine.RunState);
        }
    }

  • PlayerRunState.cs
    public class PlayerRunState : PlayerGroundedState
    {
        public PlayerRunState(PlayerStateMachine playerStateMachine) : base(playerStateMachine)
        {
        }
    
        public override void Enter()
        {
            stateMachine.MovementSpeedModifier = groundData.RunSpeedModifier;
            base.Enter();
            StartAnimation(stateMachine.Player.AnimationData.RunParameterHash);
        }
    
        public override void Exit()
        {
            base.Exit();
            StopAnimation(stateMachine.Player.AnimationData.RunParameterHash);
        }
    }

각 스테이트 별로 애니메이션, 이동속도 등이 정상적으로 적용되는 것을 알 수 있다.


Uploaded by N2T