Design Pattern] Strategy Pattern을 사용한 Player 이동 구현
- 김영호
- 2022년 11월 14일
- 2분 분량
최종 수정일: 2023년 4월 25일
Strategy Pattern(전략 패턴)은 한 행동에 대해 여러가지 전략을 필요에 따라 사용 할 수 있도록 구현하는 디자인 패턴이다.
이를 사용해 Player 이동방법을 Translate와 AddForce 두가지 방법으로 따로 구현한 뒤, Player1에는 Translate를, Player2에는 AddForce를 넣고 동작 시켰다.
각 전략은 ScriptableObject를 상속받아 구현했다.
Player
public class Player : MonoBehaviour
{
//속도
public float speed_Mov;
//Action : 전략
public Action move;
void Start()
{
//Move 전략에 사용할 캐릭터 지정
if(move != null)
move.SetCha(this);
}
void Update()
{
//전략 동작
move._Action();
}
}
Interface IMove : Move 전략을 포함할때 사용할 인터페이스
public Interface IMove
{
public void Move();
}
Action : 행동 전반의 부모 클래스
// Prefab화 시켜서 Player의 script에 드래그 앤 드롭을 통해 간편한 전략 선택을 하기 위해 ScriptableObject 상속
public class Action : ScriptableObject
{
//해당 전략을 보유한 캐릭터
protected Character cha;
public void SetCha(Character cha)
{
this.cha = cha;
}
//하위 클래스에서 기능을 구현할 동작 함수
virtual public void _Action() {}
}
Action_Move : Action을 상속받은 이동 전반의 클래스들의 부모
//움직임 전략
public class Action_Move : Action, IMove
{
public override void _Action()
{
//Action_Move._Action()을 하면 Move(하위 클래스에서 기능 구현) 동작
Move();
}
//하위 클래스에서 기능 구현
virtual public void Move() {}
}
Action_Move_Translate : Action_Move를 상속받고 Translate를 사용해 구현
//Translate를 이용한 이동 구현
[CreateAssetMenu(fileName = "Action_Move_Translate", menuName = "Scriptable Object/Action/Move/Translate", order = 0]
public class Action_Move_Translate : Action_Move
{
//실제 기능(Move) 구현
override public void Move()
{
//Exception Handling (
if(cha == null) return;
//Input
float v = Input.GetAxis("Vertical"); //forward, back
float h = Input.GetAxis("horizontal"); //right, left
//Move Direction
Vector3 mov = new Vector3(h, 0, v) * cha.stat.GetSpeedMov() * Time.deltaTime;
//Translate
cha.transform.Translate(mov);
Debug.Log(cha.name + "] Translate is better!!");
}
}
Action_Move_AddForce : Action_Move를 상속받고 AddForce를 사용해 구현
//AddForce를 이용한 이동 구현
[CreateAssetMenu(fileName = "Action_Move_AddForce", menuName = "Scriptable Object/Action/Move/AddForce", order = 0]
public class Action_Move_AddForce : Action_Move
{
//실제 기능(Move) 구현
override public void Move()
{
//Exception Handling
if(cha == null) return;
//Input
float v = Input.GetAxis("Vertical"); //forward, back
float h = Input.GetAxis("horizontal"); //right, left
//Move Direction
Vector3 mov = new Vector3(h, 0, v) * cha.stat.GetSpeedMov();
//AddForce
cha.GetComponent<Rigidbody>().AddForce(mov);
Debug.Log(cha.name + "] AddForce is better!!");
}
}
장점
새로운 이동방법으로 변경할 때 새로운 Action을 만들어 설정 해주는 것만으로 교체가가능하며, Character, Player의 코드를 고칠 필요가 없어진다.
이동을 하는데에 문제가 발생하면 해당 이동 클래스만 수정하면 되기 때문에 유지관리에 용의하다.