[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개의 댓글

관련 채용 정보