如何从列表中删除特定的游戏对象(位于数组中)?

时间:2019-02-09 21:33:02

标签: c# arrays list unity3d

我的代码目标是让多个头骨出现在屏幕上以进行比较。根据屏幕上头骨的数量(1-6),它们会改变位置和大小,Ive通过使用gameObjects数组(头骨)和可以跟踪哪个头骨位于哪个“位置”的列表来完成此操作。

如果要添加,该代码将起作用,但是在删除该对象时会遇到问题。仅当您按照添加游戏对象的顺序删除游戏对象时,它才能在 RemoveAt 上运行。 IE:列表始终删除 element 0 (列表中的第一项),而不是引起 RemoveAt 函数的特定gameObject。

尽管我找到了许多有关如何删除特定单个GameObject的答案,但由于我的gameObject位于数组中,因此它们无法正常工作-我不能简单地说出删除gameObject名称。这使我想到了如何从列表中删除特定gameObject []的问题?

删除 removeAll 都运行以下两个错误:

错误CS1502: System.Collections.Generic.List<UnityEngine.GameObject>.RemoveAll(System.Predicate<UnityEngine.GameObject>)' has some invalid arguments.
Error CS1503: Argument
#1'的最佳重载方法匹配无法转换int' expression to type System.Predicate'

这是我所有这两个脚本:

每个鸟类头骨上名为 birdController 的脚本:

public int myBirdID;
public int orderInList;

//bool to keep track of object active or not
public bool whoAmIReally;
//potentially redundant; allows game object to see if hes on or not
public GameObject IAmMe;

// Use this for initialization
void Start () {
    //fixingIntOrder();
}

public void OnEnable(){
    //when object is on check bool
        whoAmIReally = true;
        Debug.Log("IM ON");
}
    public void OnDisable(){
    //when object is turned off uncheck bool, change list value to 0
            //**this wont change actual list order or value in cubeplacement script- my hope is that it might have- likely missing a step somewhere
        whoAmIReally = false;
        orderInList = 0;
        Debug.Log("IMOFF");
}

脚本为空,所有数组和列表信息均命名为 cubePlacement

    public int numberSkullOnScreen;
    public bool[] skullOn;
    public GameObject[] allSkulls;

    public GameObject listHolder;

    public List<GameObject> birdsOnScreen = new List<GameObject>();


//declaring the script to avoid NullReferenceEcxeption where I reference it 
public birdController _birdController;


    // Use this for initialization
    void Start () {
        //only way I can get my list to work: have an object act as a placeholder onStart
        birdsOnScreen.Add(listHolder);
    }

//turning on and off the skulls
    public void toggleBirdSkull(int mySkull){
        if (skullOn[mySkull] == false){
            //set specific gameObject active
            allSkulls[mySkull].SetActive(true);
            //make skull on bool true 
            skullOn[mySkull] = true;
            //add one to the number on screen
            numberSkullOnScreen++;

            //reference int orderInList from Bird controller script
            allSkulls[mySkull].gameObject.GetComponent<birdController>().orderInList = numberSkullOnScreen;

            //add skull to list when turned on THIS WORKS YAY
            birdsOnScreen.Add(allSkulls[mySkull]);
            //Run function to place skulls
            placementSkulls();
        }

        else{
            allSkulls[mySkull].SetActive(false);
            skullOn[mySkull] = false;
            numberSkullOnScreen--;

            //remove skull from list when turned off-- THIS DOESNT WORK... 
            birdsOnScreen.RemoveAt(allSkulls[mySkull].gameObject.GetComponent<birdController>().orderInList);


            //Run function to place skulls based on the int number skulls on screen
            placementSkulls();
        }
    }

2 个答案:

答案 0 :(得分:3)

您是否尝试过使用Remove方法删除对象? 像这样:

birdsOnScreen.Remove (allSkulls[mySkull]);

您的birdsOnScreen.RemoveAt版本看起来也正确。 如果要使用RemoveAll方法,则应传递谓词,该谓词返回bool,例如:

birdsOnScreen.RemoveAll (bird => { return bird == allSkulls[mySkull]; } );

我建议您使用Remove,因为您知道要删除的对象。

在此处了解更多信息:https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.remove?view=netframework-4.7.2

此外,在将numberSkullOnScreen的值分配给对象的属性后,请尝试增加其值:

allSkulls[mySkull].gameObject.GetComponent<birdController>().orderInList = numberSkullOnScreen;

numberSkullOnScreen++;

这样,您将不再需要使用占位符,因为您的索引将是正确的。

答案 1 :(得分:1)

我想您正在寻找类似List中的类似功能。您可以使用:

public static void RemoveAt<T>(ref T[] arr, int index) {
        for (int a = index; a < arr.Length - 1; a++)
        {
            arr[a] = arr[a + 1];
        }
        Array.Resize(ref arr, arr.Length - 1);
    }

或者如果您知道对象:

public static T[] RemoveObjectArray<T> (this T[] arr, T ObjToRemove) {  
        int numIdx = System.Array.IndexOf(arr, ObjToRemove);
        if (numIdx == -1) return arr;
        List<T> tmp = new List<T>(arr);
        tmp.RemoveAt(numIdx);
        return tmp.ToArray();
    }