0

I am trying to find all active and nonactive gameObjects which have a common script added to them. I am able to find all active gameObjects but unfortunately the inactive ones do not get viewed by my script. How can I overcome this?

public myScript[] commonScripts;

void Start() {
 commonScripts = FindObjectsOfType(typeof(myScript)) as myScript[];
}
Max
  • 141
  • 1
  • 9

2 Answers2

1

If myScript is one of your C# scripts, I'd use a static list containing all instances.

Sample Code

using System.Collections.Generic;
using UnityEngine;

public class MyScript : MonoBehaviour
{
    public static List<MyScript> allObjects = new List<MyScript>();

    private void Start()
    {
        if (allObjects.Contains(this) == false)
            allObjects.Add(this);
    }

    private void OnDestroy()
    {
        if (allObjects.Contains(this))
            allObjects.Remove(this);
    }
}

You can use this in any other class as follows

using UnityEngine;

public class AnotherScript : MonoBehaviour
{
    private void AnyFunction()
    {
        foreach (MyScript ms in MyScript.allObjects)
        {
            // do whatever you want
        }
    }
}
DevConcepts
  • 174
  • 8
  • You might consider to rather use a `HashSet` .. depending on the amount of instances – derHugo Sep 29 '21 at 10:11
  • Definitely. But it still depends on the use case. – DevConcepts Sep 29 '21 at 11:01
  • not really .. the use case is clear ;) It rather depends on the amount of elements whether `Contains` and `Add` are [more performant on a `List` or a `HashSet`](https://stackoverflow.com/questions/150750/hashset-vs-list-performance) ;) – derHugo Sep 29 '21 at 11:12
1

You should try a different approach where the component instance adds itself to a list in Awake or Start

public class MyScript : MonoBehaviour
{
    void Awake()
    {
         FindObjectOfType<ContainerClass>().Add(this);
    }
    void OnDestroy()
    {
         FindObjectOfType<ContainerClass>().Remove(this);
    }
}

public class ContainerClass : MonoBehaviour
{
    private List<MyScript> scripts = new List<MyScript>();
    
    public void Add(MyScript script)
    {
         scripts.Add(script);
    }
    public void Remove(MyScript script)
    {
         scripts.Remove(script);
    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
fafase
  • 467
  • 3
  • 10
  • How is this `FindObjectOfType().Add(this);` supposed to compile ... you get a `ContainerClass[]` then try to use `Add` on it and add a `MyScript` instance ... doesn't make any sense at all ^^ – derHugo Sep 29 '21 at 10:03
  • It's FindObjectOfType not FindObjectsOfType so you get a single item. – fafase Sep 29 '21 at 10:24
  • Ah sorry my bad now I see what you mean! Still: Why have a dedicated component for that and not just do it in the class itself? – derHugo Sep 29 '21 at 10:28
  • I understand the original example implies it would be a separate component. And doing it in the class would mean you have many iteration of the same action. Else it would mean static which is the other answer. – fafase Sep 29 '21 at 10:30
  • ContainerClass can also be passed around with the consideration it may be persistent while those MyScript objects may well be destroyed. All in all, description is a bit left to the imagination. – fafase Sep 29 '21 at 10:31
  • In my eyes it would be way better to use `static` than rely on that an instance of another class hopefully is somewhere active in the scene ;) ... either way there now is also [`FindObjectsOfType(bool)`](https://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html) and this and the other solution(s) are already in the duplicate link ;) – derHugo Sep 29 '21 at 10:34