Forum rules - please read before posting.

Setting Naninovel Variable Action Bugs Menu

I've created a custom action in order to set variables in Naninovel. However, it seems that whenever I run the action, strange things happen such as menu buttons stop working or don't show as pressed. Is there something wrong with my code? I've used the Naninovel integration script as reference.

`
using UnityEngine;
using Naninovel;

if UNITY_EDITOR

using UnityEditor;

endif

namespace AC
{

public enum VarType { Integer, Float, String };
public enum SetMethod { SetValue, Variable };
public enum VarLocation { Global, Local };

[System.Serializable]
public class ActionNaninovelVarSet : Action
{

    // Declare properties here
    public override ActionCategory Category { get { return ActionCategory.Custom; }}
    public override string Title { get { return "Set Naninovel Variable"; }}
    public override string Description { get { return "Initialize Naninovel engine (if necessary) and set a variable in Naninovel"; }}


    // Declare variables here

    public string variableName = string.Empty;
    public VarType variableType = VarType.Integer;
    public SetMethod setVarMethod = SetMethod.SetValue;
    public string value = string.Empty;
    public VarLocation location = VarLocation.Global;
    public string ACVariableName = string.Empty;

    private bool asyncCompleted;

    public override float Run ()
    {
        /* 
         * This function is called when the action is performed.
         * 
         * The float to return is the time that the game
         * should wait before moving on to the next action.
         * Return 0f to make the action instantenous.
         * 
         * For actions that take longer than one frame,
         * you can return "defaultPauseTime" to make the game
         * re-run this function a short time later. You can
         * use the isRunning boolean to check if the action is
         * being run for the first time, eg: 
         */

        if (!isRunning)
        {
            asyncCompleted = false;
            isRunning = true;
            RunAsync();
        }
        else if (asyncCompleted)
        {
            isRunning = false;
            return 0f;
        }

        return defaultPauseTime;
    }


    public override void Skip ()
    {
        /*
         * This function is called when the Action is skipped, as a
         * result of the player invoking the "EndCutscene" input.
         * 
         * It should perform the instructions of the Action instantly -
         * regardless of whether or not the Action itself has been run
         * normally yet.  If this method is left blank, then skipping
         * the Action will have no effect.  If this method is removed,
         * or if the Run() method call is left below, then skipping the
         * Action will cause it to run itself as normal.
         */

         Run ();
    }


    #if UNITY_EDITOR

    public override void ShowGUI ()
    {
        // Action-specific Inspector GUI code here
        variableName = EditorGUILayout.TextField(new GUIContent("Variable Name:", "Name of the Naninovel variable to set"), variableName);
        variableType = (VarType) EditorGUILayout.EnumPopup("Variable Type:", variableType);
        setVarMethod = (SetMethod) EditorGUILayout.EnumPopup("Set Method:", setVarMethod);

        if (setVarMethod == SetMethod.SetValue) {
            value = EditorGUILayout.TextField(new GUIContent("Value:", "Value of the Naninovel variable"), value);
        }
        else {
            location = (VarLocation) EditorGUILayout.EnumPopup ("Source:", location);
            ACVariableName = EditorGUILayout.TextField(new GUIContent("AC Variable Name:", "Name of an Adventure Creator Variable"), ACVariableName);
        }
    }

    #endif

    private async void RunAsync () {
        if (string.IsNullOrWhiteSpace(variableName))
        {
            Debug.LogError("Can't set Naninovel variable from AC action: variable name is not specified.");
            asyncCompleted = true;
            return;
        }

        if (!Engine.Initialized)
            await RuntimeInitializer.InitializeAsync();

        var variableManager = Engine.GetService<ICustomVariableManager>();
        GVar myVariable;

        if (setVarMethod == SetMethod.Variable) {
            if (location == VarLocation.Global)
                myVariable = AC.GlobalVariables.GetVariable(ACVariableName);
            else
                myVariable = AC.LocalVariables.GetVariable(ACVariableName);

            value = myVariable.GetValue();
        }

        switch (variableType) {
            case VarType.Integer:
                variableManager.TrySetVariableValue<int>(variableName, int.Parse(value));
                break;
            case VarType.Float:
                variableManager.TrySetVariableValue<float>(variableName, float.Parse(value));
                break;
            case VarType.String:
                variableManager.TrySetVariableValue<string>(variableName, value);
                break;
        }

        asyncCompleted = true;
    }
}

}
`

Comments

  • Welcome to the community, @centurions90.

    If the Action is run from an ActionList that blocks gameplay (i.e. its When running property is set to Block Gameplay), then regular gameplay menus - such as the default "Menu" button in the lower-left corner - will be hidden while it runs.

    If they remain hidden, it sounds like the Action is running indefinitely.

    Your Run function looks OK, so it may be a case of the asyncCompleted = true; line not being reached.

    In general, I'd recommend avoiding the use of the async keyword in Actions - and instead make sure that the InitializeAsync function has been called beforehand.

    Here's an alternative that should do the same thing but without the async keyword - does this work?

    using UnityEngine;
    using Naninovel;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    namespace AC
    {
    
        public enum VarType { Integer, Float, String };
        public enum SetMethod { SetValue, Variable };
        public enum VarLocation { Global, Local };
    
        [System.Serializable]
        public class ActionNaninovelVarSet : Action
        {
    
            public override ActionCategory Category { get { return ActionCategory.Custom; }}
            public override string Title { get { return "Set Naninovel Variable"; }}
            public override string Description { get { return "Initialize Naninovel engine (if necessary) and set a variable in Naninovel"; }}
    
    
            public string variableName = string.Empty;
            public VarType variableType = VarType.Integer;
            public SetMethod setVarMethod = SetMethod.SetValue;
            public string value = string.Empty;
            public VarLocation location = VarLocation.Global;
            public string ACVariableName = string.Empty;
    
            public override float Run ()
            {
                if (!isRunning)
                {
                    if (Engine.Initialized)
                    {
                        RunAsync ();
                        return 0f;
                    }
                    else
                    {
                        RuntimeInitializer.InitializeAsync();
                        isRunning = true;
                        return defaultPauseTime;
                    }
                }
                else if (Engine.Initialized)
                {
                    RunAsync ();
                    isRunning = false;
                    return 0f;
                }
    
                return defaultPauseTime;
            }
    
    
            public override void Skip ()
            {
                Run ();
            }
    
    
            #if UNITY_EDITOR
    
            public override void ShowGUI ()
            {
                variableName = EditorGUILayout.TextField(new GUIContent("Variable Name:", "Name of the Naninovel variable to set"), variableName);
                variableType = (VarType) EditorGUILayout.EnumPopup("Variable Type:", variableType);
                setVarMethod = (SetMethod) EditorGUILayout.EnumPopup("Set Method:", setVarMethod);
    
                if (setVarMethod == SetMethod.SetValue)
                {
                    value = EditorGUILayout.TextField(new GUIContent("Value:", "Value of the Naninovel variable"), value);
                }
                else
                {
                    location = (VarLocation) EditorGUILayout.EnumPopup ("Source:", location);
                    ACVariableName = EditorGUILayout.TextField(new GUIContent("AC Variable Name:", "Name of an Adventure Creator Variable"), ACVariableName);
                }
            }
    
            #endif
    
            private void RunAsync () 
            {
                if (string.IsNullOrWhiteSpace(variableName))
                {
                    Debug.LogError("Can't set Naninovel variable from AC action: variable name is not specified.");
                    return;
                }
    
                var variableManager = Engine.GetService<ICustomVariableManager>();
                GVar myVariable;
    
                if (setVarMethod == SetMethod.Variable)
                {
                    if (location == VarLocation.Global)
                        myVariable = AC.GlobalVariables.GetVariable(ACVariableName);
                    else
                        myVariable = AC.LocalVariables.GetVariable(ACVariableName);
    
                    value = myVariable.GetValue();
                }
    
                switch (variableType)
                {
                    case VarType.Integer:
                        variableManager.TrySetVariableValue<int>(variableName, int.Parse(value));
                        break;
                    case VarType.Float:
                        variableManager.TrySetVariableValue<float>(variableName, float.Parse(value));
                        break;
                    case VarType.String:
                        variableManager.TrySetVariableValue<string>(variableName, value);
                        break;
                }
            }
        }
    
    }
    

    If not, it may be a case of Engine.Initialized not returning true. Placing Debug.Log statements inside the Run function should help determine if this is the case or not.

  • Ah, thank you very much @ChrisIceBox.
    Although I'm still experiencing the same problem, your comment helped me pin down the issue to being Naninovel related.

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.