728x90
https://unity.com/kr/how-to/develop-modular-flexible-codebase-state-programming-pattern
간단한 상태 패턴
using UnityEngine;
public class CubeController : MonoBehaviour
{
public enum State
{
Idle,
Walk,
}
State _state;
Vector3 _target;
void Start()
{
_state = State.Idle;
}
void Update()
{
switch (_state)
{
case State.Idle:
Idle();
break;
case State.Walk:
Walk();
break;
}
}
private void GetInput()
{
if (Input.GetKeyDown(KeyCode.A))
_target = transform.position + Vector3.left;
else if (Input.GetKeyDown(KeyCode.S))
_target = transform.position + Vector3.down;
else if (Input.GetKeyDown(KeyCode.D))
_target = transform.position + Vector3.right;
else if (Input.GetKeyDown(KeyCode.W))
_target = transform.position + Vector3.up;
if (_target != Vector3.zero)
_state = State.Walk;
}
private void Idle()
{
_target = Vector3.zero;
GetInput();
}
private void Walk()
{
Vector3 distance = _target - transform.position;
if (distance.magnitude < 0.01)
{
_state = State.Idle;
}
else
{
float moveDist = Mathf.Clamp(10 * Time.deltaTime, 0, distance.magnitude);
transform.position += distance.normalized * moveDist;
}
}
}
인터페이스를 사용하여 패턴 구현하기
using UnityEngine;
public interface IState
{
public void Enter()
{
// 상태에 처음 진입할 때 실행되는 코드
}
public void Update()
{
// 프레임당 로직. 새로운 상태로 전환하는 조건 포함
}
public void Exit()
{
// 상태에서 벗어날 때 실행되는 코드
}
}
using UnityEngine;
using static UnityEditor.Experimental.GraphView.GraphView;
public class IdleState : IState
{
CubeController _player;
public IdleState(CubeController player)
{
_player = player;
}
public void Enter()
{
// 상태에 처음 진입할 때 실행되는 코드
}
public void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
_player.Target += Vector3.left;
_player.playerStateMachine.TransitionTo(_player.playerStateMachine.walkState);
}
else if (Input.GetKeyDown(KeyCode.S))
{
_player.Target += Vector3.down;
_player.playerStateMachine.TransitionTo(_player.playerStateMachine.walkState);
}
else if (Input.GetKeyDown(KeyCode.D))
{
_player.Target += Vector3.right;
_player.playerStateMachine.TransitionTo(_player.playerStateMachine.walkState);
}
else if (Input.GetKeyDown(KeyCode.W))
{
_player.Target += Vector3.up;
_player.playerStateMachine.TransitionTo(_player.playerStateMachine.walkState);
}
}
public void Exit()
{
// 상태에서 벗어날 때 실행되는 코드
}
}
using System;
using Unity.Mathematics;
using UnityEngine;
using static UnityEngine.GraphicsBuffer;
public class WalkState : IState
{
CubeController _player;
Vector3 _target;
public WalkState(CubeController player)
{
_player = player;
}
public void Enter()
{
// 상태에 처음 진입할 때 실행되는 코드
if (_player != null)
{
_target = _player.Target;
}
}
public void Update()
{
Vector3 distance = _target - _player.transform.position ;
if (distance.magnitude < 0.01)
{
_player.playerStateMachine.TransitionTo(_player.playerStateMachine.idleState);
}
else
{
float moveDist = Mathf.Clamp(10 * Time.deltaTime, 0, distance.magnitude);
_player.transform.position += distance.normalized * moveDist;
}
}
public void Exit()
{
// 상태에서 벗어날 때 실행되는 코드
_target = Vector3.zero;
}
}
using System;
using Unity.IO.LowLevel.Unsafe;
using UnityEngine;
[Serializable]
public class StateMachine
{
public IState CurrentState { get; private set; }
public WalkState walkState;
public IdleState idleState;
public StateMachine(CubeController player)
{
this.walkState = new WalkState(player);
this.idleState = new IdleState(player);
}
public void Initialize(IState startingState)
{
CurrentState = startingState;
startingState.Enter();
}
public void TransitionTo(IState nextState)
{
CurrentState.Exit();
CurrentState = nextState;
nextState.Enter();
}
public void Update()
{
if (CurrentState != null)
{
CurrentState.Update();
}
}
}
using UnityEngine;
using UnityEngine.InputSystem;
public class CubeController : MonoBehaviour
{
public StateMachine playerStateMachine;
public Vector3 Target { get; set; } =Vector3.zero;
void Start()
{
playerStateMachine = new StateMachine(this);
playerStateMachine.Initialize(playerStateMachine.idleState);
}
void Update()
{
playerStateMachine.Update();
}
}
728x90
'Unity' 카테고리의 다른 글
[Unity] ECS 예제 목록 (0) | 2024.08.30 |
---|---|
[Unity] DOTS 시스템과 Unity JobSystem, Burst, ECS 개념 (1) | 2024.08.30 |
[Unity] Addresable 어드레서블를 이용한 웹서버 원격 로드방법 (0) | 2024.03.26 |
[Unity] Unity 파이프라인 이란? (0) | 2024.03.12 |
[Unity] LINE CHART 그래프 만들기 (2) 그래프에 라벨 숫자 넣기 (1) | 2023.11.20 |