Enabling script on seperate object on variable check

Announcements, support questions, and discussion for the Dialogue System.
Trashrat
Posts: 25
Joined: Fri Oct 13, 2023 11:38 am

Enabling script on seperate object on variable check

Post by Trashrat »

Hi there,

I have an outline script that runs on gameobjects that I want to show as interactable, and sometimes items are only interactable after certain conditions have been met. How would I enable a script, say "Enable Outline" on an object, based on the condition of a dialogue manager variable?

Thank you
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: Enabling script on seperate object on variable check

Post by Tony Li »

Hi,

To check a Dialogue System variable value in C#, use DialogueLua.GetVariable().

You can also monitor the value of a variable.
Trashrat
Posts: 25
Joined: Fri Oct 13, 2023 11:38 am

Re: Enabling script on seperate object on variable check

Post by Trashrat »

Thank Tony, I seem to have something working now. I only worry if the way I have this is unoptimal. I

Code: Select all

public class EnableOutline : MonoBehaviour
{
    Outline outline;
    [SerializeField] private bool canShowOutline = true;
    [SerializeField] private string variableName = "";
    [SerializeField] bool booleanToggle = false;


    private void Awake()
    {
        if (!TryGetComponent(out outline)) return;
        //outline = gameObject.GetComponent<Outline>();
        outline.enabled = false;
    }

    // Start is called before the first frame update
    void Start()
    {
 
    }

    // Update is called once per frame
    void Update()
    {
        canShowOutline = PixelCrushers.DialogueSystem.DialogueLua.GetVariable(variableName).asBool;
        if (!outline) return;

        if(variableName == "")
        {
            outline.enabled = Input.GetKey(KeyCode.Tab);
        }
        else if(canShowOutline != booleanToggle)
        {
            outline.enabled = Input.GetKey(KeyCode.Tab);
        }
        
    }
}
I couldn't quite figure out how to monitor for a variable change.

Thank you
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: Enabling script on seperate object on variable check

Post by Tony Li »

Here's an example of how to monitor a variable:

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

public class EnableOutline : MonoBehaviour
{
    [VariablePopup(true)][SerializeField] private string variableName = "";

    void Start()
    {
        Language.Lua.Assignment.MonitoredVariables.Add(variableName);
        Language.Lua.Assignment.VariableChanged += OnVariableChanged;
    }

    void OnDestroy()
    {
        Language.Lua.Assignment.VariableChanged -= OnVariableChanged;
        Language.Lua.Assignment.MonitoredVariables.Remove(variableName);
    }

    void OnVariableChanged(string variableThatChanged, object newValue)
    {
        if (variableThatChanged == variableName)
        {
            var boolValue = (bool)newValue;
            Debug.Log($"{variableName} changed to {boolValue}");
        }
    }
}
I also added the [VariablePopup] attribute so you can choose the variable from a dropdown instead of typing it manually.
Trashrat
Posts: 25
Joined: Fri Oct 13, 2023 11:38 am

Re: Enabling script on seperate object on variable check

Post by Trashrat »

Hi Tony, that's fantastic, and thank you so much for your help. Unfortunately I am getting a "Assignment does not contain a definiation for" error on both Monitored Variables and Variable Changes. The Assignment class in my folder only seems to have a methodnamed Execute and SetKeyValue.

Thanks again
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: Enabling script on seperate object on variable check

Post by Tony Li »

Hi,

Are you using an old version of the Dialogue System? Would it be possible for you to back up your project and update to the current version? The release notes are here.
Trashrat
Posts: 25
Joined: Fri Oct 13, 2023 11:38 am

Re: Enabling script on seperate object on variable check

Post by Trashrat »

You're right, that was absolutely the probelm there. Now all updated and that seems to be ok. Unfortunately OnVariableChanged doesn't seem to be getting called at any point and I can't currently understand why. It may have something to do with how my outline script is being used, as it currenlty sits on each object that will have an outline.

Thank you
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: Enabling script on seperate object on variable check

Post by Tony Li »

Hi,

Try adding some Debug.Log lines -- for example, when you hook into Language.Lua.Assignment.VariableChanged (+=) and unhook (-=) and when OnVariableChanged is called in case some condition in OnVariableChanged is causing it to exit out early.
Trashrat
Posts: 25
Joined: Fri Oct 13, 2023 11:38 am

Re: Enabling script on seperate object on variable check

Post by Trashrat »

Hi Tony,

Unfortunately it all seems to be working fine when adding the variables and when removing them on destroy; it's just that OnVariableChanged isn't getting called. i'm assuming this would happen when there is a change in the variable?

I have included my code below, as well as the relevant section of my Assignment class just incase:

Code: Select all

public class EnableOutline : MonoBehaviour
{
    Outline outline;

    [VariablePopup(true)][SerializeField] private string variableName = "";
    
    private void Awake()
    {
        if (!TryGetComponent(out outline)) return;
        outline.enabled = false;
    }

    void OnEnable()
    {
        if(variableName != "")
        {
            Language.Lua.Assignment.MonitoredVariables.Add(variableName);
            Language.Lua.Assignment.VariableChanged += OnVariableChanged;
        } 
    }

    void OnDestroy()
    {
        if(variableName != "")
        {
            Language.Lua.Assignment.VariableChanged -= OnVariableChanged;
            Language.Lua.Assignment.MonitoredVariables.Remove(variableName);
        }
    }

    void OnVariableChanged(string variableThatChanged, object newValue)
    {
        Debug.Log(variableName);
        if (variableThatChanged == variableName)
        {
            var boolValue = (bool)newValue;
            Debug.Log($"{variableName} changed to {boolValue}");
        }
    }

    void Update()
    {
        if (!outline) return;
        outline.enabled = Input.GetKey(KeyCode.Tab);
    }
}

Code: Select all

// [PixelCrushers] Supports monitoring of variable changes:
// Local variable assignments take the form: x = 3
public static HashSet<string> MonitoredLocalVariables = new HashSet<string>();
public static System.Action<string, object> LocalVariableChanged = null;
// Variable assignments are in the Variable[] table: Variable["x"] = 3
public static HashSet<string> MonitoredVariables = new HashSet<string>();
public static System.Action<string, object> VariableChanged = null;
private static LuaValue VariableTableToMonitor = null;

public static void InitializeVariableMonitoring()
{
    MonitoredLocalVariables = new HashSet<string>();
    LocalVariableChanged = null;
    MonitoredVariables = new HashSet<string>();
    VariableChanged = null;
    VariableTableToMonitor = null;
}

public static void InvokeVariableChanged(string variable, object value)
{
    VariableChanged?.Invoke(variable, value);
}
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: Enabling script on seperate object on variable check

Post by Tony Li »

Hi,

How are you changing the variable?
Post Reply