프로그래밍/디자인패턴
유니티(C#)로 사용해 보는 디자인 패턴_ProtoType Pattern_프로토타입
리뷰하는 (게임)프로그래머_리프TV
2020. 5. 30. 11:07
프로토 타입
이번 예제에서는 몬스터의 리스폰을 프로토 타입으로 구현해 보았습니다.
Monster.cs
public class KMS_Monster
{
public int health;
public int speed;
public int positionX;
public int positionY;
public virtual KMS_Monster Clone()
{
return new KMS_Monster();
}
}
가상 함수인 Clon이 존재
Demon.cs
public class KMS_Demon : KMS_Monster
{
public KMS_Demon(int hp, int spd, int x, int y)
{
health = hp;
speed = spd;
positionX = x;
positionY = y;
}
public override KMS_Monster Clone()
{
return new KMS_Demon(health, speed, positionX, positionY);
}
}
Ghost.cs
public class KMS_Ghost : KMS_Monster
{
public KMS_Ghost(int hp, int spd, int x, int y)
{
health = hp;
speed = spd;
positionX = x;
positionY = y;
}
public override KMS_Monster Clone()
{
return new KMS_Ghost(health, speed, positionX, positionY);
}
}
몬스터를 상속 받은 친구들은 Clone 함수를 각자 가지고 있어야 함
기본 생성자로 생성하는게 아니라
이미 가지고 있는 정보에 복사본을 만든다고 생각하면 된다
PrototypePattern.cs
public delegate KMS_Monster SpawnCallBack();
public class KMS_ProtoTypePattern
{
SpawnCallBack spawnCallBack = null;
// 처음 생성자로 생성할 때 어떤 함수가 호출될지를 저장
public KMS_ProtoTypePattern(SpawnCallBack callBack)
{
spawnCallBack = new SpawnCallBack(callBack);
}
public KMS_Monster SpawnMonster()
{
// 생성자때 입력한 함수 호출
return spawnCallBack();
}
}
실제 사용 할 때 ProtoTypePattern에 스폰 지역을 선택
코드를 쓰고나니 뭔가 이상해 지긴했는데
중요한 부분은 하단 코드에서 여기라고 생각
baseGhost.Add(baseGhost[0].Clone());
본인이 본인의 클론을 들고 동일한 값으로 만들어 주는 부분인데
굉장히 제한적인 패턴이라고 생각함
Manager.cs
using System.Collections.Generic;
using UnityEngine;
public class KMS_GameManager : MonoBehaviour
{
// 프로토 타입 패턴으로 스폰 생성
KMS_ProtoTypePattern spawnMonster;
KMS_ProtoTypePattern spawnMonster2;
// 각각의 몬스터를 저장할 컨테이너
List<KMS_Monster> baseGhost = new List<KMS_Monster>();
List<KMS_Monster> baseDemon = new List<KMS_Monster>();
void Start()
{
// 콜백 메시지를 등록
spawnMonster = new KMS_ProtoTypePattern(spawnGhost);
spawnMonster2 = new KMS_ProtoTypePattern(spawnDemon);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
// spawnGhost 함수가 호출 되서 기본 Ghost를 하나 생성
var monster = spawnMonster.SpawnMonster();
// 해당 부분을 저장한다
baseGhost.Add(monster);
Debug.Log("Create Ghost");
}
else if (Input.GetKeyDown(KeyCode.B))
{
if (baseGhost.Count > 0)
{
// 이 부분이 복사 만들어 놓은 첫번째(순서는 중요치 않음)의 클론 생성해서 다시 보관
baseGhost.Add(baseGhost[0].Clone());
Debug.Log("Create clone Ghost");
}
}
else if (Input.GetKeyDown(KeyCode.C))
{
// spawnDemon 함수가 호출되서 Demon하나 생성
baseDemon.Add(spawnMonster2.SpawnMonster());
Debug.Log("Create Demon");
}
else if (Input.GetKeyDown(KeyCode.D))
{
if (baseDemon.Count > 0)
{
// 클론 생성해서 저장
baseDemon.Add(baseDemon[0].Clone());
Debug.Log("Create clone Demon");
}
}
else if (Input.GetKeyDown(KeyCode.E))
{
// 지금까지 만든 데이터 출력
for (int i = 0; i < baseGhost.Count; ++i)
{
Debug.Log(baseGhost[i] + " " + i);
}
}
else if (Input.GetKeyDown(KeyCode.F))
{
// 지금까지 만든 데이터 출력
for (int i = 0; i < baseDemon.Count; ++i)
{
Debug.Log(baseDemon[i] + " " + i);
}
}
}
public KMS_Monster spawnGhost()
{
return new KMS_Ghost(10, 10, 10, 10);
}
public KMS_Monster spawnDemon()
{
return new KMS_Demon(20, 20, 20, 20);
}
}