Forum rules - please read before posting.

Changing Menu Label Text Color During Runtime With Action List

All right... so I've a Menu which is Unity UI Prefab.
I've a Text linked to the Menu as "Label" component (which I activate/deactivate through Action List Hide/Show Menu Element).
What I need to do is also changing the color of that Text with an Action List (to call on a different moment... basically, a first action list is showing the text, then if I do something right, that text changes color, still through actionlist in runtime).
I've noticed there's nothing like that under the Menu action lists, so I wrote a simple custom script and I thought to call the function via Object/Event in the Action List, but it's not working (can't drop my UI Text into the "Object" of the Action List/Call Event).
A long option could be to duplicate the text, one for each color, then Hide/Show the one that I'd like, but this mean having lot of objects/actions which I prefer to avoid.
So I guess the best way is to write a custom AC Action... I've wrote some, but I'm not sure how to get and set the Text color of a Label as Menu Element...
Is that even possible?

Comments

  • If using a custom script, trigger it with the Object: Send message Action - not Object: Call event. The latter will always affect the object you assign (i.e. the UI prefab), while the former can affect the runtime instance of it (provided it has a Constant ID with Retain in prefab? checked).

    A custom Action is also viable, but AC doesn't control the appearance of a Unity UI text-box - only it's text contents. You can, however, reference its name as set in the Menu Manager to access its Unity UI counterpart:

    MenuLabel myLabel = PlayerMenus.GetElementWithName ("MyMenu", "MyLabel") as MenuLabel;
    myLabel.uiText.color = Color.green;
    

    It's also possible to achieve this without code - by instead relying on animation. An Animator attached to your Text box can have two animation states that each tint the colour. Create a transition between them based on a Bool animator parameter, and you can then use the Object: Animate Action to control it.

  • edited September 2020

    All the methods that consider "Object" is not working on my end (being a Call Event, Send message or Animate), because the Object (my UI text) is inside a Unity UI Prefab (handled by AC as menu). So it cannot find the Object... Unless I put the prefab in every scene or something like that, which is not elegant (and not even sure it works)... Am I doing something wrong? Is there something silly I'm not considering? (the object has a Constant ID already). I can't do that using as object the whole UI prefab, because then I'm not sure how to call the method on a single child and not on all children.

    That's why I thought to call that Menu Element (Label) via custom AC script, assigning which one as I usually do with "Hide/Show Menu Element" from the Menu Action List.

    So the custom action should be something like the Menu / Change State, but becoming Menu / Change Color (I can set a fixed color, no need to set it al the time on the action list editor), which gives me two fields to fill:
    Menu containing element:
    Element to color:

    Basically what I was trying is to do, was copy-pasting the "ActionMenuState" and change few lines here and there to set the color... But it's giving me headaches!

    Your line of script alone I guess is not exactly what I was looking for, since the "MyMenu" and "MyLabel" should be filled in the Custon ActionList as "Menu" and "Menu Element".

    This is what I've got so far... (it's working, but not sure if it's the right thing)
    CODE

    Will dig more...

  • edited December 2020
    using UnityEngine;
    using System.Collections.Generic;
    
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
    
        [System.Serializable]
        public class ActionMenuElementColor : Action
        {
    
            public string menuToChange = "";
            public int menuToChangeParameterID = -1;
    
            public string elementToChange = "";
            public int elementToChangeParameterID = -1;
    
            protected LocalVariables localVariables;
            protected string runtimeMenuToChange, runtimeElementToChange;
    
            public Color color;
    
    
            public ActionMenuElementColor()
            {
                this.isDisplayed = true;
                category = ActionCategory.Custom;
                title = "Change Color";
                description = "Change Color of a label";
            }
    
    
            public override void AssignParentList(ActionList actionList)
            {
                if (actionList != null)
                {
                    localVariables = UnityVersionHandler.GetLocalVariablesOfGameObject(actionList.gameObject);
                }
                if (localVariables == null)
                {
                    localVariables = KickStarter.localVariables;
                }
    
                base.AssignParentList(actionList);
            }
    
    
            public override void AssignValues(List<ActionParameter> parameters)
            {
                menuToChange = AssignString(parameters, menuToChangeParameterID, menuToChange);
                elementToChange = AssignString(parameters, elementToChangeParameterID, elementToChange);
    
                runtimeMenuToChange = AdvGame.ConvertTokens(menuToChange, Options.GetLanguage(), localVariables, parameters);
                runtimeElementToChange = AdvGame.ConvertTokens(elementToChange, Options.GetLanguage(), localVariables, parameters);
            }
    
    
            public override float Run()
            {
                MenuLabel myLabel = PlayerMenus.GetElementWithName(runtimeMenuToChange, runtimeElementToChange) as MenuLabel;
                myLabel.uiText.color = color;
                myLabel.fontColor = color;
                return 0f;
            }
    
    
            #if UNITY_EDITOR
    
            public override void ShowGUI(List<ActionParameter> parameters)
            {
                menuToChangeParameterID = Action.ChooseParameterGUI("Menu containing element:", parameters, menuToChangeParameterID, ParameterType.String);
                if (menuToChangeParameterID < 0)
                {
                    menuToChange = EditorGUILayout.TextField("Menu containing element:", menuToChange);
                }
    
                elementToChangeParameterID = Action.ChooseParameterGUI("Label to color:", parameters, elementToChangeParameterID, ParameterType.String);
                if (elementToChangeParameterID < 0)
                {
                    elementToChange = EditorGUILayout.TextField("Label to color:", elementToChange);
                }
    
                color = EditorGUILayout.ColorField ("Color:", color);
    
                AfterRunningOption();
            }
    
            #endif
    
        }
    
    }
    
  • Awesome! The best support ever (as always)!

  • Ok... issue... the color is not saved... How can I achieve that?

  • Since you're using Unity UI, you can attach a custom Remember component to save its color value.

    See this tutorial for details on the process.

    Altenatively, if you changed the colour of UI components through animation (attach an Animator, create parameters that trigger transitions to different colours), you could use AC's Object: Animate Action and Remember Animator component to change/save the colour state.

  • edited November 2020

    All right... I'm trying... but I'm getting some headache to save/load the color... I guess I need to transform it as a string...?

  • P.S. that "RememberLight" script gives me errors... maybe it's not updated?

  • P.P.S. if I attach the script to a text component of my UI, it's not called.

  • edited November 2020

    This is my final script... So, yeah, the one in the tutorial contains some errors. I've split the color into 4 floats and I guess it should work. So forget the part about string...
    However, the issue now is about the script not being called during my save, maybe because the UI element it is attached to is not on scene? I'm not sure... Can you help me with that? My menu is an UI prefab, which contains different texts, each has its own ID and are correctly attached to the Menu elements in AC. Everything works perfectly (it saves which label is shown, which not, etc.), but doesn't save the color...

  • Looks like there's a display issue on the tutorial page, preventing the code from displaying correctly - I'll look into this, thanks.

    For your own script: Remember scripts on persistent objects (i.e. in the DontDestroyOnLoad scene) should save as global data, but the object needs to be enabled. If the Menu is not on at the time of saving, it won't be called.

    What you'll need to do, in that case, is move the component to a persistent object that is on, and have it reference the Text component by some other means.

    What's the context here? How many such components are you looking to save, and are they all sharing the same modified colour?

  • edited November 2020

    Basically it's a "tracker" of tasks.
    It's a Menu that slides in when pressing a button (or input) in the Main UI and has a list of the current missions.
    The full game has about 50 tasks. Each is a Label (Menu Element of Missions Tracker Menu).
    When a task is given, I turn on the Menu Element which contains it.
    When a task is accomplished, I change the color to green.
    When a task is half way (i.e. collect 2/3 big rocks), I change the color to orange.
    When I'm on a different part of the game, I hide some.
    All work great, except saving the color.
    I didn't went for using "AC Objectives", because for some reasons just relying on a custom Menu was better for me (my tasks are very different each other and not really "objectives").

    The problem is that during Autosave the UI menus are hidden. Same happens when I go to Save menu. Therefore my "Missions Tracker" Menu is always off during save (to not have the tasks list on the save screenshot).

    I'm not sure I understand what do you mean with: "What you'll need to do, in that case, is move the component to a persistent object that is on, and have it reference the Text component by some other means."

    P.S. the RememberLight tutorial is not only displayed wrongly, but contains obsolete coding.

  • I'm not sure I understand what do you mean with: "What you'll need to do, in that case, is move the component to a persistent object that is on, and have it reference the Text component by some other means."

    Never mind. In the next update, I will allow disabled Menus to save Remember data.

    the RememberLight tutorial is not only displayed wrongly, but contains obsolete coding.

    I have since updated the tutorial. If you still have an issue, please share specific details.

  • Hi all, so just to confirm, the only way to change menu text colour during gameplay is with a custom script? It would be great to have a visual scripting option for this, but I'm assuming the answer may be to just use the unity menu system.

  • The script above provides the ability to do so in an Action, but see also my first reply in this thread - if your Menu is rendered with Unity UI, it's possible to control any property, colour included, using Animation.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.