Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question How do I find an Object from the list

Discussion in 'Scripting' started by Giannigiardinelli, Apr 4, 2024.

  1. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189
    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!



    Code (CSharp):
    1.   void Update()
    2.     {
    3.  
    4.         float Closestdistance = Mathf.Infinity;
    5.         foreach (GameObject obj in Objects)
    6.         {
    7.             var distance = Vector3.Distance(obj.transform.position, transform.position);
    8.  
    9.             if (distance < Closestdistance)
    10.             {
    11.  
    12.  
    13.                 Closestdistance = distance;
    14.                 Closest = obj;
    15.  
    16.            
    17.             }
    18.  
    19.             distance = Vector3.Distance(Player.transform.position, Closest.transform.position);
    20.             Distance = Closestdistance;
    21.  
    22.             if (Distance < 1f)
    23.             {
    24.                 Destroy(obj);
    25.  
    26.             }
    27.  
    28.         }
     
  2. MCF24

    MCF24

    Joined:
    Mar 10, 2021
    Posts:
    18
    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.
     
    Giannigiardinelli likes this.
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,156
    Just remove the object from the collection when you destroy it. Though you will want to ensure you're using a List<T>. The code seems to be overcomplicated honestly. You just loop until you find the first one with distance less than one.

    Code (CSharp):
    1. private void Update()
    2. {
    3.     GameObject closestObject = null;
    4.  
    5.     foreach (GameObject obj in Objects)
    6.     {
    7.         float distance = Vector3.Distance(obj.transform.position, transform.position);
    8.  
    9.         if (distance < 1f)
    10.         {
    11.             closestObject = obj;
    12.             break;
    13.         }
    14.     }
    15.  
    16.     if (closestObject != null)
    17.     {
    18.         Objects.Remove(closestObject);
    19.         Object.Destroy(closestObject);
    20.     }
    21. }
     
  4. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189

    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
     
  5. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189
    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:

    Code (CSharp):
    1.     void Update()
    2.     {
    3.         float closestDistance = Mathf.Infinity;
    4.         // GameObject Closest = null;
    5.  
    6.         foreach (GameObject obj in Objects)
    7.         {
    8.             var distance = Vector3.Distance(obj.transform.position, transform.position);
    9.  
    10.             if (distance < closestDistance)
    11.             {
    12.                 Closest = obj;
    13.                 closestDistance = distance;
    14.  
    15.             }
    16.  
    17.             distance = Vector3.Distance(Player.transform.position, Closest.transform.position);
    18.             Distance = closestDistance;
    19.  
    20.  
    21.  
    22.             if (Distance < 1f)
    23.             {
    24.                 Closest.transform.position = new Vector3(0, 50, 0);
    25.             }
    26.  
    27.  
    28.  
    29.         }
    30. }
    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
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,156
    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.
     
    Nad_B likes this.
  7. jmgek

    jmgek

    Joined:
    Dec 9, 2012
    Posts:
    177
    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
     
  8. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189
    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...
     
  9. jmgek

    jmgek

    Joined:
    Dec 9, 2012
    Posts:
    177
    How's "Just jump directly into unity" working out for you here spiny? https://forum.unity.com/threads/am-i-wasting-my-time-with-unity-learning.1561576/#post-9750490
    :D


    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<T>.Add(T) Method (System.Collections.Generic) | Microsoft Learn
    and
    `.Remove()` List<T>.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.
     
  10. abrakadouche

    abrakadouche

    Joined:
    Apr 8, 2022
    Posts:
    17
    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.
     
  11. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189
    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 :



    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine.UI;
    4. using UnityEngine;
    5.  
    6.  
    7. public class OptionFindObjectInventory : MonoBehaviour
    8. {
    9.  
    10.     [Header("Particule")]
    11.     public GameObject ParticuleFireRED;
    12.     public GameObject ParticuleFireGREEN;
    13.     [Header("Prefab")]
    14.     public GameObject Player;
    15.     private GameObject[] Objects;
    16.     public GameObject Closest;
    17.     [Header("Text Affichage")]
    18.     public float Distance;
    19.     public Text textDistance;
    20.     private int CounterObjectsFind;
    21.     private bool ActiveCounter = true;
    22.     [Header("Particle FX")]
    23.     public GameObject FlamePlayer;
    24.  
    25.  
    26.     void Start()
    27.     {
    28.         Objects = GameObject.FindGameObjectsWithTag("Objects");
    29.  
    30.  
    31.     }
    32.  
    33.  
    34.     void Update()
    35.     {
    36.         float closestDistance = Mathf.Infinity;
    37.  
    38.  
    39.         foreach (GameObject obj in Objects)
    40.         {
    41.             var distance = Vector3.Distance(obj.transform.position, transform.position);
    42.  
    43.             if (distance < closestDistance)
    44.             {
    45.                 Closest = obj;
    46.                 closestDistance = distance;
    47.  
    48.             }
    49.  
    50.             distance = Vector3.Distance(Player.transform.position, Closest.transform.position);
    51.             Distance = closestDistance;
    52.  
    53.  
    54.  
    55.             if (Distance < 1f)
    56.             {
    57.                 if (ActiveCounter)
    58.                 {
    59.                     CounterObjectsFind += 1; // 3 Odds to find the prisoner cages and you have to buy again to use it
    60.                     ActiveCounter = false;
    61.                 }
    62.                 Closest.transform.position = new Vector3(0, 50, 0);
    63.             }
    64.  
    65.  
    66.  
    67.         }
    68.  
    69.         if (CounterObjectsFind == 3)
    70.         {
    71.             FlamePlayer.SetActive(false);
    72.             CounterObjectsFind = 0;
    73.         }
    74.  
    75.  
    76.  
    77.  
    78.         if (Distance > 5f)
    79.         {
    80.  
    81.             ParticuleFireRED.SetActive(true);
    82.             ParticuleFireGREEN.SetActive(false);
    83.  
    84.         }
    85.  
    86.  
    87.         if (Distance < 5f)
    88.         {
    89.             ParticuleFireRED.SetActive(false);
    90.             ParticuleFireGREEN.SetActive(true);
    91.  
    92.             ActiveCounter = true;
    93.         }
    94.  
    95.         textDistance.text = Distance.ToString("F1") + "°";
    96.  
    97.     }
    98.  
    99.  
    100. }
    101.  
    102.  
    103.  
     
  12. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,156
    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.
     
    Nad_B likes this.
  13. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    730
    Brace for "now I'm getting a Collection was modified; enumeration operation may not execute." error :D
     
  14. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189
    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 ?
     
  15. jmgek

    jmgek

    Joined:
    Dec 9, 2012
    Posts:
    177
    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
     
  16. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,006
    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:

     
  17. jmgek

    jmgek

    Joined:
    Dec 9, 2012
    Posts:
    177
    Then learn with unity and try and use arrays instead of lists.
     
  18. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    1,054
    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.
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         float closestDistance = Mathf.Infinity;
    4.         Closest=null;
    5.         foreach (GameObject obj in Objects)
    6.         {
    7.             if (obj==null) // object no longer present in the array?
    8.                 continue; // skip the following code and get the next object
    9.             Distance = Vector3.Distance(obj.transform.position, transform.position);
    10.             if (Distance < 1f)
    11.                 Destroy(obj);
    12.             else if (Distance < closestDistance)
    13.             {
    14.                 Closest = obj;
    15.                 closestDistance = Distance;
    16.             }
    17.         }
    18.     }
    19.  
    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).
     
    Giannigiardinelli likes this.
  19. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,006
    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<T> 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...
     
  20. jmgek

    jmgek

    Joined:
    Dec 9, 2012
    Posts:
    177
    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?
     
  21. jmgek

    jmgek

    Joined:
    Dec 9, 2012
    Posts:
    177
    Lists are resizable collections are you trying to say he shouldn't understand them? Are you all this ignorant?
     
  22. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    730
    I'm a little bit with @jmgek on this, these forums are not really a "Learn C#" forums, but more like "General discussions and problems of Scripting in Unity", which assumes the posters have at least a minimum C# knoweldge. Collections are fundamentals to any programming languages, I'd say as fundamental as variables, conditions and loops.

    If OP asked "what is an "if"?" or "what this "foreach" thing does?" after few replies, I'd bet most of people here will give a small explanation then highly encourage the asker to stop what they're doing and go learn some C# basics...

    And it doesn't necessary mean that they have to do a classical "Harvard CS50 course", but there are tons of C# introduction courses specifically tailored to Unity, for example CodeMonkey just launched recently a C# basics courses.

    That's just my $.02.
     
    Last edited: Apr 8, 2024
    Ryiah and jmgek like this.
  23. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    1,054
    Lists can be great!. I didn't tell him not to use lists. I'm just letting him know that he doesn't have to use them. The post I replied to sounded like he was about to become a list fanatic. :)

    I'm sensing you're really bored, jmgek. I've noticed all of your posts seem a little argumentative and antagonistic. Chill, dude! There must be something more constructive for you to do. Start a new project. Make something cool! :cool:
     
    Kurt-Dekker likes this.
  24. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    730
    No please, God, no! not again :D
     
    Kurt-Dekker likes this.
  25. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,450
    We have a section dedicated to people just getting started and in a perfect world we would direct people there but the major problem with that section is how low activity it is. A thread here will at least get a response from Kurt but a thread in that section is likely to not receive any answer and is often a beginner trying to help another beginner.
     
    Nad_B likes this.
  26. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189
    I admit that I learned all of them with unity3d, I managed to list a lot of info in forums and tutorials and let's say that I manage to manage despite my somewhat archaic learning^^
    Soon I'm going to start a programming course, and if you say I can learn C# without unity I'll ask for it. I understood that if you use unity, you need to code according to the unity software.
    Thanks for knowing information!
     
  27. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,450
    Only in the sense that you're using the Unity APIs. Aside from that, and the scripting framework being out of date compared to the official releases by Microsoft, you can do what you want.
     
  28. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189

    Thx you @Kurt-Dekker
    For your info I'll inquire. Are there any books that use the 3 headings you mentioned?

    - 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)
     
  29. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189
    Great, thanks @zulo3d , I'll take it easy, and figure out how it works. Already in preview there are things that speak
    I'll get back if the script works that way
     
  30. Giannigiardinelli

    Giannigiardinelli

    Joined:
    May 8, 2014
    Posts:
    189
    Yes, CodeMonkey I am a follower of this person who helped me a lot and would not fail to mention him in the game created.
    She allowed me to understand and to be able to manage afterwards.
    Thank you to everyone who took the time to help me with the "tables" and "lists"
     
    Nad_B likes this.
  31. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    730
    I wish you great success in your endeavor, adventurer!

    Don't hesitate to ask questions, even if it seems "stupid" to you, believe me it's not. It's just a lack of experience and we've all been there. It's just when something is too fundamental, I'd prefer to reply with "learn the basics first", in a kind manner of course, because development is simply a job, and like other jobs, it requires both knowledge and experience. And here we can help with the experience part, but most of us can't do the knowledge part because we're very bad teachers :D
     
  32. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,006
    Books? :)

    In seriousness, sure, I guess there probably are.

    It isn't the source of the info. It's the info.

    My guide above is just to help you think about the torrent of new info.