我有两个脚本,每个脚本都附加到另一个空的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);
}
}
到目前为止,它可以满足我的要求,但是我是否将随机部分添加到了正确的脚本中并放置了?
我该如何使它代替生成不间断的随机对象,而仅在更改size变量的Range滑块时才生成它们呢?
例如[Range(1,150])
当我更改值时,它将在FixedUpdate中添加/删除对象吗? (应该是Update,它是FixedUpdate,因为在此之前我使用了Rigidbody,但现在没有使用)。
想法是更改大小,或者如果我将大小设置为1000,然后使用“范围”滑块更改使用对象的数量,例如445或500或1000。
每次更改大小时,它会将对象随机放在其他随机位置。但是一次,而不是像现在在固定更新中那样总是如此。
每次更改大小都会随机更改对象位置。 因此,如果将大小更改为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;
}
}
在“开始”的第二个脚本中,例如,我使用了整个对象一次,当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个生成器。 / p>
生成器的大小永远不会改变。然后,当将范围右移到右时,将使生成器使用它们直到结束,就是这样,它将永远不会改变,它将使用它们,仅使用27。
例如,即使Range值是150,在等级中仍然有27个生成器,并且在游戏中它本身是150,而不是150。
答案 0 :(得分:0)
到目前为止,它可以满足我的要求,但是我是否在正确的脚本中添加了随机部分并放置了?
我不知道,如果你问我是1 +1 = 2,我可以给你答案。
我该如何使它生成连续的随机对象,而不是生成连续的随机对象,仅当我更改大小变量的“范围”滑块时才生成它们?
您需要另一个尺寸字段:
public class Pool
{
public string tag;
public GameObject prefab;
[Range(1, 150)]
public int size;
private int sizeOld;
}
然后在FixedUpdate更新中进行简单比较:
void Update()
{
foreach(Pool pool in 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
}
}
}
当我更改值时,它将在FixedUpdate中添加/删除对象?
取决于调用生成方法的位置。