【发布时间】:2019-02-26 21:15:13
【问题描述】:
我有两个脚本,每个脚本都附加到另一个空游戏对象:
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);
}
}
到目前为止,它做了我想要的,但是我是否在正确的脚本和位置中添加了随机部分?
我怎样才能做到这一点,而不是生成不间断的随机对象,它只会在我更改大小变量的范围滑块时生成它们?
例如 [范围(1,150])
当我更改值时,它会添加/删除 FixedUpdate 中的对象吗? (应该是 Update 它是 FixedUpdate,因为之前我使用的是刚体,但现在不是)。
这个想法是要么更改大小,要么我将大小设置为 1000,然后使用范围滑块更改使用对象的数量,例如 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。如果范围低于 27,它将使用更少的对象,但如果大于 27,层次结构中仍然只有 27 个生成器。
生成器的大小永远不会改变。然后当左右移动范围时,它会填满产卵者使用它们直到结束,就是这样,它永远不会改变它会全部使用它们,但只有 27 个。
例如,即使 Range 值为 150,层次结构中仍然有 27 个生成器,并且在游戏中它自己而不是 150。
【问题讨论】: