Button to enable a canvas doesnt work.

Greetings!
I have a very specific problem that I could not find answer elsewere, so I come here for help! first post ever, so, apologies for any mistakes.

I’m learning unity, and I thought it would be interesting, in a turn based game, to get the canvas of the character enabled only when he is taking his turn.

I have another script that instantiate clones of prefabs that represent my characters, each have their own canvas, that for now, display a single ‘end turn’ button, and I have another script that is supposed to manage their turns.

At runtime the prefabs spawn. In the Unity Editor, the script that manages the turns properly has every component associated in the script in the inspector panel, and when i press the button to display one clone’s canvas, it just does nothing, and does not display any errors.

I declare these arrays at the beginning of the script:

public GameObject[] characters;
[SerializeField] private CharacterAtributes[] characterAtributes;
[SerializeField] private Canvas[] characterCanvas;

Later, I call this function to get references for instantiated characters inside the arrays:

void CharacterFinder()
{
    for (int i = 0; i < 4; i++)
    {
        characters[i] = GameObject.Find("PlayerCharacter" + (i + 1));
        characterAtributes[i] = characters[i].GetComponent<characterAtributes>();
        characterCanvas[i] = characters[i].GetComponentInChildren<Canvas>(includeInactive: true);
    }
}

Then I made this button just to test the management of the canvases:

public void CharacterTurnReady()
{
    characterAtributes[0].speed -= 20.0f;
    characterCanvas[0].enabled = true;
    Debug.Log("character canvas: " + characterCanvas[0]);
    if characterCanvas[0].enabled)
    {
        Debug.Log("Canvas enabled: " + characterCanvas[0].name);
    }
    else
    {
        Debug.Log("Canvas disabled: " + characterCanvas[0].name);
    }
}

And, after pressing the main canvas button, the debuglog says it is enabled, but the button inside the character canvas doesnt appear, and then later i ran another debug in the ‘Update’ function, and it says the canvas is enabled even without pressing this button that is supposed to enable it.
And then i look in the inspector panel, the canvas that i want to change is properly referenced in the array.

Does not do what i want and shows no errors in the log. Dont know what to do (T_T).

Is it possible you have multiple canvases showing at once, and your not clicking on the button you think you are?
In your CharacterTurnReady() function, I don’t see you disabling any canvases. You might need to disable all other canvases, and only enable the one you want

Also, you’re missing a “(” on line 6 of CharacterTurnReady(), so it wouldn’t compile.

If you’re instantiating items at runtime, why do you need CharacterFinder()? Instantiate gives you the reference of what you’ve instantiated.

public List<GameObject> characters;
GameObject characterGO = Instantiate(..);
characters.Add(characterGO);

Why create separate character data arrays (characterAtributes[ ] and characterCanvas)?
A character prefab could have added to each prefab you’ve instantiated:

public class Character : MonoBehaviour
{
   public characterAtributes attributes; //Serialize!
   public Canvas canvas; //Serialize!
}

No need for GetComponent<>

Thank you for your reply!

No, I have one main canvas enabled in the editor, and it has one button that calls that function. The other canvases are disabled in the prefabs by default, and they are instantiated as the objects are instantiated.

Thats because they are disabled by default in the editor before runtime. The game has one canvas enabled, and instantiate 4 objects with canvases as children, disabled before runtime in the prefab.

I must have missed that “(” while copying the code to comment here, but in the script it has the “(”

I havent tried that, i guess i need the objectFind because the instantiation happens at another script, i have one script that spawns the characters based on playerprefs of a previous scene, then another script that is supposed to manage their turns, wich is the script that is not behaving as i want. I will try implementing your code.

One array is for the script inside the instantiated object, they might have different atributes such as different ‘health bars’ so each object has a copy of that script, while the other array is for their canvases, i guess i need one for each.
I need to try implementing this.

Something that I observed, is that, when i press the button that is supposed to enable the canvas that i want, it does a debug log saying that it IS enabled, even tho its not. AND i decided to put the same debuglog in the “Update” function, and it says it is enabled, right after the objects are instantiated, even before i press the button that has the “.enable = true;” in it…

I created a new scene, added nothing more than 2 canvas, one canvas with one button, and another canvas with 2 buttons, one called ‘enable’ and another called ‘disable’.
Then i created a simple script with two simple functions, one that does ‘.disable = true;’ and another that does
‘.disable = false;’ then added a on click event on each button and gave them their functions.

Turns out, that if the canvas is enabled at the Unity Editor before i press ‘Play’ i can enable and disable the first canvas with these buttons, but if the first canvas is disabled before runtime, the ‘enable’ button just doesnt work.

public class NewBehaviourScript : MonoBehaviour
{
    public Canvas fkinCanvas;
    // Start is called before the first frame update
    void Start()
    {
      
    }

    // Update is called once per frame
    void Update()
    {
      
    }

    public void DisableFkinCanvas()
    {
        fkinCanvas.enabled = false;
    }
    public void EnableFkinCanvas()
    {
        fkinCanvas.enabled = true;
    }
}

I can “improvise” and start the game with the canvases enabled before runtime, and then quickly disable them before the player notice much, but its ugly programming. I wish i could properly enable them after runtime. Seems like a Unity flaw imo or maybe i just dont know how to do it.

If you’re asking about UGUI then I’d suggest you use the UGUI sub-forum rather than the generic scripting sub-forum. This is why we have dedicated sub-forums.

I can, of course, move your thread there for you.

Greetings MelvMay!
I assumed the problem was in my scripts, so i thought this would be the place to ask, im not experienced with this community, so, apologies for any mistakes!

You can move the thread to UGUI sub-forum if you think it is the better place, im not sure about the nature of my problem, if its ui or scripting or both. Regardless, i have found an improvised solution, and i doubt anyone will invest in trying to help me with a problem of that is rather more complex than it seems, but that doesnt have any terrible consequences.

Anyways, thank you for your help!!!

1 Like