Unity 특강

스탠다드반 특강 3주차 - 10/30

오늘도즐겨 2024. 11. 11. 16:01

💻디자인패턴특강 2회

지난 강의 복습

 

📌 싱글톤 패턴

유일하다 - 추가적으로 생기는 것을 제한하는 방법이 필요

전역적으로 접근이 가능하다 - public static을 통해 구현


📌 오브젝트 풀 패턴

할당/해제에 걸리는 성능 낭비와 메모리 낭비를 줄이고 싶어서

생성/파괴가 반복되는 오브젝트를 재활용한다.

필요할 만큼을 미리 생성 + 비활성화해 둠

Queue로 보통 생성했는데, List = 모자라면 추가로 생성하는 것을 

미리 생성해 둔 양 이상을 요구한다면 추가로 생성

파괴 대신 오브젝트를 비활성화한다.


📌 전략패턴

원본클래스를 건드리지 않고 다양하게 추가되는 방식을 대응하고 싶어서

마치 골프에서 상황에 맞게 채를 바꾸는 것처럼,

상황에 맞게 로직군을 바꿔주는 방식이 전략패턴이다.

 

객체지향의 다형성 - 하나의 객체가 여러 가지 타입을 가질 수 있는 것

부모 클래스에서 virtual로 생성 후, 자식클래스에서 상속을 통해 override로 재정의 하여 사용하는 것

 

전략인터페이스를 정의하고, 세부 동작을 구현

 

If If If로 구성되어 있던 부분들을 AttackStrategy를 상속받는 구체 클래스로 변경

새로운 무기가 추가되더라도 if가 늘어나지 않음.

public interface IAttackStrategy
{
    void Attack();
}
public class SwordAttack : IAttackStrategy
{
    public void Attack()
    {
        Debug.Log("Sword Attack");
    }
}
public class BowAttack : IAttackStrategy
{
    public void Attack()
    {
        Debug.Log("BowAttack");
    }
}
public class MagicAttack : IAttackStrategy
{
    public void Attack()
    {
        Debug.Log("Magic Attack");
    }
}
public class Character
{
    private IAttackStrategy attackStrategy;
    public void SetAttackStrategy(IAttackStrategy strategy)
    {
        attackStrategy = strategy;
    }
    public void Attck()
    {
        attackStrategy?.Attack();
    }
}

📌 상태패턴(FSM)

여러 상태들이 있고 실행되는 로직이 달라짐을 체계적으로 관리하고 싶음

idle, angry, dead와 같은 여러 상태를 두고 그 상태에 맞는 행동을 하게 한다라고 생각하면 됩니다.

상태들을 전환하는 역할을 하는 StateMachine/실행되어야 할 로직을 정의하는 State들로 구성

 

State에서 관리함

public interface IDoorState
{
    void Open(Door door);
    void Open(Door door);
}
public class OpenState : IDoorState
{
    public void Open(Door door)
    {
        Debug.Log("Door is aready open.")
    }
    public void Close(Door door)
    {
        Debug.Log("Door closed.")
        door.SetState(new ClosedState());
    }
}
public class ClosedState : IDoorState
{
    public void Open(Door door)
    {
        Debug.Log("Door is opened.")
        door.SetState(new OpenState());
    }
    public void Close(Door door)
    {
        Debug.Log("Door is aready closed.")
    }
}
public class Door
{
    private IDoorState state;
    public Door()
    {
        state = new ClosedState();//초기상태설정
    }
    public void SetState(IDoorState newState)
    {
        state = newState;
    }
    public void Open()
    {
        state.Open(this);
    }
    public void Close()
    {
        state.Close(this);
    }
}

 


📌 이벤트 기반 프로그래밍 / Pub - Sub패턴

 

발행자 1 - 구독자 1 = 함수호출

발행자 1 - 구독자 N =  옵저버패턴

발행자 N - 구독자 N = 이벤트 버스 패턴

 

발행자와 구독자 사이에서 의존성을 만들지 않고 싶어서 사용함

퀘스트 시스템을 구현할 때 퀘스트의 종류가 많지 않아 간단하고 이해가 잘 되는 이벤트 시스템을 만들고 싶을 수 있음

이벤트의 발행자와 구독자 간의 의존성을 만들지 않은 상태에서

EventBus에는 액션을 등록하고, Publiser가 이벤트를 Invoke 하도록 합니다.

이때  Publisher가 한 개의 클래스라는 가정이 없다.

모두가 공용으로 쓰는 EventManager가 탄생한 것이다.


📌 명령패턴

구현하고자 하는 목적에 따라 달라질 수 있음.

 

로깅 (1:04)

플레이어들이 어떤 행동을 했었는지를 꾸준히 로깅하고,

이를 통해 게임 플레이에서 부적이 있었는지 확인할 수 있음.

 

되돌리기 (1:14)

PlayerInput 클래스에서는 입력을 받고,

PlayerMovement는 이동처리를 진행할 것임.

ICommand는 실행과 역실행의 구현을 강제함.

상속받은 MoveCommand는 실행과 역실행을 할 수 있음.

 

행동을 객체로 만들어 재사용, 기록, 취소, 병렬 처리를 쉽게 하기 위해

행동을 객체화해서 복잡한 작업을 순차적으로 처리하거나 되돌릴 수 있음