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;
using UnityEditor;
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;
}
}
}
`
It looks like you're new here. If you want to get involved, click one of these buttons!
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?
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.