간단하게 객체 풀 만들기

입문


이런 기사를 보기 때문에 초보자가 아니라고 생각해 쓴 것으로 초보적인 일은 생략했다.
2021/11/20 추기① {
Unity 표준 개체 풀 등장
Unity 2021에서 사용할 수 있는 Unity 표준 개체 풀 정보
근데 이 기사를 보시는 분들한테는 어려울 것 같아요.

환경


Unity 2019.2.11f

개체 풀


대량의 생성과 파괴를 미리 생성한다.수영장
순환하는 대상을 사용하여 생성 & 파괴 처리를 하지 않고 동작이 가벼워진다.
이런 느낌.

Q. 쉬운 방법


A.명단같은곳은필요 없어요.
풀의 보존 및 탐색을 Game Object의 하위 요소로 사용하기 때문에 특별한 어려움은 없다
아직 안 무거워요.

내용은 이것밖에 없어요.


Pool.cs
Transform pool; //オブジェクトを保存する空オブジェクトのtransform
void Start(){
 pool = new GameObject("名前").transform;
}

void GetObject(GameObject obj , Vector3 pos , Quaternion qua){
 foreach(Transform t in pool) {
    //オブジェが非アクティブなら使い回し
    if( ! t.gameObject.activeSelf){ 
      t.SetPositionAndRotation(pos,qua); 
      t.gameObject.SetActive(true);//位置と回転を設定後、アクティブにする
    } 
  } 
  //非アクティブなオブジェクトがないなら生成
  Instantiate(obj , pos , qua , pool);//生成と同時にpoolを親に設定
} 

예제 코드


샘플로 "Player"라는 유저용 스크립트와 "Bullet"이라는 총알 스크립트가 있다고 가정하면...
탄용 각본
Bullet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    void Update()
    {
        //右方向に移動
        transform.position += transform.right * 10 * Time.deltaTime ;
    }

    private void OnBecameInvisible()
    {
        //画面外に行ったら非アクティブにする
        gameObject.SetActive(false);
    }
}

유저 스크립트
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    //生成する弾
    [SerializeField] GameObject bullet = null;

    //弾を保持(プーリング)する空のオブジェクト
    Transform bullets;
    void Start()
    {
        //弾を保持する空のオブジェクトを生成
        bullets = new GameObject("PlayerBullets").transform;
    }

    void Update()
    {
        //まわれまーわれメリーゴーランド
        transform.Rotate(0, 0, 0.5f);

        //弾生成関数を呼び出し
        InstBullet(transform.position, transform.rotation);
    }

    /// <summary>
    /// 弾生成関数
    /// </summary>
    /// <param name="pos">生成位置</param>
    /// <param name="rotation">生成時の回転</param>
    void InstBullet(Vector3 pos,Quaternion rotation)
    {
        //アクティブでないオブジェクトをbulletsの中から探索
        foreach(Transform t in bullets)
        {
            if (!t.gameObject.activeSelf)
            {
                //非アクティブなオブジェクトの位置と回転を設定
                t.SetPositionAndRotation(pos, rotation);
                //アクティブにする
                t.gameObject.SetActive(true);
                return;
            }
        }
        //非アクティブなオブジェクトがない場合新規生成

        //生成時にbulletsの子オブジェクトにする
        Instantiate(bullet, pos, rotation, bullets);
    }
}
이런 느낌.

레벨 라이브러리의 Bullet 반복 활동과 비활동을 볼 수 있습니다

적용 (반환값 설정)


반환값 사용 클래스 유형
언제 버전부터 Instantiate () 의 매개 변수에 클래스를 추가했기 때문에 사용했습니다.
그러나 결과적으로 GetComponet<>()를 사용해야 하중을 줄이는 방법은...
함수의 반환 값이 Bullet형이기 때문에public의speed를 변경합니다.
(Bullet의 speed를 단순 변수로 설정하지 않고 검사기에 표시하는 것을 좋아하지 않음)
탄용 각본
Bullets.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    //Playerから入力
    public float speed { set; get; }

    void Update()
    {
        //右方向に移動
        transform.position += transform.right * speed * Time.deltaTime ;
    }

    private void OnBecameInvisible()
    {
        //画面外に行ったら非アクティブにする
        gameObject.SetActive(false);
    }
}
Player.cs

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

public class Player : MonoBehaviour
{
    //生成する弾
    [SerializeField] Bullet bullet = null;

    //弾を保持(プーリング)する空のオブジェクト
    Transform bullets;
    void Start()
    {
        //弾を保持する空のオブジェクトを生成
        bullets = new GameObject("PlayerBullets").transform;
    }

    void Update()
    {
        //まわれまーわれメリーゴーランド
        transform.Rotate(0, 0, 0.5f);

        //弾生成関数を呼び出し
        Bullet b = InstBullet(transform.position, transform.rotation);
        b.speed = Random.Range(5, 20f);
    }

    /// <summary>
    /// 弾生成関数
    /// </summary>
    /// <param name="pos">生成位置</param>
    /// <param name="rotation">生成時の回転</param>
    Bullet InstBullet(Vector3 pos,Quaternion rotation)
    {
        //アクティブでないオブジェクトをbulletsの中から探索
        foreach(Transform t in bullets)
        {
            if (!t.gameObject.activeSelf)
            {
                //非アクティブなオブジェクトの位置と回転を設定
                t.SetPositionAndRotation(pos, rotation);
                //アクティブにする
                t.gameObject.SetActive(true);
                return t.GetComponent<Bullet>();
            }
        }
        //非アクティブなオブジェクトがない場合新規生成

        //生成時にbulletsの子オブジェクトにする
        return Instantiate(bullet, pos, rotation, bullets);
    }
}
이런 느낌.
이렇게 말하지만, 나는 단지 플레이어가 속도를 조작할 수 있도록 할 뿐이다

총결산


예를 들어, 비활성 객체를 다른 상위 객체로 이동하여 검색 부담을 줄입니다.
친자관계의 변경 부담이 매우 높다고 해서 대량으로 하는 상대는 그다지 추천하지 않는다
활동용과 비활동용 목록을 만들고 친자관계를 변경하지 않는 것은 간단하고 부하가 적은 것 같다
부하 경감 대상 풀로 간단하게 제작할 수 있으니 꼭 활용하세요.
요약이 뭐였지?

좋은 웹페이지 즐겨찾기