Как удалить конкретный игровой объект (который находится в массиве) из списка? - PullRequest
0 голосов
/ 10 февраля 2019

Моя цель с кодом состоит в том, чтобы на экране появилось несколько черепов для сравнения.В зависимости от количества черепов на экране (1-6) они меняют положение и размер, я сделал это с помощью массива gameObjects (черепов) и списка, который может отслеживать, какой череп находится в какой «позиции».

Код работает, если вы добавляете, но сталкивается с проблемами при удалении объекта.Он работает на RemoveAt только в том случае, если вы удаляете объекты GameObject в том же порядке, в котором они были добавлены.IE: список всегда удаляет элемент 0 (первый элемент в списке), а не конкретный gameObject, вызывающий функцию RemoveAt .

Хотя я нашел многоответы о том, как удалить отдельные отдельные объекты GameObject. Они не работают, так как мои объекты GameObject находятся в массиве. Я не могу просто сказать удалить имя gameObject .Что приводит меня к моему вопросу о том, как удалить определенный gameObject [] из списка?

remove или removeAll , запустите эти две ошибки:

ошибка CS1502: Наилучшее совпадение перегруженного метода для System.Collections.Generic.List<UnityEngine.GameObject>.RemoveAll(System.Predicate<UnityEngine.GameObject>)' has some invalid arguments.<br> 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 голосов
/ 10 февраля 2019

Вы пытались удалить объекты, используя метод 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++;

Таким образом, вам больше не нужно использовать заполнитель, потому что ваши индексы будут правильными.

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

Полагаю, вам нужна похожая функция, как в Списке.Вы можете использовать это:

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();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...