게임프로젝트/쿠키런 모작

R&D 타일맵 랜덤 무한 생성(3) 오브젝트 풀링 수정중

pudding81 2024. 3. 30. 13:36

 
 
 

¤오브젝트 풀링 활용
 

- 유니티 에셋에 있는 풀 패키지를 사용함.
- 오브젝트 풀링을 활용해서 타일맵의 생성과 파괴를 하지않고 재사용함.
- 전체 풀의 객체가 비활성화된 상태로 생성되었다가
 4.5초마다 활성화 시킴. 화면을 벗어나면 비활성화됌.
 
 
==>  타일맵의객체수를 줄이면 에러가 남 :
타일맵의 객체수는 2개로 하니 3번째 호출할 경우 나오지않음.
비활성화된 객체가 풀에 반환이 되어 재사용되지 않는 것 같음.

=>   타일매니저를 풀매니저 컴포넌트로 옮기고
타일컨트롤러에 에셋에 있는 Ipoolobject 인터페이스 연결 - 메서드를 추가하고 타일매니저에 반환 매서드와 연결해줌

 

 
 

using Redcode.Pools;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor.EditorTools;
using UnityEngine;

public class TileManager : MonoBehaviour
{
    [SerializeField]
    private PoolManager poolManager;

    
    // 난수생성기
    private int minNumber = 0; //타일맵 인덱스 최소범위
    private int maxNumber = 3; //타일맵 인덱스 최대범위
    //필요한 임의의 숫자들의 총 개수// 타일맵의 길이
    private int iterations = 99;  
    //이미 생성된 임의의 숫자들의 리스트
    private List<int> results = new List<int>();

    // LCG Parameters
    // seed, a, c, m은 난수 생성 알고리즘에 사용되는 변수들로,
    // 각각 초기값, 곱셈 상수, 덧셈 상수, 모듈로 상수를 나타냅니다. 
    private const long a = 1103515245;
    private const long c = 12345;
    private const long m = 2147483647;
    private long seed = 123456789; // Initial seed

    private int count = 0;




    private void Start()
    {

        GenerateRandomNumbers();

        // PoolManager 인스턴스를 찾습니다.
        PoolManager poolManager = FindObjectOfType<PoolManager>();
        // 코루틴 시작
        StartCoroutine(CreateTileMap());



    }


   void Update()
    {
       
       
    }



    IEnumerator CreateTileMap()
    {

        while (true) 
        {
            //int randomIndex = UnityEngine.Random.Range(0, 4); // 랜덤 인덱스 생성
            // 타일맵을 순서대로 활성화함
            int randomIndex = results[count];

            //var pool = poolManager.GetPool<TileMapController>(randomIndex);
            var tileMap = poolManager.GetFromPool<TileMapController>(randomIndex);
            // 여기서 randomIndex는 풀의 인덱스입니다.

           // Debug.LogFormat("맵 번호 {0}", randomIndex);



            // 가져온 오브젝트를 사용합니다.
            if (tileMap != null)
            {
                tileMap.gameObject.SetActive(true);

                //오브젝트가 성공적으로 가져와졌다면, 여기서 추가 작업을 수행합니다.
                tileMap.transform.position = new Vector2(17.88f, 0);
                //  예를 들어, 오브젝트의 위치를 설정합니다.
            }

            else
            {
                Debug.Log("타일맵이 널");
              
               // ReturnObjectToPool(randomIndex, tileMap);

            }

            count++;
            yield return new WaitForSeconds(6f);

          

        }


    }

    //public void ReturnObjectToPool(int randomIndex,TileMapController tileMap)
    //{
    //    // 오브젝트를 비활성화합니다.
    //    tileMap.gameObject.SetActive(false);

    //    // 오브젝트를 풀에 반환합니다.
    //    poolManager.TakeToPool(randomIndex,tileMap);
    //    Debug.Log("풀에 반환");
    //}





       //타일맵 랜덤 번호를 생성하고 저장
    void GenerateRandomNumbers()
    {
        long originalSeed = seed; // 초기 seed 값을 임시 변수에 저장
        results.Clear();
        for (int i = 0; i < iterations; i++)
        {
            seed = (a * seed + c) % m; // 현재 seed를 사용하여 난수 생성
            int randomNumber = minNumber + (int)(seed % (maxNumber - minNumber + 1));
            results.Add(randomNumber);
        }
        seed = originalSeed; // 난수 생성 후 원래 seed 값으로 복원
    }

}

 `GetComponent<T>()`와 `GameObject.FindAnyObjectByType<T>()`의 차이점은 다음과 같습니다:

1. **`GetComponent<T>()`**:
   - `GetComponent<T>()`는 **동일한 GameObject에 연결된 컴포넌트**를 찾습니다.
   - 즉, 현재 GameObject 내에서만 검색합니다.
   - 예를 들어, 현재 GameObject에 연결된 `LevelManager` 컴포넌트를 찾을 때 사용합니다.

2. **`GameObject.FindAnyObjectByType<T>()`**:
   - `GameObject.FindAnyObjectByType<T>()`는 **전체 계층 구조에서 해당 타입을 가진 객체를 찾습니다**.
   - 씬 전체에서 검색하며, 최적의 방법은 아닙니다.
   - 이 함수는 느리기 때문에 특정한 경우에만 사용해야 합니다.

따라서, `GetComponent<T>()`는 현재 GameObject 내에서 컴포넌트를 찾고, `GameObject.FindAnyObjectByType<T>()`는 전체 씬에서 해당 타입을 가진 객체를 찾습니다. 일반적으로 `GetComponent<T>()`를 사용하는 것이 더 효율적입니다. 😊