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

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

问题描述

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

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 个弹簧,每次使用弹簧时,我都想从数组中的第一个元素中取出它,将该数组的所有剩余元素向上移动,然后将第一个对象移动到最后一个数组中的索引.

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 开始,每次你请求一个对象时,你将它加一.如果索引等于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();
}

<小时>

方法二:

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 中的游戏对象即可回收它.下次您需要一个新的时,循环遍历 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一个新的,将它添加到列表中,然后返回它.这是最简单的方法.只需观看 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天全站免登陆