向上移动/移动数组中的对象,然后将第一个元素移动到最后一个索引 [英] Move/Shift Objects in array up then move the first element to the last index

查看:510
本文介绍了向上移动/移动数组中的对象,然后将第一个元素移动到最后一个索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Unity3D中构建游戏,我试图通过启用和禁用GameObjects来重用GameObjects,而不是实例化并销毁它们.

I'm building a game in Unity3D and I am trying to reuse GameObjects by enabling and disabling them rather than instantiating and destroying them.

我在GameObject数组中有10个弹簧,每次使用弹簧时,我都希望从该数组的第一个元素中取出弹簧,向上移动该数组的所有其余元素,然后将第一个Object移至最后一个数组中的索引.

I have 10 springs in a GameObject array and every time I use a spring I want to take it from the first element in the array, shifting all of the remaining elements of that array up, then move the first Object to the last index in the array.

推荐答案

这称为对象池.您无需从第一个或最后一个删除数组即可执行此操作.有很多方法可以在Unity中将其存档.

This is called Object Pooling. You do not need to remove array from first or last to do this. There are many ways to archive this in Unity.

方法1(推荐):

即使可以,但在数组中移动对象也是不必要且效率低下的.您可以有一个可移动的索引.它从0开始,并且每次您请求对象时,都将其递增1.如果索引等于Array.Length - 1,则将索引重置为0.

Even though that works, it unnecessary and inefficient to move the Objects in the array. You can have an index that moves around. It starts from 0 and each time you request an Object, you increment it by one. If the index equals to Array.Length - 1, reset index back to 0.

public class ArrayObjectPooling
{
    int amount = 10;
    GameObject[] objArray;
    int currentIndex = 0;

    public ArrayObjectPooling(GameObject objPrefab, string name, int count)
    {
        amount = count;
        objArray = new GameObject[amount];

        for (int i = 0; i < objArray.Length; i++)
        {
            objArray[i] = UnityEngine.Object.Instantiate(objPrefab, Vector3.zero, Quaternion.identity);
            objArray[i].SetActive(false);
            objArray[i].name = name + " #" + i;
        }
    }

    //Returns available GameObject
    public GameObject getAvailabeObject()
    {
        //Get the first GameObject
        GameObject firstObject = objArray[currentIndex];

        //Move the pointer down by 1
        shiftDown();

        return firstObject;
    }

    //Returns How much GameObject in the Array
    public int getAmount()
    {
        return amount;
    }

    //Moves the current currentIndex GameObject Down by 1
    private void shiftDown()
    {
        if (currentIndex < objArray.Length - 1)
        {
            currentIndex++;
        }
        else
        {
            //Reached the end. Reset to 0
            currentIndex = 0;
        }
    }
}

用法:

public GameObject prefab;

void Start()
{
    ArrayObjectPooling arrayPool = new ArrayObjectPooling(prefab, "Springs", 10);
    GameObject myObj = arrayPool.getAvailabeObject();
}


方法2 :

List足以执行此操作.请看看看看Unity的Object官方教程池实现了这一点.无需在此处发布代码.

List is enough to do this if the pool is small. Please take a look at Unity's official tutorial for Object Pooling implemented this. It is unnecessary to post the code here.

您只需禁用 List中的GameObject即可对其进行回收.下次您需要一个新的时,遍历List并返回List中的第一个禁用的GameObject.如果启用,则表示它仍在使用中.

You simply disable the GameObject in the List to recycle it. Next time you need a new one, loop over the List and return the first disabled GameObject in the List. If it is enabled, that means that it is still in use.

如果在List中未找到禁用的GameObject,则可以Instantiate一个新的GameObject,将其添加到列表中,然后将其返回.这是最简单的方法.只需观看Unity教程即可了解更多信息.

If no disabled GameObject is found in the List, then you can Instantiate a new one, add it to the list and then return it. This is the easiest way of doing this. Just watch the Unity tutorial for more information.

方法3 :

使用队列或堆栈.您可以将对象排入队列,或从池中推送/弹出对象.如果您对此进行简单的重新搜索,就有很多实现方法.

Use Queue or Stack. You can queue and enqueue or push/pop the Objects from the pool. There are many implementation out there if you do a simple reseach-search on this.

方法4 :

之所以仅提及它,是因为这是您最初的问题,即如何在数组中上移对象,然后将第一个值放在数组的最后一个索引中.您不应该使用它.只是在这里显示它可以完成.

This is only mentioned because this was your original question about how to shift objects up in an array and then put the first value in the last index of the array. You should not not use this. It is only here just to show that it can be done.

public class ArrayObjectPooling
{
    int amount = 10;
    public GameObject[] objArray;

    public ArrayObjectPooling(GameObject objPrefab, string name, int count)
    {
        amount = count;
        objArray = new GameObject[amount];

        for (int i = 0; i < objArray.Length; i++)
        {
            objArray[i] = UnityEngine.Object.Instantiate(objPrefab, Vector3.zero, Quaternion.identity);
            objArray[i].SetActive(false);
            objArray[i].name = name + " #" + i;
        }
    }

    //Returns available GameObject
    public GameObject getAvailabeObject()
    {
        //Get the first GameObject
        GameObject firstObject = objArray[0];

        //Move everything Up by one
        shiftUp();

        return firstObject;
    }

    //Returns How much GameObject in the Array
    public int getAmount()
    {
        return amount;
    }

    //Moves the GameObject Up by 1 and moves the first one to the last one
    private void shiftUp()
    {
        //Get first GameObject
        GameObject firstObject = objArray[0];

        //Shift the GameObjects Up by 1
        Array.Copy(objArray, 1, objArray, 0, objArray.Length - 1);

        //(First one is left out)Now Put first GameObject to the Last one
        objArray[objArray.Length - 1] = firstObject;
    }
}

用法:

public GameObject prefab;

void Start()
{
    ArrayObjectPooling arrayPool = new ArrayObjectPooling(prefab, "Springs", 3);
    GameObject myObj = arrayPool.getAvailabeObject();
}

这篇关于向上移动/移动数组中的对象,然后将第一个元素移动到最后一个索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆