이상하게 중간저장후 게시글 올리기가 안되네여
---- ---------------- ---
그런데 유니티 게임오브젝트의 경우
처음 생성될때 SetActive(false);
Pop될때 SetActive( true ) 되면 좋겠잖아요?
또 pool안에 들어있을때
하이어라키 창에서
이렇게 루트에 있는 것보다는 Grounds혹은 poolGround 같은 게임오브젝트에 자식으로 들어가 있는게
보기 편할거 아님?
마찬가지로 Pop할때는 poolGround같은데에서 사용할 위치로 바로 옮겨지면 좋구요
Pop(GameObject parent);
같은 식으로 말입니다.
그래서 GameObject전용 풀을 만들어 봅시다.
알고보니 C#은 상속받아서 메소드를 override 하려면 ( 덮어쓰려면 )
virtual이란걸 써야된데네요?
virtual쓰려면 protected 혹은 public이어야되구요,
생성자는 잘은 모르겠지만 아무것도 안하는 생성자가 필요해서 입력파라미터를 안받는 놈을 하나 만들었습니다.
----
public class GameObjectPool<T> where T : class
{
// Instance count to create.
public short count;
string data;
public delegate T Func ();
protected Func create_fn;
// Instances.
public Stack<T> objects;
// Construct
public GameObjectPool (){
}
public GameObjectPool (short count, Func fn) {
this.count = count;
this.create_fn = fn;
this.objects = new Stack<T> (this.count);
allocate ();
}
protected virtual void allocate () {
for (int i = 0; i < this.count; ++i) {
this.objects.Push (this.create_fn ());
}
}
public virtual T pop () {
if (this.objects.Count <= 0) {
allocate ();
}
return this.objects.Pop ();
}
public virtual void push (T obj) {
this.objects.Push (obj);
}
}
---------------- 그리고 대망의 GameObject용 오브젝트풀 JustGameObjectPool입니다 .이름이 영 못쓰겠군요
public class JustGameObjectPool : GameObjectPool<GameObject> {
public GameObject poolParentObj;
public delegate GameObject HandleObject( GameObject obj );
HandleObject afterCreate;
HandleObject beforePush;
HandleObject afterPop;
public JustGameObjectPool (short count, Func create_fn, GameObject parent) : base( ) {
this.poolParentObj = parent;
this.count = count;
this.create_fn = create_fn;
this.objects = new Stack<GameObject> (this.count);
this.afterCreate = defaultBeforePush;
this.beforePush = defaultBeforePush;
this.afterPop = defaultAfterPop;
allocate ();
}
public JustGameObjectPool (short count, Func fn, GameObject parent, HandleObject afterCreate
, HandleObject beforePush, HandleObject afterPop) : base ( ){
this.poolParentObj = parent;
this.count = count;
this.create_fn = fn;
this.objects = new Stack<GameObject> (this.count);
if( afterCreate != null ){
this.afterCreate = afterCreate;
} else {
this.afterCreate = defaultBeforePush;
}
if( beforePush != null ){
this.beforePush = beforePush;
} else {
this.beforePush = defaultBeforePush;
}
if( afterPop != null ){
this.afterPop = afterPop;
} else {
this.afterPop = defaultAfterPop;
}
allocate ();
}
protected override void allocate () {
GameObject tmp;
for (int i = 0; i < this.count; ++i) {
tmp = this.create_fn ();
tmp = afterCreate(tmp);
this.objects.Push (tmp);
}
}
public override GameObject pop(){
GameObject tmp;
if (this.objects.Count <= 0) {
allocate ();
}
tmp = this.objects.Pop ();
return afterPop(tmp);
}
public GameObject pop(GameObject parent){
GameObject tmp;
tmp = pop();
tmp.transform.parent = parent.transform;
return tmp;
}
public override void push (GameObject obj) {
this.objects.Push (beforePush(obj));
}
private GameObject defaultBeforePush(GameObject objCreated){
//Debug.Log("defaultBeforePush");
if( poolParentObj != null ) {
objCreated.transform.parent = poolParentObj.transform;
}
objCreated.SetActive(false);
return objCreated;
}
private GameObject defaultAfterPop(GameObject objPop){
objPop.SetActive(true);
return objPop;
}
}
//
처음 풀에서 오브젝트가 생성되고 스택에 들어가기전에 해줄작업 -> afterCreate;
풀에서 새로 오브젝트를 꺼내고 해줄 작업 -> afterPop;
풀에 다시 집어넣기 직전에 할일 -> beforePush;
afterCreate, beforePush는 둘다 풀에 집에넣는건데
보통은 pool 용 부모 오브젝트의 자식으로 옮기고 ( 하이어라키에서 보기편하게 )
SetActive ( false ) 로 게임에서 안보이게 하겠죠?
이런 함수를 defaultBeforePush라고 만들어서
afterCreate, beforePush를 람다식으로 생성자에서 입력하지 않는경우 기본값으로 하게 했습니다.
afterPop도
마찬가지로 SetActive(true)를 하는게 기본이니 그런작업하는걸
defaultAfterPop으로 만들어줬습니다.
HandleObject afterCreate;
HandleObject beforePush;
HandleObject afterPop;
이 3개중 일부만 할때는 일부만 고치고 싶다 할때는
public JustGameObjectPool (short count, Func fn, GameObject parent, HandleObject afterCreate
, HandleObject beforePush, HandleObject afterPop) : base ( ){
JustGameObjectPool((short) 30, () = {
return Instantiate( objPrefab );
}, poolParent, (GameObject obj) => {
obj.SetActive(true);
obj.getComponent<SpriteRenderer>().color = new Color32(255,0,0,0);
return obj;
}, null, null );
같은 식으로 일부만 람다식으로 하고 null로 한 것은 기본 default뭐뭐뭐 함수를 쓰게 했습니다.
여튼 그렇습니다.
해봤더니
잘됨
댓글 0