Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

공hannah부

CJ UNIT 7기 게임TF #10(급식실 게임 - 오브젝트 풀링) 본문

프로젝트/CJ UNIT 7기 게임TF

CJ UNIT 7기 게임TF #10(급식실 게임 - 오브젝트 풀링)

Hannah0226 2022. 11. 29. 04:12
오늘의 내용

- 학생을 계속 생성하고 파괴하는 과정은 모바일 환경에서 치명적이다 -> 렉 유발

- 오브젝트 풀링을 사용해 이를 완화시켜보자

- 오브젝트 풀링이란? 미리 객체를 생성하고 필요할 때마다 가져다 쓰는 것!

 

Object Pool

인스펙터 창에서 받아올 값

- 오브젝트 풀링 할 오브젝트

- 미리 만들어놓을 오브젝트 갯수

- 부모가 될 곳

[System.Serializable]
public class ObjectInfo
{
    public GameObject goPrefab;
    public int count;
    public Transform tfPoolParent;
}

 

오브젝트 풀링 해야할 오브젝트

- 계속 생성되는 식판 든 학생 / 안든학생 (기본학생)

- 클릭 / 드래그 했을 때 바뀌는 행복한 학생 / 슬픈 학생 (감정 학생)

- 총 6개이므로 6개의 큐를 만들어준다

public Queue<GameObject> StudentOQueue = new Queue<GameObject>();
public Queue<GameObject> StudentXQueue = new Queue<GameObject>();
public Queue<GameObject> StudentOHappyQueue = new Queue<GameObject>();
public Queue<GameObject> StudentOSadQueue = new Queue<GameObject>();
public Queue<GameObject> StudentXHappyQueue = new Queue<GameObject>();
public Queue<GameObject> StudentXSadQueue = new Queue<GameObject>();

 

큐를 return시키는 함수

- 인스펙터 창에서 지정해 놓은 갯수만큼 학생 instantiate시키기

- 생성한 오브젝트 비활성화

- 부모 설정

   → **주의** 부모 설정할 때 뒤에 false 값을 꼭! 붙여줘야한다. 붙여주지 않으면 생성된 학생 크기 엄청커짐.. 

   → SetParent(p_objectInfo.tfPoolParent, false);

Queue<GameObject> InsertQueue(ObjectInfo p_objectInfo)
{
	Queue<GameObject> t_queue = new Queue<GameObject>();
	for(int i=0; i<p_objectInfo.count; i++)
	{
		GameObject t_clone = Instantiate(p_objectInfo.goPrefab, transform.localPosition, Quaternion.identity);
		t_clone.SetActive(false);
		if(p_objectInfo.tfPoolParent != null)
			t_clone.transform.SetParent(p_objectInfo.tfPoolParent,false);
		else
			t_clone.transform.SetParent(this.transform,false);
		t_queue.Enqueue(t_clone);
	}
	return t_queue;
}

 

함수 불러오기

- 각각 배열에 넣어 관리한다

StudentOQueue = InsertQueue(objectInfo[0]);
StudentXQueue = InsertQueue(objectInfo[1]);
StudentOHappyQueue = InsertQueue(objectInfo[2]);
StudentOSadQueue = InsertQueue(objectInfo[3]);
StudentXHappyQueue = InsertQueue(objectInfo[4]);
StudentXSadQueue = InsertQueue(objectInfo[5]);

 

NoteManager

기본 학생 생성

- Dequeue로 큐에 담긴 객체 가져오기

- 가져온 학생 오브젝트에 학생이 이동을 시작할 위치 설정

   → **주의** 위치를 설정 할 때 transform.position이 아니라 transform.localPosition을 써야한다. position을 쓰면 완전 이상한 곳에 생성됨...저도 알고싶지 않았어요...

- 가져온 학생 오브젝트 활성화 시키기

//NoteManager 랜덤수가 1일 때 식판 든 학생 생성
GameObject StudentO = ObjectPool.instance.StudentOQueue.Dequeue();
StudentO.transform.localPosition = new Vector3(-1400, 0, 0);
StudentO.SetActive(true);

 

감정 학생 생성

- Dequeue로 큐에 담긴 객체 가져오기

- 기본 학생이 클릭 / 드래그 된 위치로 감정 학생 위치 지정

- 가져온 학생 오브젝트 활성화 시키기

//NoteManager 식판 든 학생 행복 학생으로 바꾸는 함수 안
GameObject StudentOHappy = ObjectPool.instance.StudentOHappyQueue.Dequeue();
StudentOHappy.transform.localPosition = new Vector3(x, 0, 0);
StudentOHappy.SetActive(true);

 

감정 학생 제거

- 여기서 중요한 점은 감정 학생을 생성한 후 0.5초뒤 제거해야한다는 점이다

- delay주는 방법을 찾아보다 Coroutine을 알게되어 이를 사용하기로 했다

- DelayTime 함수 만들어주기

   → 함수 안에 0.5초 기다리기, 학생 오브젝트 비활성화를 넣어준다

IEnumerator DelayTime(GameObject studentQueue)
{
	yield return new WaitForSeconds(0.5f);
	studentQueue.SetActive(false);
}

- DelayTime 함수 가져오고 Enqueue로 꺼내온 학생 오브젝트 다시 큐에 넣어주기

StartCoroutine(DelayTime(StudentOHappy));
ObjectPool.instance.StudentOHappyQueue.Enqueue(StudentOHappy);

 

NoteO / NoteX

기본 학생 제

- Enqueue로 꺼내온 학생 오브젝트 다시 큐에 넣어주기

- 학생 오브젝트 비활성화 시키기

//NoteO스크립트 OnPointerClick일 때
ObjectPool.instance.StudentOQueue.Enqueue(gameObject);
gameObject.SetActive(false);

 

실행 영상

- 큐가 정상적으로 잘 만들어지고 오브젝트 활성화와 비활성화도 잘 작동된다!