Updating dynamic variables at Runtime?

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
domopuff
Posts: 25
Joined: Fri May 13, 2022 2:26 am

Updating dynamic variables at Runtime?

Post by domopuff »

Hi there!

Fantastic package but I have a question for my project.

What would be the best way to update a dynamic variable every 0.1 second in this case, PlayerCash, at runtime in the conversation dialogue? This variable is randomized by means of an external C# script.

So when the player checks his account balance, he will find his cash balance updating every 0.1 seconds.
You have[var=PlayerCash] available.

Would appreciate some advice. Thank you!
User avatar
Tony Li
Posts: 21977
Joined: Thu Jul 18, 2013 1:27 pm

Re: Updating dynamic variables at Runtime?

Post by Tony Li »

Hi,

Do you want the subtitle text to update live, so the number visibly ticks up while the player is watching the subtitle? If so, you're going to need to write some code to do that. If you can confirm that this is what you want to do, I can provide some example code here.
domopuff
Posts: 25
Joined: Fri May 13, 2022 2:26 am

Re: Updating dynamic variables at Runtime?

Post by domopuff »

Hi Tony,

That's indeed what I am looking for. Thank you for the help.
User avatar
Tony Li
Posts: 21977
Joined: Thu Jul 18, 2013 1:27 pm

Re: Updating dynamic variables at Runtime?

Post by Tony Li »

One way you can do it is to write a C# method that increments the subtitle text in a coroutine. Here's an example scene:

DS_LiveSubtitleUpdateExample_2022-05-16.unitypackage

It has two scripts. The PlayerCash script just increments a PlayerCash variable:
PlayerCash.cs

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

public class PlayerCash : MonoBehaviour
{
    private void Start()
    {
        InvokeRepeating(nameof(AddCash), 1, 0.1f);
    }

    private void AddCash()
    {
        DialogueLua.SetVariable("PlayerCash", DialogueLua.GetVariable("PlayerCash").asFloat + 1);
    }
}
The LiveUpdateLua script makes a C# method available to Lua. This way you can call it in a dialogue entry's Script field to make that dialogue entry do live updates on a specified frequency:
LiveUpdateLua.cs

Code: Select all

using System.Collections;
using UnityEngine;
using PixelCrushers.DialogueSystem;

public class LiveUpdateLua : MonoBehaviour
{
    private bool doLiveUpdate = false;
    private WaitForSeconds delay;

    private void Awake()
    {
        Lua.RegisterFunction(nameof(LiveUpdate), this, SymbolExtensions.GetMethodInfo(() => LiveUpdate(0)));
    }

    private void OnConversationLine(Subtitle subtitle)
    {
        if (doLiveUpdate)
        {
            StartCoroutine(LiveUpdateCoroutine(subtitle));
        }
        else
        {
            StopAllCoroutines();
        }
    }

    private void OnConversationEnd(Transform actor)
    {
        StopAllCoroutines();
    }

    private void LiveUpdate(double frequency)
    {
        doLiveUpdate = true;
        delay = new WaitForSeconds((float)frequency);
    }

    private IEnumerator LiveUpdateCoroutine(Subtitle subtitle)
    {
        DialogueActor dialogueActor;
        var panel = DialogueManager.standardDialogueUI.conversationUIElements.standardSubtitleControls.GetPanel(subtitle, out dialogueActor);
        while (true)
        {
            panel.subtitleText.text = FormattedText.ParseCode(subtitle.dialogueEntry.currentDialogueText);
            yield return delay;
        }
    }
}
domopuff
Posts: 25
Joined: Fri May 13, 2022 2:26 am

Re: Updating dynamic variables at Runtime?

Post by domopuff »

Hi Tony,

Thanks for this as it works perfectly in the scene. The issue for me is that I have already configured all dialogues to show up as responses instead of subtitles. How can I access the text on the response panels to live update them via a coroutine?
User avatar
Tony Li
Posts: 21977
Joined: Thu Jul 18, 2013 1:27 pm

Re: Updating dynamic variables at Runtime?

Post by Tony Li »

Hi,

You can use OnConversationResponseMenu(Response[]) instead of OnConversationLine. Instead of updating the subtitle panel's subtitleText.text, loop through DialogueManager.standardDialogueUI.defaultMenuPanel.instantiatedButtons (or the buttons property if you're using the Buttons list instead of a template button):
Spoiler

Code: Select all

private void OnConversationLine(Subtitle subtitle)
{
    StopAllCoroutines();
}

private void OnConversationResponseMenu(Response[] responses)
{
    if (doLiveUpdate)
    {
        StartCoroutine(LiveUpdateCoroutine());
    }
    else
    {
        StopAllCoroutines();
    }
}

private IEnumerator LiveUpdateCoroutine()
{
    yield return WaitForEndOfFrame(); // Allow menu to create its buttons first.
    
    // Get the list of response buttons:
    var buttons = new List<StandardUIResponseButton>();
    foreach (GameObject buttonGO in DialogueManager.standardDialogueUI.defaultMenuPanel.instantiatedButtons)
    {
        buttons.Add(buttonGO.GetComponent<StandardUIResponseButton>());
    }
    
    // Keep updating until menu ends.
    while (true)
    {
        foreach (StandardUIResponseButton button in buttons)
        {
            button.label.text = FormattedText.ParseCode(button.response.destinationEntry.currentDialogueText);
            yield return delay;
        }
    }
}
domopuff
Posts: 25
Joined: Fri May 13, 2022 2:26 am

Re: Updating dynamic variables at Runtime?

Post by domopuff »

Thanks for your speedy reply. This worked for me!
User avatar
Tony Li
Posts: 21977
Joined: Thu Jul 18, 2013 1:27 pm

Re: Updating dynamic variables at Runtime?

Post by Tony Li »

Glad to help!
Post Reply