Page 1 of 1

Updating dynamic variables at Runtime?

Posted: Mon May 16, 2022 1:53 am
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!

Re: Updating dynamic variables at Runtime?

Posted: Mon May 16, 2022 8:43 am
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.

Re: Updating dynamic variables at Runtime?

Posted: Mon May 16, 2022 11:48 am
by domopuff
Hi Tony,

That's indeed what I am looking for. Thank you for the help.

Re: Updating dynamic variables at Runtime?

Posted: Mon May 16, 2022 1:46 pm
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;
        }
    }
}

Re: Updating dynamic variables at Runtime?

Posted: Mon May 16, 2022 10:41 pm
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?

Re: Updating dynamic variables at Runtime?

Posted: Tue May 17, 2022 7:47 am
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;
        }
    }
}

Re: Updating dynamic variables at Runtime?

Posted: Tue May 17, 2022 1:57 pm
by domopuff
Thanks for your speedy reply. This worked for me!

Re: Updating dynamic variables at Runtime?

Posted: Tue May 17, 2022 2:09 pm
by Tony Li
Glad to help!