Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用对象池在x、y、z上定位随机对象?_C#_Unity3d - Fatal编程技术网

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);
    }
}