이상하게 중간저장후 게시글 올리기가 안되네여

---- ---------------- ---

그런데 유니티 게임오브젝트의 경우

처음 생성될때 SetActive(false);

Pop될때 SetActive( true ) 되면 좋겠잖아요?



또 pool안에 들어있을때

하이어라키 창에서



viewimage.php?id=2abcdd23dad63db0&no=29bcc427b38a77a16fb3dab004c86b6fefd5355bb210043215884566e8f3c822879d8c35533916f16d13caa12cfcfd1803398b15209005e7aee0





이렇게 루트에 있는 것보다는 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뭐뭐뭐 함수를 쓰게 했습니다.



여튼 그렇습니다.



해봤더니


viewimage.php?id=2abcdd23dad63db0&no=29bcc427b38a77a16fb3dab004c86b6fefd5355bb210043215884566e8f3c822879d8c35533916f16d13caa12cfca9184ed0b76e0e0201d42ba6


viewimage.php?id=2abcdd23dad63db0&no=29bcc427b38a77a16fb3dab004c86b6fefd5355bb210043215884566e8f3c822879d8c35533916f16d13caa12cfcf8497a619654a6d1d4e7a5a6


잘됨