TIL
20240125 TIL
[폴른]
2024. 1. 25. 21:58
Today I Learned :
ObjectPool
- 오브젝트 풀링은 GameObject를 반복적으로 생성하고 파괴하는 데 따르는 부하를 줄여줌으로써 성능을 향상시킵니다.
- 오브젝트를 재사용함으로써 불필요한 메모리 할당 및 해제를 피하고, 메모리 사용의 효율성을 높입니다.
- 빈번한 오브젝트 생성과 파괴는 가비지 컬렉션의 부하를 초래할 수 있습니다. 오브젝트 풀링은 오브젝트를 유지하고 재사용함으로써 가비지 컬렉션을 줄입니다.
// 적당히 생략된 코드
public class FruitManager : MonoBehaviour
{
[SerializeField] private GameObject[] fruitPrefabs;
private List<GameObject>[] objectPool;
private const int objectPoolSize = 7; // 과일당 풀 사이즈
private void Awake()
{
InitObjectPool();
}
private void Start()
{
InvokeRepeating(nameof(SpawnFruit), zero, spawnInterval);
}
private void InitObjectPool()
{
objectPool = new List<GameObject>[fruitPrefabs.Length];
// i = enum.FruitsType 과 동일하게
for (int i = zero; i < fruitPrefabs.Length; i++)
{
objectPool[i] = new List<GameObject>();
for (int j = zero; j < objectPoolSize; j++)
{
GameObject fruit = InstantiateFruit(i);
fruit.SetActive(false);
objectPool[i].Add(fruit);
}
}
}
private GameObject InstantiateFruit(int fruitIndex)
{
// 새로운 과일 오브젝트 생성
GameObject fruit = Instantiate(fruitPrefabs[fruitIndex]);
objectPool[fruitIndex].Add(fruit);
return fruit;
}
private void SpawnFruit()
{
// 생성위치
Vector3 spawnPosition = new Vector3(randX, randY, zero);
int randFruitIndex = Random.Range(zero, max);
GameObject fruit = GetPooledObject(randFruitIndex) ?? InstantiateFruit(randFruitIndex);
fruit.transform.position = spawnPosition;
fruit.SetActive(true);
}
private GameObject GetPooledObject(int fruitIndex)
{
if (fruitIndex < zero || fruitIndex >= objectPool.Length)
{
return null;
}
for (int i = zero; i < objectPool[fruitIndex].Count; i++)
{
if (!objectPool[fruitIndex][i].activeInHierarchy)
{
return objectPool[fruitIndex][i];
}
}
return null;
}
}
일정량의 오브젝트를 미리 생성해놓고 재사용하며, 모자란경우 새로 생성.
풀링할 오브젝트가 다양한 경우 매니저를 만들고 다양한 종류를 지원할수 있도록 개발
activeInHierarchy
게임 오브젝트의 활성화 상태를 검사하는 데 사용
activeInHierarchy vs activeSelf: activeInHierarchy는 게임 오브젝트 및 그 상위 부모 계층 구조에 대한 전체적인 활성 여부를 검사합니다. activeSelf는 해당 게임 오브젝트의 직접적인 활성 여부만을 검사합니다.
상수선언
const를 선언하여 자주사용되는 숫자를 별도로 선언하여 재사용한다.
기존에 알고있기론 그냥 숫자로 쓰는것과 비교해서 성능차이가 있다고 알고있었는데, 실제로는 컴파일 타임에서 최적화가 이루어지기 때문에 별차이가 없다고 한다.
다만 const 사용시 코드 가독성과 유지보수에 용이하다고 한다.
Mathf.Clamp(currentPosition.x, minX, maxX)
min, max 범위 내에 있으면 그대로 리턴하고, 범위를 벗어나는 경우 범위에서 가까운 값을 리턴한다.
스크립트로 Sprite 설정
SpriteRenderer fruitSpriteRenderer = fruitsOnStick[fruitStack.Count - 1].GetComponent<SpriteRenderer>();
fruitSpriteRenderer.sprite = Resources.Load<Sprite>($"Fruits/{fruit.type}");