Individual Object Canvases

So picture a tactics game. Units are taking turns, but turn order is variable, not round-robin (because different maneuvers can take different amounts of time).
The bottom left section of the screen has the currently active unit’s information: A character portrait, text field with their name, a hp bar, maybe mp or energy bar, probably any status effects they have.
The bottom right, meanwhile, has the player’s selected unit - basically whoever they’ve clicked on most recently. This lets them click around the field and see who’s at what health value, or just double-check who’s who if two units look similar.

My organization for making this kind of thing happen has been to have an overarching Unit object. This contains the model that appears on the map but also a canvas with the Unit’s information (portrait image, text field, hp bar, etc).
Inside the canvas is also an initiative marker, telling the player how soon their next turn is relative to the other units in the scene.

So what I’m trying to do is fairly complex:
From another object - a GameController (with a script of the same name) - when a turn is done I want to set CurrentUnit to a new Unit in the scene. (This much I’ve managed to do.)

Then I want to disable the “CharacterInfo” portion of each Unit’s Canvas (but not the ENTIRE Canvas, because that would disable the initiative marker) and enable the CurrentUnit’s “CharacterInfo.”
The idea being each one has information in the bottom left corner but only the correct info is active at any given time.

Following the advice for disabling objects in Unity has thus far been fruitless, and as I look into conversations about Canvases I’m wondering whether there’s some wonky rule to enabling/disabling parts of a Canvas.

public void HandleUnitVisibility()
    {
        for (int i = 0; i < initList.Count; i++)
        {
            CharacterInfo ci = initList[i].GetComponentInChildren<CharacterInfo>();
            if (initList[i] == currentUnit)
            {
                ci.SetActive(true);
               
            }
            else
            {
                ci.SetActive(false);
            }
        }
    }

This doesn’t work because SetActive isn’t recognized as part of CharacterInfo, which is just an empty GameObject. “ci.enabled” doesn’t work either, for the same reason. I’ve tried to cast CharacterInfo as a GameObject to regain access to .enabled or SetActive but if that can be done I’m not doing it right.
(initList is a List of Unit GameObjects, in case you’re wondering)

Related question: Is the underlying design - a set of overlapping canvases, with only one visible at any time - just really awful? Should I be rejiggering my fields so that there’s a single section on the bottom left and it’s grabbing info FROM each Unit?

Have you tried ci.gameObject.SetActive?

1 Like

It replies:
‘CharacterInfo’ does not contain a definition for ‘gameObject’ and no accessible extension method ‘gameObject’ accepting a first argument of type ‘CharacterInfo’ could be found.

Well, I found one Huge problem with the code, though I still haven’t gotten it working:
CharacterInfo is its own kind of named Struct in C#. Naming my GameObject “CharacterInfo” was always going to be a disaster.
I’ve changed it to “UnitInfo” but I’m still having trouble accessing game object inside of canvas inside of game object.

Is GetComponent even the right tool? What I want to be flicking on and off is the entire GameObject and its children (Not the entire Unit, but down inside it the UnitInfo object and everything it contains).