Page 1 of 1

Calling function within a template from a conversation event

Posted: Tue Jan 05, 2021 10:12 am
by alexlol
Hello! I'm constructing a simple SMS conversation using the Textline Dialogue UI and I've added WhatsApp style ticks:
Screenshot 2021-01-05 150049.png
Screenshot 2021-01-05 150049.png (9.76 KiB) Viewed 782 times
Screenshot 2021-01-05 150407.png
Screenshot 2021-01-05 150407.png (24.77 KiB) Viewed 782 times
As seen above, the ticks are a prefab image added to the hierarchy of the PC Message Template, and they have a simple script which switches them from blue to green when called. I would like to call this method from the Events section of specific conversation lines in the Dialogue Editor to simulator messages being sent and read.

However, I'm unsure how to achieve this correctly - as it's part of the PC Message Template, I can't call it as a scene event, and if I add a non-scene event to the dialogue line I'm unable to simply drag in the object in from the Textline DIalogue UI prefab.

Is there a good solution to calling functions within the PC Message Template like this? Thanks,

- Alex

Re: Calling function within a template from a conversation event

Posted: Tue Jan 05, 2021 12:02 pm
by Tony Li
Hi Alex,

Generally speaking, all methods are virtual in TextlineDialogueUI and the near-identical script now included in Plugins / Pixel Crushers / Dialogue System / Script / UI / Standard / Dialogue / SMS / SMSDialogueUI. You can override those methods to change the UI's behavior.

However, in your case, you want to change the messages after they've been displayed, not in any of the TextlineDialogueUI methods that are responsible for initially displaying them. You could make a subclass of StandardUISubtitlePanel that remembers some piece of identifying information such as the dialogue entry ID number:

Code: Select all

public class CustomSubtitlePanel : StandardUISubtitlePanel
{
    public int entryID;
    
    public override void SetContent(Subtitle subtitle)
    {
        base.SetContent(subtitle);
        entryID = subtitle.dialogueEntry.id;
    }
}
Then make a subclass of TextlineDialogueUI that adds a method to set ticks by entry ID. You could even register it as a Lua function

Code: Select all

public class CustomDialogueUI : TextlineDialogueUI
{
    public override void Awake()
    {
        base.Awake();
        Lua.RegisterFunction("SetTick", this, SymbolExtensions.GetMethodInfo(() => LuaSetTick((double)0)));
    }
    
    public void LuaSetTick(double entryID) { SetTick((int)entryID); } // Lua uses doubles.
    
    public void SetTick(int entryID)
    {
        foreach (var go in instantiatedMessages)
        {
            var panel = go.GetComponent<CustomSubtitlePanel>();
            if (panel.entryID == entryID) 
            {
                // (Here, set SMS Seen Indicator on this panel.)
                break;
            }
        }
    }
}
Use these subclasses in place of StandardUISubtitlePanel and TextlineDialogueUI.

In your dialogue entry's Script field, call SetTick(#).

Re: Calling function within a template from a conversation event

Posted: Tue Jan 05, 2021 12:32 pm
by alexlol
Thank you, I'll try this out now - I'm assuming if I were to check out using the SMSDialogueUI instead, I can just inherit from that instead of TextlineDialogueUI?

Re: Calling function within a template from a conversation event

Posted: Tue Jan 05, 2021 12:51 pm
by Tony Li
Yes, that's correct. They're practically identical. SMSDialogueUI just makes it part of the core asset release.

Re: Calling function within a template from a conversation event

Posted: Tue Jan 05, 2021 1:49 pm
by alexlol
That works - thank you so much!

Re: Calling function within a template from a conversation event

Posted: Tue Jan 05, 2021 1:59 pm
by alexlol
A small addendum - using this method, is there a way to call the SetTick() before displaying any of the current NPC dialogue/Pre Delay Icon?

Eg:
  • The player submits the message
  • There is a short delay
  • SetTick is called,
  • Another short delay
  • The next message/pre delay is called
Hope that makes sense.

Re: Calling function within a template from a conversation event

Posted: Tue Jan 05, 2021 2:41 pm
by Tony Li
Hi,

Look into overriding TextlineDialogueUI/SMSDialogueUI's AddMessageWithPreDelay() method. This is the method that shows the pre-delay icon, waits for a duration, then calls AddMessage() to actually add the message.

Re: Calling function within a template from a conversation event

Posted: Wed Jan 06, 2021 9:22 am
by alexlol
Thanks - this has been incredibly helpful. The way I finally got it working how I want was to call SetTick() on the player conversation node with the ticks and set a coroutine to delay based on a variable.

The Dialogue System is so vast and robust that I find it sometimes easy to overlook the best way to approach something, so these forums are invaluable.

Re: Calling function within a template from a conversation event

Posted: Wed Jan 06, 2021 10:30 am
by Tony Li
Happy to help! I'm glad you got it working the way you want.