Как я могу использовать пул объектов с атрибутом диапазона? - PullRequest
0 голосов
/ 19 апреля 2020

Минимум атрибута диапазона установлен равным 1 максимум 20. Я хочу, чтобы при перемещении ползунка диапазона в инспекторе вправо, чтобы увеличить значение, отключите объекты в соответствии с текущим значением диапазона, а при перемещении влево включите их обратно.

Скрипт MakeBall, в котором я использую атрибут range, а также добавил переменную oldrange, пытаясь найти, перемещается ли ползунок влево или вправо, а затем отключить / включить объект / ы, но он не работает нормально. При перемещении вправо отключаются только некоторые объекты, а затем при перемещении вправо немного больше к шару 12 или даже к 8 или 9 я получаю безостановочное исключение:

ArgumentOutOfRangeException: индекс вышел за пределы диапазона. Должен быть неотрицательным и меньше размера коллекции.

В строке 38:

balls[range].SetActive(false);

Сценарий Make Ball:

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class MakeBall : MonoBehaviour {
    [Header("The ball was already present in the object pooler")]
    public int ballIndex = 0;
    [Header("This ball will be added to the object pooler when the game begins")]
    public GameObject differentBall;
    private int differentIndex;
    private ObjectPooler OP;
    public Transform SpawnPoint;

    [Range(0, 20)]
    public int range = 0;
    private int oldrange = 0;

    private void Start()
    {
        OP = ObjectPooler.SharedInstance;
        differentIndex = OP.AddObject(differentBall);
        Random.InitState((int)System.DateTime.Now.Ticks);

        for(int i = 0; i < 20; i++)
        {
            CreateObjects();
        }

    }

    // Update is called once per frame
    void Update () {

        if(oldrange < range)
        {
            var balls = GameObject.FindGameObjectsWithTag("Ball").ToList();
            balls[range].SetActive(false);
        }

        if(oldrange > range)
        {
            var balls = GameObject.FindGameObjectsWithTag("Ball").ToList();
            balls[range].SetActive(true);
        }

        oldrange = range;
    }

    private void CreateObjects()
    {
        GameObject ball = OP.GetPooledObject(ballIndex);
        ball.tag = "Ball";
        ball.name = "Ball";
        ball.transform.rotation = SpawnPoint.transform.rotation;
        float xPos = Random.Range(-5f, 5f);
        float zPos = Random.Range(-5f, 5f);
        ball.transform.position = SpawnPoint.transform.position + xPos * Vector3.right + zPos * Vector3.forward;
        ball.SetActive(true);
    }
}

Это Класс ObjectPooler:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class ObjectPoolItem
{

    public GameObject objectToPool;
    public int amountToPool;
    public bool shouldExpand = true;

    public ObjectPoolItem(GameObject obj, int amt, bool exp = true)
    {
        objectToPool = obj;
        amountToPool = Mathf.Max(amt,2);
        shouldExpand = exp;
    }
}

public class ObjectPooler : MonoBehaviour
{
    public static ObjectPooler SharedInstance;
    public List<ObjectPoolItem> itemsToPool;


    public List<List<GameObject>> pooledObjectsList;
    public List<GameObject> pooledObjects;
    private List<int> positions;

    void Awake()
    {

        SharedInstance = this;

        pooledObjectsList = new List<List<GameObject>>();
        pooledObjects = new List<GameObject>();
        positions = new List<int>();


        for (int i = 0; i < itemsToPool.Count; i++)
        {
            ObjectPoolItemToPooledObject(i);
        }

    }


    public GameObject GetPooledObject(int index)
    {

        int curSize = pooledObjectsList[index].Count;
        for (int i = positions[index] + 1; i < positions[index] + pooledObjectsList[index].Count; i++)
        {

            if (!pooledObjectsList[index][i % curSize].activeInHierarchy)
            {
                positions[index] = i % curSize;
                return pooledObjectsList[index][i % curSize];
            }
        }

        if (itemsToPool[index].shouldExpand)
        {

            GameObject obj = (GameObject)Instantiate(itemsToPool[index].objectToPool);
            obj.SetActive(false);
            obj.transform.parent = this.transform;
            pooledObjectsList[index].Add(obj);
            return obj;

        }
        return null;
    }

    public List<GameObject> GetAllPooledObjects(int index)
    {
        return pooledObjectsList[index];
    }


    public int AddObject(GameObject GO, int amt = 3, bool exp = true)
    {
        ObjectPoolItem item = new ObjectPoolItem(GO, amt, exp);
        int currLen = itemsToPool.Count;
        itemsToPool.Add(item);
        ObjectPoolItemToPooledObject(currLen);
        return currLen;
    }


    void ObjectPoolItemToPooledObject(int index)
    {
        ObjectPoolItem item = itemsToPool[index];

        pooledObjects = new List<GameObject>();
        for (int i = 0; i < item.amountToPool; i++)
        {
            GameObject obj = (GameObject)Instantiate(item.objectToPool);
            obj.SetActive(false);
            obj.transform.parent = this.transform;
            pooledObjects.Add(obj);
        }
        pooledObjectsList.Add(pooledObjects);
        positions.Add(0);

    }
}

Основная цель заключается в использовании ползунка в инспекторе с пулами объектов для отключения / включения объектов вместо создания / уничтожения.

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