Page 1 of 1

[HOWTO] How To Run UnityEvents On Quest State Change

Posted: Wed Mar 17, 2021 9:01 am
by Tony Li
Here are three general purpose ways to run UnityEvents when a quest state changes outside of a conversation. The first two are similar, so I've grouped them together

1 & 2. Add a Dialogue System Events component, or a script with an OnQuestStateChange() method, to the Dialogue Manager. If you use Dialogue System Events, add a script with a method that you can hook up to the OnQuestStateChange() UnityEvent. In the method, check the quest state and do something. For example, the script might look like this:
QuestStateEvents.cs

Code: Select all

// Uses built-in OnQuestStateChanged() method.

using System;
using UnityEngine;
using PixelCrushers.DialogueSystem;

[Serializable]
public class QuestEvents
{
    [QuestPopup] public string requiredQuestName;
    public UnityEvent onAccepted;
    public UnityEvent onCompleted;
}

public class QuestStateEvents : MonoBehaviour
{
    public QuestEvents[] questEvents;

    void OnQuestStateChange(string questName)
    {
        QuestState state = QuestLog.GetQuestState(questName);
        foreach (QuestEvents questEvent in questEvents)
        {
            if (questEvent.requiredQuestName == questName)
            {
                if (state == QuestState.Active) questEvent.onAccepted.Invoke();
                else if (quest == QuestState.Success) questEvent.onCompleted.Invoke();
            }
        }
    }
}

3. Or you can assign a replacement method to QuestLog.SetQuestStateOverride. Your replacement can call the default method and then do extra work. Example:
Spoiler

Code: Select all

QuestLog.SetQuestStateOverride = CustomSetQuestState;

void CustomSetQuestState(string questName, string stateString)
{
    QuestLog.DefaultSetQuestState(questName, stateString);
    QuestState state = QuestLog.StringToState(stateString);
    if (state == QuestState.Active) // do something
    else if (state == QuestState.Success) // do something else
}