[240220]TIL

응징·2024년 2월 20일
0

TIL

목록 보기
30/36
post-thumbnail

유한 상태 머신 (FSM)

  • FSM은 유한 상태 기계를 나타내는 디자인 패턴
  • 상태와 상태 간의 전환을 기반으로 동작하는 동작 기반 시스템
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerStateMachine : StateMachine
{
    public Player Player { get; }

    // States
    public PlayerIdleState IdleState { get; }
    public PlayerWalkState WalkState { get; }
    public PlayerRunState RunState { get; }
    public PlayerJumpState JumpState { get; }
    public PlayerFallState FallState { get; }
    public PlayerComboAttackState ComboAttackState { get; }

    // 
    public Vector2 MovementInput { get; set; }
    public float MovementSpeed { get; private set; }
    public float RotationDamping { get; private set; }
    public float MovementSpeedModifier { get; set; } = 1f;

    //
    public bool IsAttacking { get; set; }
    public int ComboIndex { get; set; }

    public float JumpForce { get; set; }

    public Transform MainCameraTransform { get; set; }

    public PlayerStateMachine(Player player)
    {
        this.Player = player;

        IdleState = new PlayerIdleState(this);
        WalkState = new PlayerWalkState(this);
        RunState = new PlayerRunState(this);

        JumpState = new PlayerJumpState(this);
        FallState = new PlayerFallState(this);

        ComboAttackState = new PlayerComboAttackState(this);

        MainCameraTransform = Camera.main.transform;

        MovementSpeed = player.Data.GroundedData.BaseSpeed;
        RotationDamping = player.Data.GroundedData.BaseRotationDamping;
    }
}

가장 핵심이 되는 상태머신 스크립트에서 필요한 상태의 스크립트를 나열한다.

IdleState : 가장 기본이 되는 상태
WalkState : 걷고 있는 상태
RunState : 달리고 있는 상태
JumpState : 점프하고 있는 상태
FallState : 점프이후 혹은 낭떠러지에서 떨어지고 있는 상태
ComboAttackState : 공격 상태 (몇번째 콤보 상태인지까지 파악)

상태 머신 단계

public interface IState
{
    public void Enter();
    public void Exit();
    public void HandleInput();
    public void Update();
    public void PhysicsUpdate();

}

Enter : 상태에 진입할 때 호출할 것
Exit : 상태에서 나올 때 호출
HandleInput : 입력을 처리

PlayerBaseState 상속

PlayerGroundedState

허공이 아닌 땅 위에 있을때 진행될 상태를 여기서 전환.

상태 전환

점프를 누르자마자 전환

protected override void OnJumpStarted(InputAction.CallbackContext context)
{
stateMachine.ChangeState(stateMachine.JumpState);
}

이동키를 누르고 있다면 전환

protected virtual void OnMove()
{
stateMachine.ChangeState(stateMachine.WalkState);
}

공격키를 누르고 있다면 전환

protected virtual void OnAttack()
{
stateMachine.ChangeState(stateMachine.ComboAttackState);
}

Idle 전환

 protected override void OnMovementCanceled(InputAction.CallbackContext context)
    {
        if (stateMachine.MovementInput == Vector2.zero) //이동이 없을때
        {
            return;
        }

        stateMachine.ChangeState(stateMachine.IdleState); 

        base.OnMovementCanceled(context);
    }

OnMovementCanceled는 애초에 Input이 끝났을때 처리하는 메소드이지만 Move Input 값은 안받고 있더라고 점프하거나 낭떠러지에서 떨어질때는 Idle로 전환하면 안되기 때문에 위와 같은 조건문 처리를 함

Fall 전환

 public override void PhysicsUpdate()
    {
        base.PhysicsUpdate();

        //평소의 중력보다 값이 많을때 떨어지고 있다고 판단
        if (!stateMachine.Player.Controller.isGrounded
            && stateMachine.Player.Controller.velocity.y < Physics.gravity.y * Time.fixedDeltaTime)
        {
            stateMachine.ChangeState(stateMachine.FallState);
            return;
        }
    }

PlayerAirState

Fall에서 나가기 (Idle 전환)

public override void Update()
    {
        base.Update();

        //땅을 밟으면 멈추게
        if (stateMachine.Player.Controller.isGrounded)
        {
            stateMachine.ChangeState(stateMachine.IdleState);  //땅을 밟으면 Idle 상태로 전환
            return;
        }
    }

CharacterController

  • 이동 제어: 캐릭터를 전후좌우로 이동시키는 기능을 제공. 이동 방향과 속도를 조절하여 캐릭터를 이동.

  • 중력 적용: 캐릭터에 중력을 적용하여 점프 후에 떨어지는 동작을 구현할 수 있다

  • 충돌 처리: 캐릭터와 다른 물체 간의 충돌을 감지하고 처리. 이를 통해 벽이나 바닥과의 충돌을 감지하고, 이동을 방해하는 등의 작업을 수행.

  • 지형 탐색: 캐릭터가 이동 가능한 지형과 접촉하는지를 확인. 이를 통해 캐릭터가 지형을 따라 이동하거나 경사를 오르내리는 등의 작업을 수행

  • 애니메이션 제어: 일반적으로 CharacterController는 캐릭터의 실제 이동을 담당, 애니메이션은 이동 방향과 관련된 모션을 재생하는 데 사용

CharacterController > Collider
CharacterController < RigidBady

Cinemachine 패키지

카메라 시스템을 강화하기 위한 패키지 중 하나이다.

이해 안가는거

컴포넌트에 들어간 스크립트는 Player 뿐

PlayerStateMachine에서 public Player Player { get; }데이터를 초기화 해서 가능하게 된것 같긴한데 아무리 생각해도 여러가지 스크립트의 Update 문이나 Exit문 등, 오브젝트에 달려 있지도 않은데 돌아가는 이유를 잘 모르겠으며, 내가 지금 뭘 몰라서 모르고 있는지도 모르겠으니 튜터님한테 꼭 이 점 물어보기

CharacterController.isGrounded

//땅을 밟으면 멈추게
        if (stateMachine.Player.Controller.isGrounded)
        {
            stateMachine.ChangeState(stateMachine.IdleState);  //땅을 밟으면 Idle 상태로 전환
            return;
        }

CharacterController는 sGrounded 라는 bool 값이 있는데 얘가 충돌한 것이 그라운드인지 아니면 단순한 오브젝트인지 어떻게 판별하는걸까? 그냥 아래쪽에 충돌하는 것을 Ground 라고 판별하는건가?

profile
Unity 개발 위주로 정리합니다

0개의 댓글