Page 1 of 1

A public variable as a quest state condition

Posted: Sat Jul 20, 2024 2:10 pm
by mel
Hello,

I've been using Dialogue System for Unity paired with Quest Machine. I generally trigger quest progress via dialogue or using a simple custom script to send a message based on certain Usable behavior. My current challenge is that I want to set up a quest state condition so that it progresses to the next stage based on the value of a public variable(s), rather than a Lua variable. I have a game manager in my scene, and when it has certain values (ie stats are at a particular threshold), I need to progress the quest to the next stage. I've had a look through the docs and quest machine components but not sure how I'd go about this sort of thing - are you able to help point me in the right direction? I know the message system is a possible option, but keen to know if there are more direct or optimal ways.

Thank you.

Re: A public variable as a quest state condition

Posted: Sat Jul 20, 2024 4:29 pm
by Tony Li
Hi,

I recommend making your variable into a property. For example, instead of a "gold" variable:

Code: Select all

public int gold;
you could define a "gold" property with a private backing variable:

Code: Select all

private int _gold;
public int gold
{
    get { return _gold; }
    set { _gold = value; }
}
Then say your Quest Machine quest has a quest node that triggers when the player's "gold" value exceeds 1000. (Maybe the tax man comes or something.) In this case, you can tell that quest node to listen for a message such as "Is Wealthy". Then extend the property like this:

Code: Select all

private int _gold;
public int gold
{
    get { return _gold; }
    set 
    {
        _gold = value;
        if (value > 1000) MessageSystem.SendMessage(this, "Is Wealthy", "");
    }
}
----------

Or, if you want to handle it in a more general-purpose way, you can add a C# event to the "gold" property instead:

Code: Select all

public event System.Action<int> GoldChanged;

private int _gold;
public int gold
{
    get { return _gold; }
    set 
    {
        _gold = value;
        GoldChanged?.Invoke(value);
    }
}
Then you can write separate code that hooks into the GoldChanged event, such as:

Code: Select all

// This script listens for changes to the gold property.
void OnEnable() { GoldChanged += OnGoldChanged; }
void OnDisable() { GoldChanged -= OnGoldChanged; }

void OnGoldChanged(int value)
{
    if (value > 1000) MessageSystem.SendMessage(this, "Is Wealthy", "");
}
This way you're separating the quest specifics from the implementation of the gold property.