3
\$\begingroup\$

I'm using a "toggle visibility" script on many objects in my scene, and in my gameController class I'm storing references to them in an array like this:

public Fields[] fields;

then I access them by the array index:

fields[0].setVisibility(true);

This works fine, but this list is growing and everything is getting unmaintainable.

So I would like to iterate thru the references to the objects, find the script by its game object name, and call the required function setVisibility(state).

A call, if possible should look like this:

GameObjectName.ScriptName.FunctionCall.State

In this way, I would have a clear overview of my code.

Is this possible in Unity C#?

\$\endgroup\$
7
  • \$\begingroup\$ Is Fields a MonoBehaviour? How would one determine "the required function" using the game object's name? The more context you can give us about what gameplay feature you're implementing here, the better we can target answers that will be effective and scalable for that use. (Name-based lookups make me wary — there are almost always better solutions available) \$\endgroup\$
    – DMGregory
    Commented Aug 9, 2020 at 15:23
  • \$\begingroup\$ Yes, Fields is a MonoBehaviour. Calling the required function by his GameObject name would be very handy. In the case of fields, I'm just calling a "visible" toggle behavior, but I was hoping to find a clean structure in my code by just iterating thru referenced Empty children and accessing everything by GameObject names. Does this make sense? \$\endgroup\$
    – karl
    Commented Aug 9, 2020 at 16:05
  • \$\begingroup\$ It's not clear to me what operation you want to do with the name. Can you edit your question to describe the context in more detail, or possibly pseudocode demonstrating the kind of thing you want to do? \$\endgroup\$
    – DMGregory
    Commented Aug 9, 2020 at 16:06
  • \$\begingroup\$ I edited the question, this is the most simple scenario I can imagine. Please let me know if that is clearer now. Thanks! \$\endgroup\$
    – karl
    Commented Aug 9, 2020 at 16:22
  • \$\begingroup\$ Are you talking about GetComponent<Fields>()? \$\endgroup\$
    – DMGregory
    Commented Aug 9, 2020 at 16:28

2 Answers 2

1
\$\begingroup\$

This sets GameObjects' visibility by name by activating/deactivating them:

using System.Collections.Generic;
using UnityEngine;

public class Utility : MonoBehaviour
{
    static Dictionary<string, GameObject> gameObjects;

    public void Awake()
    {
        gameObjects = new Dictionary<string, GameObject>();
        foreach (var o in Resources.FindObjectsOfTypeAll<GameObject>())
            if (o.CompareTag("MyTag"))
                gameObjects.Add(o.name, o);
    }
    
    static public void SetVisible(string name, bool visibility = true)
    {
        gameObjects[name].SetActive(visibility);
    }
}

This makes the game object named "AnitaBath" visible by activating it

Utility.SetVisible("AnitaBath");

This makes the game object named "AnitaBath" invisible by deactivating it

Utility.SetVisible("AnitaBath", false);

How to Use This Script

This script should be added to a unique object in your scene like GameManager. It enumerates all objects in the scene tagged "MyTag" whenever it's Awake() method is called.

It assumes GameObject names are unique, you've created a new tag called "MyTag" and added this tag to the objects you'll be calling SetVisible on.

If you don't use the tag, you run the risk of affecting hidden internal objects (e.g., "SceneLight", "InternalIdentityTransform", "PreviewMaterials", "Cone", "Cube", ...)

\$\endgroup\$
1
  • \$\begingroup\$ This works perfectly. Thank you so much!!! \$\endgroup\$
    – karl
    Commented Aug 11, 2020 at 11:55
2
\$\begingroup\$

This sets GameObjects' visibility by name by enabling/disabling their MeshRenderer:

static public class Utility
{
    static public void SetVisible(string name, bool visibility = true)
    {
        GameObject.Find(name).GetComponent<MeshRenderer>().enabled = visibility;
    }
}

This makes the game object named "AnitaBath" visible by activating it

Utility.SetVisible("AnitaBath");

This makes the game object named "AnitaBath" invisible by deactivating it

Utility.SetVisible("AnitaBath", false);

Assumptions

This script assumes the GameObjects you are working with are active and contain a MeshRenderer component

\$\endgroup\$
3
  • \$\begingroup\$ Thanks a lot, this is what I need. Will this work with inactive objects too? And I'm not sure how to use this. Do I have to make a Utility script and reference it from my GameHandler script? \$\endgroup\$
    – karl
    Commented Aug 10, 2020 at 11:15
  • \$\begingroup\$ Good point. GameObject.Find doesn't find inactive GameObjects. I updated the code to change visibility by enabling/disabling a MeshRenderer component instead. \$\endgroup\$
    – Jim U
    Commented Aug 10, 2020 at 19:06
  • \$\begingroup\$ Yes, you create a Utility.cs script. It should NOT be dragged onto a GameObject in your scene; it just needs to exist in your Project assets. \$\endgroup\$
    – Jim U
    Commented Aug 10, 2020 at 19:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .