Page 1 of 1

How To: Get Notifications When DS Variables Change

Posted: Tue Mar 24, 2020 10:34 am
by Tony Li
A frequently asked question is: How can I be notified when a Dialogue System Lua variable changes?

The Condition Observer component provides a scripting-free, general purpose way to check any Dialogue System state, including variable changes. However, it uses polling, which means it checks the variable on a frequency that you've specified, whether the variable has actually changed or not. This isn't optimally efficient. If you're up for a tiny bit of scripting, here are some other suggestions:

When a C# variable changes, there are no built-in notifications either. However, in C# you can set up notifications by using a property:

Code: Select all

private int myVariable;
public int MyProperty
{
    get
    { 
        return myVariable;
    }
    set
    {
        myVariable = value;
        Debug.Log("MyProperty changed!"); //<-- Notification here.
    }
}
You can do the same for a Dialogue System variable in C#. Here's an example of setting up a property for a Dialogue System variable Variable["Enemies"]:

Code: Select all

public int Enemies
{
    get
    {
        return DialogueLua.GetVariable("Enemies").asInt;
    }
    set
    {
        DialogueLua.SetVariable("Enemies", value);
        Debug.Log("Enemies changed!"); //<-- Notification here.
    }
}
However, that doesn't cover the case if you change the variable in Lua itself, such as in a dialogue entry node's Script field:
  • Script: Variable["Enemies"] = Variable["Enemies"] + 1
C# properties use get and set methods. Lua doesn't have properties. But you can still write get and set C# methods for Lua variables, such as:

Code: Select all

int GetEnemies()
{
    return DialogueLua.GetVariable("Enemies").asInt;
}

void SetEnemies(double value)
{
        DialogueLua.SetVariable("Enemies", value);
        Debug.Log("Enemies changed!"); //<-- Notification here.
}
Then register these C# methods with Lua:

Code: Select all

Lua.RegisterFunction("GetEnemies", this, SymbolExtensions.GetMethodInfo(() => GetEnemies()));
Lua.RegisterFunction("SetEnemies", this, SymbolExtensions.GetMethodInfo(() => SetEnemies((double)0)));
(Side note: Lua uses doubles for all numbers, which is why the SetEnemies method passes a double.)

Then you can use GetEnemies() and SetEnemies() in your Script fields:
  • Script: SetEnemies(GetEnemies() + 1))

Alternatively, you could write a more general purpose method to get and set any int variable:

Code: Select all

int GetIntVar(string variableName)
{
    return DialogueLua.GetVariable(variableName).asInt;
}

void SetIntVar(string variableName, double value)
{
        DialogueLua.SetVariable(variableName, value);
        Debug.Log(variableName + " changed!"); //<-- Notification here.
}
Then your Script field might look like:
  • Script: SetIntVar("Enemies", GetIntVar("Enemies") + 1))
Or, if you prefer:
  • Script: SetIntVar("Enemies", Variable["Enemies"] + 1))