Как я могу расположить случайные объекты на x, y, z, используя пул объектов? - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть два скрипта, каждый из которых прикреплен к другому пустому 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.

1 Ответ

0 голосов
/ 26 февраля 2019

Это делает то, что я хочу до сих пор, но я добавил случайную часть в правильный сценарий и место?

Я не знаю, если вы спросите меня, 1 +1 = 2, я могу дать вам ответ.

И как я могу сделать так, чтобы вместо генерации непрерывных случайных объектов он генерировал их только тогда, когда я изменю ползунок Range переменной размера?

Вам нужно другое поле размера:

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?

Зависит от того, где вы вызываете метод порождения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...