EasyCastleUNITY

2023/08/28 필기 (오브젝트 풀링 내용 포함) 본문

개인 필기

2023/08/28 필기 (오브젝트 풀링 내용 포함)

EasyCastleT 2023. 8. 28. 12:46

찾는 오브젝트들의 상태
비활성화된 것은 제외하고 검출
비활성화 제외 검출 결과
비활성화 된 것 까지 검출
비활성화 포함 검출 결과

링큐에 대한 이해도가 부족한거 같다. 다시 공부할 것

https://learn.microsoft.com/ko-kr/dotnet/csharp/linq/write-linq-queries

 

C#에서 LINQ 쿼리 작성하기

C#에서 LINQ 쿼리를 작성하는 방법을 알아봅니다.

learn.microsoft.com

InvokeRepeating

사용코드
결과

Object Pooling(오브젝트 풀링)

게임오브젝트나 프리팹을 동적으로 생성하는 작업은 물리적인 부하가 발생

그러므로, 주기적 또는 반복적으로 생성하는 객체를 씬을 처음 로드할 때, 모두 생성한 다음 사용하는 방식이 유리

사용할 객체를 미리 만들어 놓은 후 필요할 때, 가져다 사용하는 방식 (개발 디자인 패턴 중 하나)

 

1. 미리 만들어서 컬렉션에 담아 놓자

1-1. 그러므로 컬렉션을 정의

2. 풀에 미리 만들어서 비활성화 시킴

3. 풀에서 비활성화 되어 있는 오브젝트를 찾아서 활성화 시킴

4. 풀에 반납

 

오브젝트 풀링의 단점

1. 미리 만들어 놓은 객체가 너무 많다면, 오히려 성능 저하를 일으킬 수 있다.

2. 게임을 시작할 때, 로딩을 하는 순간에, 이 오브젝트들을 만드는 것인데, 이 객체가 너무 많으면 

    로딩 시간이 길어지며, 유저에 이탈로 이어질 수 있다. (즉, 동기로 하는 것은 문제가 될 가능성이 있다)

 

오브젝트 풀링 테스트 

TestBulletPoolManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestBulletPoolManager : MonoBehaviour
{
    //총알을 미리 생성해 저장할 리스트 
    [SerializeField] private List<GameObject> bulletPool = new List<GameObject>();
    //오브젝트 풀에 생성할 총알의 최대 개수
    [SerializeField] private int maxBullets = 15;

    //싱글톤 인스턴스 선언
    public static TestBulletPoolManager instance = null;

    [SerializeField] private GameObject bulletPrefab;

    private void Awake()
    {
        if(instance == null)
        {
            instance = this;
        }
        else if (instance != null)
        {
            Destroy(this.gameObject);
        }
        DontDestroyOnLoad(this.gameObject);
    }
    // Start is called before the first frame update
    void Start()
    {
        this.CreateBulletPool();
    }
    

    private void CreateBulletPool()
    {
        for(int i=0; i<this.maxBullets; i++)
        {
            GameObject bullet = Instantiate<GameObject>(this.bulletPrefab);
            bullet.SetActive(false);
            bullet.transform.SetParent(this.transform);
            this.bulletPool.Add(bullet);
        }
    }

    public GameObject GetBulletInPool()
    {
        foreach (GameObject bullet in this.bulletPool)
        {
            if(bullet.activeSelf == false)
            {
                return bullet;
            }
        }
        return null;
    }
    //반환
    public void ReleaseBullet(GameObject bulletGo)
    {
        bulletGo.SetActive(false);
        bulletGo.transform.SetParent(this.transform);
    }
}

TestObjectPoolingMain

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestObjectPoolingMain : MonoBehaviour
{
    [SerializeField] private Button btn;

    // Start is called before the first frame update
    void Start()
    {
        this.btn.onClick.AddListener(() => {
            GameObject bullet = TestBulletPoolManager.instance.GetBulletInPool();
            bullet.transform.SetParent(null); //밖으로 빼기 
            bullet.transform.localPosition = Vector3.zero;
            bullet.SetActive(true);
        });
    }
    
}

TestBullet1

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestBullet1 : MonoBehaviour
{
    [SerializeField] private float moveSpeed = 1.0f;

    // Update is called once per frame
    void Update()
    {
        this.transform.Translate(Vector3.forward * this.moveSpeed * Time.deltaTime);    
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.collider.CompareTag("Wall"))
        {
            //Destroy(this.gameObject);
            TestBulletPoolManager.instance.ReleaseBullet(this.gameObject);
            Debug.Log("벽과 충돌");
        }
    }
}

실행영상

'개인 필기' 카테고리의 다른 글

2023/08/30 필기 (Light 관련 및 씬 비동기 전환)  (0) 2023.08.30
2023/08/29 필기  (0) 2023.08.29
2023/08/22 필기  (0) 2023.08.22
2023/08/21 필기  (0) 2023.08.21
ref 키워드 and Vector3.SmoothDamp  (0) 2023.08.18