티스토리 뷰

💻 Unity 디자인 패턴

Strategy 패턴

// Enemy.cs

public interface ImovementStrategy
{
    void Move(Transform transform, float speed);
}

public class StraightMovement: ImovementStrategy
{
    public void Move(Transform transform, float speed)
    {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }
}

public class ZigzagMovement : ImovementStrategy
{
    private float amplitude = 2f;
    private float frequency = 2f;
    private float time = 0;

    public void Move(Transform transform, float speed)
    {
        time += Time.deltaTime;

        transform.Translate(Vector3.forward * speed * Time.deltaTime);

        float xOffset = Mathf.Sin(time * frequency) * amplitude;
        transform.position = new Vector3(xOffset, transform.position.y, transform.position.z);
    }
}

public class CircularMovement : ImovementStrategy
{
    private float radius = 5f;
    private float angularSpeed = 50f;
    private float angle = 0;
    private Vector3 center;
    private bool isInitialize = false;

    public void Move(Transform transform, float speed)
    {
        if (!isInitialize)
        {
            center = transform.position;
            isInitialize = true;
        }

        angle += angularSpeed * Time.deltaTime;

        float x = center.x + Mathf.Cos(angle * Mathf.Deg2Rad) * radius;
        float z = center.z + Mathf.Sin(angle * Mathf.Deg2Rad) * radius;

        transform.position = new Vector3(x, transform.position.y, z);

        // 회전방향 고려
        transform.LookAt(
            new Vector3(center.x + Mathf.Cos((angle + 90) * Mathf.Deg2Rad) * radius, 
            transform.position.y,
            center.x + Mathf.Sin((angle + 90) * Mathf.Deg2Rad) * radius));
    }
}

public class Enemy : MonoBehaviour
{
    [SerializeField]
    private float moveSpeed = 3f;

    private ImovementStrategy movementStrategy;

    void Start()
    {
        movementStrategy = new StraightMovement();
    }

    void Update()
    {
        if (movementStrategy != null)
        {
            movementStrategy.Move(transform, moveSpeed);
        }
    }

    public void SetMovementStrategy(ImovementStrategy strategy)
    {
        movementStrategy = strategy;
    }
}

// EnemyController.cs

public class EnemyController : MonoBehaviour
{
    private Enemy enemy;

    void Start()
    {
        enemy = GetComponent<Enemy>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            enemy.SetMovementStrategy(new StraightMovement());
            Debug.Log("직선 이동");
        }
        else if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            enemy.SetMovementStrategy(new ZigzagMovement());
            Debug.Log("지그재그 이동");
        }
        else if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            enemy.SetMovementStrategy(new CircularMovement());
            Debug.Log("원형 이동");
        }
    }
}

State 패턴

// IState.cs

public interface IState
{
    void Enter(); // 상태 진입시 실행
    void Update(); // 상태 유지 중 실행
    void Exit(); // 상태 종료 시 실행
}

// IdleState.cs

public class IdleState : IState
{
    public void Enter()
    {
        Debug.Log("Idle 상태 시작");
    }

    public void Update()
    {
        //Debug.Log("Idle 상태 유지중");
    }

    public void Exit()
    {
        Debug.Log("Idle 상태 종료");
    }
// StateMachine.cs

public class StateMachine
{
    private IState currentState;

    public void ChangeState(IState newState)
    {
        currentState?.Exit();
        currentState = newState;
        currentState?.Enter();
    }

    public void Update()
    {
        currentState?.Update();
    }
}
// PlayerController.cs

public class PlayerController : MonoBehaviour
{
    private StateMachine stateMachine;

    void Start()
    {
        stateMachine = new StateMachine();
        stateMachine.ChangeState(new IdleState());
    }

    void Update()
    {
        stateMachine.Update();

        if (Input.GetKeyDown(KeyCode.Space))
        {
            stateMachine.ChangeState(new JumpState());
        }
        else if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.LeftArrow))
        {
            stateMachine.ChangeState(new RunState());
        }
        else if (!Input.anyKey)
        {
            stateMachine.ChangeState(new IdleState());
        }
    }
}

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함