Forum rules - please read before posting.

Inexplicable Button Deactivation

Hi, Chris, Long time no type!
I'm almost done with this project I'm working on, I just need to understand why GameSaveMenu starts with all of it's save slot buttons deactivated. I haven't told it to do that, and have even added a script to override this deactivation, but it still produces the error.

Here's the Error:
https://www.mediafire.com/view/q7sgs6km49wegdb/InactiveGOConsole.png/file

Here's the Action List that called LoadGif() (Even though the name of the Action List is GamePauseMenu_turnOn, I can assure you it is the list that is called when GameSaveMenu is activated):

https://www.mediafire.com/view/kvm6lksdch1cpwb/GameObjectCallingScript.png/file

Here's the Object that called the Script that contained the LoadGif() Command,called "UIGifManager"

Here's an excerpt from the script that attempted to patch the Deactivation bug:
` public void LoadGif(string gifname)
{
ActivateChildren();
LoadGifPlayerList();
Debug.Log("UIGifManager.LoadGif(): gifplayer currently has " + gifplayer.Length + " elements.");
if (gifplayer == null) { Debug.Log("UIGifManager.LoadGif() was called. Couldn't load gifplayer #" + selectedPlayer); }

   gifplayer[selectedPlayer].FileName = gifname;
    AnimatedGifPlayer player = gifplayer[selectedPlayer];
    player.Init();
}
private void LoadGifPlayerList()
{
    gifplayer = GetComponentsInChildren<AnimatedGifPlayer>();
}
private void ActivateChildren()
{
    Button[] button = GetComponentsInChildren<Button>();
    foreach (Button b in button)
    {
        b.gameObject.SetActive(true);
    }
}`

Is it the Adventure Creator Menu Manager deactivating the buttons, somehow, or something else?
Please tell me if there's anything else I can do to help clear up this mystery. Thank you!

Comments

  • edited July 2021

    Short answer: yes. Depending on settings, AC will limit the display of save-game slots to only those that are valid.

    If you check Allow empty slots? in the element's properties, it should then show all slots - at least up to the Maximum nuber of slots? property.

    If this isn't enough to fix things, I would need more context on the add-on you're looking to incorporate. You have a lot of custom scripts attached to your UI prefab, so I'd need to know how you're looking to merge the two system.

  • It looks like the SaveList was set to allow empty slots.

    https://www.mediafire.com/view/4v5h9sc6u1lu63w/SaveListConfiguration.png/file

    The two scripts attached to the Prefab are PrefabGifManager and UIGifManager.
    They help reset the animated gifs I use on the save slot buttons' RawImages (A Button usually comes with an Image, but to make the OldMoatGames' Animated Gif Player work, I have to replace them.)

    PrefabGifManager resets the AnimatedGifPlayer on the UI object its attached to. In hindsight, I probably should have called it something like "PrefabGifResetter", but I thought I was going to expand its functionality at one point.

    UIGifManager provides commands that I can use to manipulate Animated Gifs on UI Menus from the Action List Editor. Here's a screen cap of UIGifManager being used in an Action List:

    https://www.mediafire.com/file/eatu4evw6u0wpk9/UsingUIGifManagerInActionList.png/file

    Here's UIGifManager's script in it's entirety:
    `using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using OldMoatGames;
    using UnityEngine.UI;
    /* How to use:
    Attach to the parent node of any UI object that has children with animated gifs that need
    changing in runtime.

    Pass parent into Call Event Object.
    Make 2 Unity Event() calls: First SelectAnimatedGifPlayer(pickedPlayer).
    The order of the Animated Gifs in the list is determined by their top-down order
    in the parent's hierarchy. Use '0' for the first player, '1' for the second, etc.
    Next is LoadGif(gifName). Write the gif's name, along with ".gif" in the parenthesis.
    Example: LoadGif(Save01Full.gif)
    
    */
    

    public class UIGifManager : MonoBehaviour
    {
    private AnimatedGifPlayer[] gifplayer;
    private int selectedPlayer;

    private void OnEnable()
    {
        ActivateChildren();
        LoadGifPlayerList();
        if (gifplayer == null) {
            Debug.Log("UIGifManager.OnEnable() has been called: No animated" +
            " gif players were found.");
        }
        else
        {
            Debug.Log("UIGifManager.OnEnable() called: " + gifplayer.Length + " AnimatedGifPlayer " +
                "components were found. gifplayer[0].name = "+gifplayer[0].name);
        }
    }
    public void SelectAnimatedGifPlayer(int pickedPlayer)
    {    
        selectedPlayer = pickedPlayer;
        Debug.Log("UIGifManager.SelectAnimatedGifManager() called: selectedPlayer = " + pickedPlayer);
    }
    public void LoadGif(string gifname)
    {
        ActivateChildren();
        LoadGifPlayerList();
        Debug.Log("UIGifManager.LoadGif(): gifplayer currently has " + gifplayer.Length + " elements.");
        if (gifplayer == null) { Debug.Log("UIGifManager.LoadGif() was called. Couldn't load gifplayer #" + selectedPlayer); }
    
       gifplayer[selectedPlayer].FileName = gifname;
        AnimatedGifPlayer player = gifplayer[selectedPlayer];
        player.Init();
    }
    private void LoadGifPlayerList()
    {
        gifplayer = GetComponentsInChildren<AnimatedGifPlayer>();
    }
    private void ActivateChildren()
    {
        Button[] button = GetComponentsInChildren<Button>();
        foreach (Button b in button)
        {
            b.gameObject.SetActive(true);
        }
    }
    

    }`

    And this is all PrefabGifManager really does:
    private void OnEnable() { AnimatedGifPlayer = GetComponent<AnimatedGifPlayer>(); AnimatedGifPlayer.AutoPlay = true; AnimatedGifPlayer.Init(); }

    What I'm trying to do is to have these buttons slide in from off screen displaying their gifs using commands from an Action List, then, when the player exits the save menu, have the buttons slide off screen before closing the menu.

    If I'm forgetting any useful information, please let me know!

  • The main issue I'm seeing is that you're using the Object: Call event Action to update the SaveMenu prefab.

    The issue here is that - at runtime - you'll want to be dealing with the instance of the SaveMenu prefab that's in the scene Hierarchy, and not the original prefab itself. It may be that you're calling the functions correctly, only on the wrong object.

    The Object: Send message Action, by comparison, uses AC's Constant ID system to instead call a prefab instance at runtime.

    Though, when the menu is turned on, it's probably easier to call any initialisation functions through code directly - which it looks like you're already partly doing with the OnEnable functions.

    The best way to trigger code when a menu is turned on is to hook into the OnMenuTurnOn custom event. Attach this script to your prefab's root Canvas for an example on how it's used:

    using UnityEngine;
    using AC;
    
    public class MenuEventExample : MonoBehaviour
    {
    
        private void OnEnable () { EventManager.OnMenuTurnOn += OnMenuTurnOn; }
        private void OnDisable () { EventManager.OnMenuTurnOn -= OnMenuTurnOn; }
    
        private void OnMenuTurnOn (AC.Menu menu, bool isInstant)
        {
            if (menu.RuntimeCanvas == GetComponent<Canvas> ())
            {
                // This menu was turned on
                Debug.Log ("The menu " + menu.title + " was turned on");
            }
        }
    
    }
    

    In terms of the SaveList element's buttons not all showing even though Allow empty slots? is checked, that may be a separate issue. Try duplicating your UI prefab and removing any custom scripts, so that we can try out its behaviour when nothing else is involved. Do the save slots not all show when they should?

  • The Object: Send message Action, by comparison, uses AC's Constant ID system to instead call a prefab instance at runtime.

    What kind of message do I send?
    If you wanted to make a menu with a Unity UI prefab with 3 save slots that slide on screen in a half-second, then when the user presses an "Exit" button in the Unity Prefab menu, then slides all three slots off screen in a half-second before closing, what would you do? Is there a tutorial I could use or something?

    Thank you for helping me through this.

  • What kind of message do I send?

    The message sent should match the name of the C# function you wish to be triggered. This can't take complex parameters - only an optional integer - so it's best used when you only need to call a parameterless function.

    If you wanted to make a menu with a Unity UI prefab with 3 save slots that slide on screen in a half-second, then when the user presses an "Exit" button in the Unity Prefab menu, then slides all three slots off screen in a half-second before closing, what would you do?

    Unity UI menus can have animated transitions, triggered automatically by naming convention when turned on/off. To do this, set the menu's "Transition type" to "Custom Animation" and make sure that the root Canvas has an Animator with the intended animations supplied. See the Manual's "Unity UI menus" chapter for details on what these animations should be.

  • I'm trying to use the Custom Animation transition type.
    https://www.mediafire.com/file/zkq4yx1pgoo62c0/CustomAnimationSelected.png/file

    The other states weren't being implemented in this animation yet; I just wanted to get "On" working. Here's what I did:
    https://www.mediafire.com/file/nvfjmjgw6y11vpw/StateOfOn.png/file

    Transitions of the three states:

    Default to On
    https://www.mediafire.com/file/wlij5hrv5e0cifr/Default+To+On.png/file

    On to Mark As Done
    https://www.mediafire.com/file/qv3fpm3ulur33mh/On+To+Mark+As+Done.png/file

    Mark As Done to Default
    https://www.mediafire.com/file/hde0f3d81utll0i/Mark+As+Done+To+Default.png/file

    Mark As Done calls a script
    https://www.mediafire.com/file/20x5ixr5i49uoyd/Mark+As+Done+Calls+A+Script.png/file

    This is the script I added to the "Mark As Done" state:
    `public class MarkAsDone : StateMachineBehaviour
    {
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
    // Set the animation parameter "done" to true.
    animator.SetBool("done", true);
    Debug.Log("MarkAsDone.OnStateEnter(): done parameter set to true.");
    }

    }`

    Nothing crashes, but the menu just blinks in. What do I do?

    Thank you for your help, Chris!

  • I'm not following the purpose of your Mark As Done script / Done parameter. For now, just give the Controller the 4 states that AC requires, without transitions.

    Then, view the canvas's live Animator window at runtime at the moment the menu turns on - which animation gets called?

  • Then, view the canvas's live Animator window at runtime at the moment the menu turns on - which animation gets called?

    As far as I can tell, none of them.
    https://www.mediafire.com/file/x2go0ljjgdtmx50/Called+Animation.png/file

    The Animator wouldn't let me delete the transition that connects Entry to On. I'm guessing AC manages transitions in-engine? Are the states all supposed to be empty?

  • The Entry -> On transition is a requirement of the Animator Controller - it's just Unity's way of visualising which is the default animation. At runtime, though, AC should handle the transitions automatically.

    Where on your canvas prefab is the Animator placed, though? For it to be used by AC, it must be on the root - otherwise, you can rely on custom scripting / hooking into the OnMenuTurnOn custom event to trigger your animations manually.

  • Where on your canvas prefab is the Animator placed, though? For it to be used by AC, it must be on the root

    Well, that's a good start, it wasn't the root object. It used to be, but since it had a canvas, I made it the child of an object with only a Rect Transform so I could use the new parent for the Recttransform boundary field.

    I put the Animator on the parent node, and tried to animate it, but the children don't respond to the parent's movements.

    What do I do? Thank you for seeing me though this.

  • edited August 2021

    An Animator is able to control any children in its Hierarchy - you should be able to control the position of any RectTransforms in the prefab, if the Animator is on the root.

    Which object(s) are you trying to animate, and how, when the menu turns on? Any screenshots you can share that help explain the situation will help.

    Are you saying that the children don't respond at runtime, or you're having trouble creating the animations themselves?

    This may be more of a Unity question/issue, but share screenshots and I'll try to see what's what.

  • Which object(s) are you trying to animate, and how, when the menu turns on? Any screenshots you can share that help explain the situation will help.

    Well, I'm trying to have the menu's save slots slide in and off screen, and all the other components fade in and out when activated/deactivated, but if that's not possible, I'll just slide the whole thing, in/out.

    Are you saying that the children don't respond at runtime, or you're having trouble creating the animations themselves?

    The first one.

    Here is my Save Menu, in all of it's majesty:
    https://www.mediafire.com/file/83qp75d277vz7ww/SaveMenuHierarchy.png/file

    Here I am sliding the parent object away during an animation recording, the children seemingly oblivious:
    https://www.mediafire.com/file/d5ldqp4yfd4c79t/ParentGoesChildrenStay.png/file

    Thank you again!

  • None of the objects have Layout Elements, if that's important.

  • You can't reposition the root RectTransform of a Canvas - only its children.

    To move the whole menu, you need to instead animate the position of its immediate child - SaveMenuCanvas in your case.

    If you only want to have the save slots slide in, though, then you'll instead want to move an object that is only a parent of your SaveSlot objects. To do this, add a new empty GameObject to your SaveMenuCanvas, and then parent your three SaveSlot objects to it. As part of the menu's "On" animation, you can then animate the position of this new empty to have the slots slide into view - and then also animate anything else you need, e.g. fade in the other components.

    A quick way to fade UI components in and out is to attach a Canvas Group component, and then animate its Alpha property.

  • Thanks for the Canvas Group advice; these really are handy!
    The animation problems are starting to clear up, that just leaves the custom messages.

    Here's an example of me trying to use a custom message that calls a method in a script component in SaveMenu called UIGifManager:
    https://www.mediafire.com/file/ht7cdkm8q7qur52/CustomMessage.png/file

    The full name of the method is SelectAnimatedGifPlayer and it has one integer argument.

    public void SelectAnimatedGifPlayer(int pickedPlayer) { selectedPlayer = pickedPlayer; Debug.Log("UIGifManager.SelectAnimatedGifManager() called: selectedPlayer = " + pickedPlayer); }

    The Debug.Log entry never appears in the Console.
    What should I do next?

  • The "ActionList when turn on" asset is actually run just before the UI is enabled. Try this modified version of the MenuEventExample script that's attached in your screenshot:

    using UnityEngine;
    using AC;
    
    public class MenuEventExample : MonoBehaviour
    {
    
        public Canvas canvas;
    
        private void OnEnable () { EventManager.OnMenuTurnOn += OnMenuTurnOn; }
        private void OnDisable () { EventManager.OnMenuTurnOn -= OnMenuTurnOn; }
    
        private void OnMenuTurnOn (AC.Menu menu, bool isInstant)
        {
            if (menu.RuntimeCanvas == canvas)
            {
                // This menu was turned on
                Debug.Log ("The menu " + menu.title + " was turned on");
                GetComponent<UIGifManager> ().SelectAnimatedGifPlayer (0);
            }
        }
    
    }
    

    You may need to add a namespace if your UIGifManager uses one.

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.