У меня есть два скрипта, каждый из которых прикреплен к другому пустому GameObject:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPooler : MonoBehaviour
{
[System.Serializable]
public class Pool
{
public string tag;
public GameObject prefab;
public int size;
}
#region Singleton
public static ObjectPooler Instance;
private void Awake()
{
Instance = this;
}
#endregion
public List<Pool> pools;
public Dictionary<string, Queue<GameObject>> poolDictionary;
// Start is called before the first frame update
void Start()
{
poolDictionary = new Dictionary<string, Queue<GameObject>>();
foreach(Pool pool in pools)
{
Queue<GameObject> objectPool = new Queue<GameObject>();
for(int i = 0; i < pool.size; i++)
{
GameObject obj = Instantiate(pool.prefab);
obj.SetActive(false);
objectPool.Enqueue(obj);
}
poolDictionary.Add(pool.tag, objectPool);
}
}
public GameObject SpawnFromPool(string tag, Vector3 position, Quaternion rotation)
{
if(!poolDictionary.ContainsKey(tag))
{
Debug.LogWarning("Pool with tag " + tag + " doesn't exist.");
return null;
}
GameObject objectToSpawn = poolDictionary[tag].Dequeue();
objectToSpawn.SetActive(true);
objectToSpawn.transform.position = position;
objectToSpawn.transform.rotation = rotation;
IPooledObject pooledObj = objectToSpawn.GetComponent<IPooledObject>();
if(pooledObj != null)
{
pooledObj.OnObjectSpawn();
}
poolDictionary[tag].Enqueue(objectToSpawn);
return objectToSpawn;
}
}
А второй и вот я добавил в FixedUpdate случайную часть:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CubeSpawner : MonoBehaviour
{
ObjectPooler objectPooler;
// Start is called before the first frame update
void Start()
{
objectPooler = ObjectPooler.Instance;
}
private void FixedUpdate()
{
var randp = new Vector3(Random.Range(0, 300), Random.Range(0, 300), Random.Range(0, 300));
objectPooler.SpawnFromPool("Cube", randp, Quaternion.identity);
}
}
Это делаетчто я хочу до сих пор, но я добавил случайную часть в правильный сценарий и поместил?
И как я могу сделать так, чтобы вместо генерации непрерывных случайных объектов он генерировал их только тогда, когда я буду менять ползунок Rangeпеременной размера?
Например [Range (1,150])
А когда я изменю значение, он будет добавлять / удалять объекты в FixedUpdate?(Это должно быть Update, это FixedUpdate, так как до этого я использовал Rigidbody, но не сейчас).
Идея состоит в том, чтобы либо изменить размер, либо установить размер, например, 1000, а затем использовать Rangeползунок для изменения количества используемых объектов, например, 445, 500 или 1000.
И каждый раз, когда я меняю размер, он случайным образом перемещает объекты в другие случайные позиции.Но один раз, а не все время, как сейчас в FixedUpdate.
Каждый раз при изменении размера меняйте положение объектов случайным образом.Так что, если размер я изменил на 10, измените положение 10 объектов случайным образом и используйте только эти 10 объектов.Если я изменю размер на 700, то меняю случайным образом 700 объектов и использую 700. (Не уверен, правильно ли говорить, использовать или уничтожить).
ОБНОВЛЕНИЕ:
Это то, что я пробовал вВ первом скрипте я добавил переменную oldSize и Range:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPooler : MonoBehaviour
{
[System.Serializable]
public class Pool
{
public string tag;
public GameObject prefab;
[Range(1, 150)]
public int size;
public int sizeOld;
}
#region Singleton
public static ObjectPooler Instance;
private void Awake()
{
Instance = this;
}
#endregion
public List<Pool> pools;
public Dictionary<string, Queue<GameObject>> poolDictionary;
// Start is called before the first frame update
void Start()
{
poolDictionary = new Dictionary<string, Queue<GameObject>>();
foreach(Pool pool in pools)
{
Queue<GameObject> objectPool = new Queue<GameObject>();
for(int i = 0; i < pool.size; i++)
{
GameObject obj = Instantiate(pool.prefab);
obj.SetActive(false);
objectPool.Enqueue(obj);
}
poolDictionary.Add(pool.tag, objectPool);
}
}
private void Update()
{
}
public GameObject SpawnFromPool(string tag, Vector3 position, Quaternion rotation)
{
if(!poolDictionary.ContainsKey(tag))
{
Debug.LogWarning("Pool with tag " + tag + " doesn't exist.");
return null;
}
GameObject objectToSpawn = poolDictionary[tag].Dequeue();
objectToSpawn.SetActive(true);
objectToSpawn.transform.position = position;
objectToSpawn.transform.rotation = rotation;
IPooledObject pooledObj = objectToSpawn.GetComponent<IPooledObject>();
if(pooledObj != null)
{
pooledObj.OnObjectSpawn();
}
poolDictionary[tag].Enqueue(objectToSpawn);
return objectToSpawn;
}
}
И во втором скрипте в Start я использую один раз целые объекты, например, я запускаю игру, когда значение Range равно27, а затем при изменении значения я обновляю oldSize:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CubeSpawner : MonoBehaviour
{
ObjectPooler objectPooler;
// Start is called before the first frame update
void Start()
{
objectPooler = ObjectPooler.Instance;
foreach (ObjectPooler.Pool pool in objectPooler.pools)
{
var randp = new Vector3(Random.Range(0, 300), Random.Range(0, 300), Random.Range(0, 300));
objectPooler.SpawnFromPool("Cube", /*transform.position*/ randp, Quaternion.identity);
}
}
private void Update()
{
foreach (ObjectPooler.Pool pool in objectPooler.pools)
{
if (pool.size != pool.sizeOld)
{
int diff = pool.size - pool.sizeOld;
pool.sizeOld = pool.size;
// Spawn new diff number of objects if diff is positive
var randp = new Vector3(Random.Range(0, 300), Random.Range(0, 300), Random.Range(0, 300));
objectPooler.SpawnFromPool("Cube", /*transform.position*/ randp, Quaternion.identity);
}
}
//var randp = new Vector3(Random.Range(0, 300), Random.Range(0, 300), Random.Range(0, 300));
//objectPooler.SpawnFromPool("Cube", transform.position /*randp*/, Quaternion.identity);
}
}
Но на самом деле создатели в Иерархии никогда не менялись там все время 27. Если Range меньше, чем 27, он будет использоватьменьше объектов, но если оно выше 27, в иерархии будет только 27 производителей.
Размер производителей никогда не изменится.И затем при перемещении Range влево-вправо, он будет заполнять тех, кто их использует, до конца, и это все, что он никогда не изменит, он будет использовать их все, но только 27.
Даже если значение Range равно 150, например, все еще там27 участников в иерархии и в самой игре, а не 150.