How do I find an Object from the list

I spent all day and night for try to resolve this problem! I’d like to remove the first “GameObject” which is detected by the Player when it reaches the distance of 1f!
I can’t find the solution, if I destroy it I get the error where unity is looking for the object! How to avoid deletion without changing all the code! I’m to find any information about it!

  void Update()
    {

        float Closestdistance = Mathf.Infinity;
        foreach (GameObject obj in Objects)
        {
            var distance = Vector3.Distance(obj.transform.position, transform.position);

            if (distance < Closestdistance)
            {


                Closestdistance = distance;
                Closest = obj;

            
            }

            distance = Vector3.Distance(Player.transform.position, Closest.transform.position);
            Distance = Closestdistance;

            if (Distance < 1f)
            {
                Destroy(obj);

            }

        }

Although obj has been destroyed, it appears to be included in the objects list.
Before destroying obj remove the obj from the objects list and try again.

1 Like

Just remove the object from the collection when you destroy it. Though you will want to ensure you’re using a List. The code seems to be overcomplicated honestly. You just loop until you find the first one with distance less than one.

private void Update()
{
    GameObject closestObject = null;
  
    foreach (GameObject obj in Objects)
    {
        float distance = Vector3.Distance(obj.transform.position, transform.position);

        if (distance < 1f)
        {
            closestObject = obj;
            break;
        }
    }
  
    if (closestObject != null)
    {
        Objects.Remove(closestObject);
        Object.Destroy(closestObject);
    }
}
3 Likes

That’s what I wanted to do! Except that unity doesn’t offer me the “Remove” and “Destroy” var
Why it shows me the error:

error CS7036: There is no argument given that corresponds to the required formal parameter 'value' of 'CollectionExtensions.Remove<TKey, TValue>(IDictionary<TKey, TValue>, TKey, out TValue)

Thank you both so much for your answers and help!
I’m still looking on my side, if you know more about the problem, you’re welcome
Thank you

Well, I’ve found a solution to make it work. The solution may be wrong or archaic, but it works.
I didn’t fully explain the purpose of my script, to have been by spending a whole day and all night looking for a solution.
To explain, the “player” has to find hidden objects! The script here makes it easier for him to find the objects with the indication of the distance where all the hidden objects in the scene are.

So I wanted to destroy these objects to find, so that when the player is at a distance of “1f”! But since the function doesn’t work or shows me an error, I used the function to move the object farthest away from the scene so that the script calculates the rest that is still on the game scene.

Here’s the script:

    void Update()
    {
        float closestDistance = Mathf.Infinity;
        // GameObject Closest = null;

        foreach (GameObject obj in Objects)
        {
            var distance = Vector3.Distance(obj.transform.position, transform.position);

            if (distance < closestDistance)
            {
                Closest = obj;
                closestDistance = distance;

            }

            distance = Vector3.Distance(Player.transform.position, Closest.transform.position);
            Distance = closestDistance;



            if (Distance < 1f)
            {
                Closest.transform.position = new Vector3(0, 50, 0);
            }



        }
}

If I change the script you wrote @spiney199 my script doesn’t work the way I want it to. I want the player to detect the object closest to it, and if the player moves away, it looks for another one that is closest to it. Hence the reason to use the method of moving it as far away from the game as possible.
If you have any other simpler solution or opinion, I’m open to your help!
Thank you

Well apparently your collection is a dictionary??? That context would’ve been helpful to know.

Any you can still apply what I showed in principle, rather than just copying it verbatim. Destroy the object then remove it from the collection. But use a collection that you can actually remove elements from. It’s pretty crucial C# stuff to learn.

1 Like

This isn’t an answer to your direct question but usually you would want to recycle your objects, (to each their own) but it’s a very rare case in my opinion when you should destroy an object in game development, this is where object pooling comes into play.

Easy Object Pool | Tools | Unity Asset Store

the variable of “Objects” is: private GameObject[ ] Objects…
I can’t delete otherwise I get the error that shows me that the object is no longer defined and constantly looking for where the object goes…

How’s “Just jump directly into unity” working out for you here spiny? https://discussions.unity.com/t/942763/28
:smile:

You’re missing the point of what he’s saying, no one knew you were using an array, and you shouldn’t be using that here if you want to resize your arays, use a list with

.Add() List.Add(T) Method (System.Collections.Generic) | Microsoft Learn
and
.Remove() List.Remove(T) Method (System.Collections.Generic) | Microsoft Learn

What you’re trying to do isn’t the ‘proper way’ you should be using a resizable collection.

Highly recommend you take some time to learn the basics. There are very few cases you should ever be using .Destroy in game development.

Are you using a dictionary or an array? Show how you initialized and assigned your collection.

People are giving you good answers, pointers of what you should be doing. You could save a lot of time by trying to understand them more. Although the quick dirty, and hard lesson you’re teaching yourself is valuable too.

Summarizing all the good answers here:

1 Use a list not an array, it’s much better for this use case of needing to remove an element from a collection
2 Depends on the gameobject, but if it’s a frequent reappearing object like a bullet or enemy. Don’t Destroy() use SetActive(false) and reuse it later with SetActive(true). Reason : performance + you don’t have to move it way off scene where if it has update() or other calls to code, it’ll continue to run which impacts performance again.

You might also have a second list for all the inactive gameobjects for you to pull from if you reuse them again.

Thx you @abrakadouche I’ve already tried to use “SetActive” but the script keeps looking for it even though it’s disabled, that’s why I want to delete it directly.
Then I didn’t understand @jmgek from what you want to explain to me.

and 1) I’m not sure how to use a list instead of an array like (GameObjects[ ])
2) No its no bjects that respawns frequently
3) If there is a risk of performance impact, I am willing to learn another coding method

Here’s the script now work in my method :

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


public class OptionFindObjectInventory : MonoBehaviour
{

    [Header("Particule")]
    public GameObject ParticuleFireRED;
    public GameObject ParticuleFireGREEN;
    [Header("Prefab")]
    public GameObject Player;
    private GameObject[] Objects;
    public GameObject Closest;
    [Header("Text Affichage")]
    public float Distance;
    public Text textDistance;
    private int CounterObjectsFind;
    private bool ActiveCounter = true;
    [Header("Particle FX")]
    public GameObject FlamePlayer;


    void Start()
    {
        Objects = GameObject.FindGameObjectsWithTag("Objects");


    }


    void Update()
    {
        float closestDistance = Mathf.Infinity;


        foreach (GameObject obj in Objects)
        {
            var distance = Vector3.Distance(obj.transform.position, transform.position);

            if (distance < closestDistance)
            {
                Closest = obj;
                closestDistance = distance;

            }

            distance = Vector3.Distance(Player.transform.position, Closest.transform.position);
            Distance = closestDistance;



            if (Distance < 1f)
            {
                if (ActiveCounter)
                {
                    CounterObjectsFind += 1; // 3 Odds to find the prisoner cages and you have to buy again to use it
                    ActiveCounter = false;
                }
                Closest.transform.position = new Vector3(0, 50, 0);
            }



        }

        if (CounterObjectsFind == 3)
        {
            FlamePlayer.SetActive(false);
            CounterObjectsFind = 0;
        }




        if (Distance > 5f)
        {

            ParticuleFireRED.SetActive(true);
            ParticuleFireGREEN.SetActive(false);

        }


        if (Distance < 5f)
        {
            ParticuleFireRED.SetActive(false);
            ParticuleFireGREEN.SetActive(true);

            ActiveCounter = true;
        }

        textDistance.text = Distance.ToString("F1") + "°";

    }


}

You were linked to the C# docs. But List<T> is probably the most important C# library class to learn so I would familiarise yourself with them ASAP. They can be serialised like arrays for use in the inspector as well.

And there was an example of how to use it in my first post. Just destroy the object, then remove it from the collection.

1 Like

Brace for “now I’m getting a Collection was modified; enumeration operation may not execute.” error :smile:

thx you so much @spiney199
I didn’t know that this function was the most important to know in C# programming. I admit that I haven’t seen any tutorial that advocates this or in forums on the subject of this “List”
If you don’t mind, I’ll go back to my script and create the same thing with the “List” function and you’ll walk me step by step?
If for you its okay ?

I spent 3 days arguing with spiney and the forums saying you shouldn’t learn programming with unity without understanding the fundamentals…

Lists are extremely common so if you haven’t gone over them however your learning isn’t going to be a good way to continue.

You should take some time away from unity and learn the fundamentals of C# if you want to develop quicker and better. Or you’re just going to keep wasting your time on these types of issues: Introduction to C# - interactive tutorials - C# | Microsoft Learn

C# in isolation is incredibly boring and dry and obtuse… yawners all the way. Most non-engineers I know can’t be bothered to push through and actually learn anything meaningful by a pure-language focus.

Learning is also about motivation. While adding Unity into the mix complicates what you have to learn, it also gives you a nice surface to play around with visuals easily… and that can be motivating.

Here’s how to organize your thoughts when learning C# in Unity:

Your learning will be (largely) broken into broad areas of knowledge.

You may find these main buckets helpful to organize your learning:

  • C# language syntax (organization, structure, grammar, punctuation)
  • the .NET API (all the tools that come with C#: lists, dictionaries, file IO, etc)
  • the Unity API (everything in the using UnityEngine; namespace)

Beyond that mechanical stuff comes the interesting stuff: how to actually solve real world problems.

Go do lots and lots of small tutorials. You have not done a tutorial until you can explain ALL parts of it to your dog.

Imphenzia: How Did I Learn To Make Games:

Then learn with unity and try and use arrays instead of lists.

Lists are just an array but with the ability to add and remove items. You don’t need to use them and you can still make an application without them. They can even be a little slower than arrays because they need to be managed.

What you’ve been doing wrong is that you wasn’t checking if your object was destroyed when iterating through your array of objects.

    void Update()
    {
        float closestDistance = Mathf.Infinity;
        Closest=null;
        foreach (GameObject obj in Objects)
        {
            if (obj==null) // object no longer present in the array?
                continue; // skip the following code and get the next object
            Distance = Vector3.Distance(obj.transform.position, transform.position);
            if (Distance < 1f)
                Destroy(obj);
            else if (Distance < closestDistance)
            {
                Closest = obj;
                closestDistance = Distance;
            }
        }
    }

When iterating through an array of items where it’s possible for an item to longer exist you need to always check the item to see if it’s null (removed/destroyed).

1 Like

I’m not sure I follow your logic there… is an array less boring to learn than a list??

It also doesn’t make sense since List is actually an array underneath it all.

https://dotnetos.org/blog/2022-03-07-list-implementation/

You aren’t AnimalManUK by any chance are you? Your posts are beginning to exhibit a certain… je ne sais quoi…

You can write an application in binary, why even use arrays?

“Lists are just an array but with the ability to add and remove items.” literally what he’s trying to do…

No one said he had to use them, and don’t try and make an argument by bringing the computational overhead of a list vs array, he’s Destroying his objects he doesn’t care about performance, he is trying to learn.

You use lists here because it’s easier, safer, and quicker.

Not only that, but he also doesn’t know what lists are, are you suggesting he just continues on developing without understanding or knowing about lists? Is your solution to his journey to just use arrays for everything?