Calling function within a template from a conversation event

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
alexlol
Posts: 35
Joined: Sat Nov 07, 2020 8:20 am

Calling function within a template from a conversation event

Post 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 780 times
Screenshot 2021-01-05 150407.png
Screenshot 2021-01-05 150407.png (24.77 KiB) Viewed 780 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
User avatar
Tony Li
Posts: 22049
Joined: Thu Jul 18, 2013 1:27 pm

Re: Calling function within a template from a conversation event

Post 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(#).
alexlol
Posts: 35
Joined: Sat Nov 07, 2020 8:20 am

Re: Calling function within a template from a conversation event

Post 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?
User avatar
Tony Li
Posts: 22049
Joined: Thu Jul 18, 2013 1:27 pm

Re: Calling function within a template from a conversation event

Post by Tony Li »

Yes, that's correct. They're practically identical. SMSDialogueUI just makes it part of the core asset release.
alexlol
Posts: 35
Joined: Sat Nov 07, 2020 8:20 am

Re: Calling function within a template from a conversation event

Post by alexlol »

That works - thank you so much!
alexlol
Posts: 35
Joined: Sat Nov 07, 2020 8:20 am

Re: Calling function within a template from a conversation event

Post 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.
User avatar
Tony Li
Posts: 22049
Joined: Thu Jul 18, 2013 1:27 pm

Re: Calling function within a template from a conversation event

Post 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.
alexlol
Posts: 35
Joined: Sat Nov 07, 2020 8:20 am

Re: Calling function within a template from a conversation event

Post 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.
User avatar
Tony Li
Posts: 22049
Joined: Thu Jul 18, 2013 1:27 pm

Re: Calling function within a template from a conversation event

Post by Tony Li »

Happy to help! I'm glad you got it working the way you want.
Post Reply