C# 如何使用对象池在x、y、z上定位随机对象?
我有两个脚本,每个脚本都连接到另一个空游戏对象:C# 如何使用对象池在x、y、z上定位随机对象?,c#,unity3d,C#,Unity3d,我有两个脚本,每个脚本都连接到另一个空游戏对象: using System.Collections; using System.Collections.Generic; using UnityEngine; public class ObjectPooler : MonoBehaviour { [System.Serializable] public class Pool { public string tag; public GameO
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;
}
}
到目前为止,它符合我的要求,但我是否在正确的脚本和位置添加了随机部分
我怎样才能做到这一点,而不是生成不间断的随机对象,它只会在我更改大小变量的范围滑块时生成它们
例如[范围(1150])
当我更改值时,它会在FixedUpdate中添加/删除对象?(应该是更新它的FixedUpdate,因为在此之前我使用刚体,但不是现在)
我们的想法是要么更改大小,要么将大小设置为1000,然后使用范围滑块更改使用对象的数量,例如445或500或1000
每次我改变尺寸时,它都会在其他随机位置随机移动物体。但是一次也不是所有的时间都像现在在FixedUpdate中一样
每次更改大小都会随机更改对象的位置。
因此,如果我将其大小更改为10,则随机更改10个对象的位置,并仅使用这10个对象。如果我将大小更改为700,则随机重新定位700个对象并使用700。(不确定使用或销毁是否正确)
更新:
这是我在第一个脚本中尝试的,我添加了oldSize变量和范围:
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;
}
}
但事实上,教区中的产卵者从未改变,一直都是这样。如果范围低于27,它将使用较少的对象,但如果范围高于27,层次结构中仍将只有27个产卵器
产卵器的大小永远不会改变。然后,当向左向右移动范围时,它将填充产卵者使用它们直到结束,也就是说,它永远不会改变,它将使用它们,但只有27个
例如,即使范围值是150,在等级制中仍然有27个产卵者,而在游戏中,它本身不是150
到目前为止,它符合我的要求,但我是否在正确的脚本和位置添加了随机部分
我不知道,如果你问我是1+1=2,我可以给你一个答案
我怎样才能使它生成不间断的随机对象,而只是在我更改大小变量的范围滑块时才会生成它们
您需要另一个大小字段:
公共类池
{
公共字符串标签;
公共游戏对象预制;
[射程(1150)]
公共整数大小;
私营企业;
}
然后在FixeUpdate的更新中进行简单比较:
void Update()
{
foreach(池中的池)
{
if(pool.size!=pool.sizeOld)
{
int diff=pool.size-pool.sizeOld;
pool.sizeOld=pool.size;
//如果差异为正,则生成新的差异对象数
}
}
}
当我更改值时,它会在FixedUpdate中添加/删除对象
取决于调用生成方法的位置
到目前为止,它符合我的要求,但我是否在正确的脚本和位置添加了随机部分
我不知道,如果你问我是1+1=2,我可以给你一个答案
我怎样才能使它生成不间断的随机对象,而只是在我更改大小变量的范围滑块时才会生成它们
您需要另一个大小字段:
公共类池
{
公共字符串标签;
公共游戏对象预制;
[射程(1150)]
公共整数大小;
私营企业;
}
然后在FixeUpdate的更新中进行简单比较:
void Update()
{
foreach(池中的池)
{
if(pool.size!=pool.sizeOld)
{
int diff=pool.size-pool.sizeOld;
pool.sizeOld=pool.size;
//如果差异为正,则生成新的差异对象数
}
}
}
当我更改值时,它会在FixedUpdate中添加/删除对象
取决于调用生成方法的位置。更新FixeUpdate是什么意思?你是说在第二个脚本中,cubespowner和create在那里更新并将其放入更新中?然后删除FixedUpdate?我试着把它放在CubeSpowner脚本的FixedUpdate中,并引用了第一个脚本,但效果不好。如果我用27个对象开始游戏,然后改变对象的数量,那么大小和旧大小是相同的值。在等级体系中,仍然只有27个产卵者。在游戏中也只有27个。不管我是改成70码还是改成5码。还有27个。当第一次运行游戏时,它没有使用全部27个,或者如果我从150开始,它只使用一个第一个产卵器。也许你可以告诉我完整的代码应该是什么样子?也许我遗漏了什么?使用
Update
或FixedUpdate
取决于您的决定,我只写一个例子。这里没有完整的代码,请自行编写生成方法(在注释行处)。大小和旧大小是相同的值。。。正如您所见,代码仅在不相等时更改sizeOld
。您所说的FixedUpdate更新是什么意思?你是说在第二个脚本中,cubespowner和create在那里更新并将其放入更新中?然后删除FixedUpdate?我试着把它放在CubeSpowner脚本的FixedUpdate中,并引用了第一个脚本,但效果不好。如果我用27个对象开始游戏,然后改变对象的数量,那么大小和旧大小是相同的值。在等级体系中,仍然只有27个产卵者。在游戏中也只有27个。不管我是改成70码还是改成5码。还有27个。当第一次运行游戏时,它没有使用全部27个,或者如果我从150开始,它只使用一个第一个产卵器。也许你可以告诉我完整的代码应该是什么样子?也许我遗漏了什么?使用Update
或FixedUpdate
取决于您的决定,我只写一个例子。这里没有完整的代码,请编写spawni
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;
}
}
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);
}
}