Page 1 of 2

Default quest completed message?

Posted: Tue Oct 08, 2019 4:06 pm
by nicmar
Hey! :)

Is it possible to have a default "Quest completed: <Quest Title>" alert to show when I quest is completed, instead of having to add it in the Successful > Actions > Alert text, for each quest?

(I'm very sure it's possible, it would be interesting to know how you would set it up.. :))

Thank you in advance!

-niclas

Re: Default quest completed message?

Posted: Tue Oct 08, 2019 5:27 pm
by Tony Li
Yes. Add a script (for example, to the Quest Machine GameObject or the QuestJournal GameObject) that listens for the message "Quest State Changed" (aka QuestMachineMessages.QuestStateChangedMessage constant).

Here's an example:

ReportQuestSuccess.cs

Code: Select all

using UnityEngine;
using PixelCrushers;
using PixelCrushers.QuestMachine;

public class ReportQuestSuccess : MonoBehaviour, IMessageHandler
{
    private void OnEnable()
    {
        MessageSystem.AddListener(this, QuestMachineMessages.QuestStateChangedMessage, string.Empty);
    }

    private void OnDisable()
    {
        MessageSystem.RemoveListener(this);
    }

    public void OnMessage(MessageArgs messageArgs)
    {
        var quest = QuestMachine.GetQuestInstance(messageArgs.parameter);
        if (quest != null && quest.GetState() == QuestState.Successful)
        {
            QuestMachine.defaultQuestAlertUI.ShowAlert("Quest completed: " + quest.title);
        }
    }
}

Re: Default quest completed message?

Posted: Wed Oct 09, 2019 3:23 pm
by nicmar
Thanks! It works for QuestState.Successful, but I have 3 questions:

1) How to I use the Body Text Template and Header Text Template, to insert what I want to write the same way it would be Actions > Alert Quest Action. Cause now it just shows as plain text, and it seems as if it's just added as a gameobject with text under Quest Alert UI > Content Panel. I'm thinking I should somehow reach the Unity UI Quest Alert UI script, but I'm not sure how to reference it and use the templates.

2) How can I catch the "New quest started" state? I tried QuestState.Active, but it gets triggered multiple times.

3) How can I override the animations when the alert panel opens using code? I'd like to use DoTween here instead of the animator. I see Show/Hide and the UIPanelAnimator. Should I somehow use the OnOpen and OnClose events of the UIPanel, and create a custom script on the same gameobject as the UIPanel?

Thanks a lot :)

Re: Default quest completed message?

Posted: Wed Oct 09, 2019 4:27 pm
by Tony Li
Hi,
nicmar wrote: Wed Oct 09, 2019 3:23 pm1) How to I use the Body Text Template and Header Text Template, to insert what I want to write the same way it would be Actions > Alert Quest Action. Cause now it just shows as plain text, and it seems as if it's just added as a gameobject with text under Quest Alert UI > Content Panel. I'm thinking I should somehow reach the Unity UI Quest Alert UI script, but I'm not sure how to reference it and use the templates.
That's a little more complicated. You can do a lot with plain text. You can localize it by using a StringField, and you can use rich test codes to do things like set colors and formatting. If you're using TextMesh Pro, you can include sprites in your text. If you can get by with this, it's much simpler.

Otherwise you'll have to manage QuestContent objects like quests do. They're ScriptableObjects, and they require writing a custom editor. You can inherit most of the functionality from Quest Machine's existing editors, but you'll still have to write some editor code to put it together. If you need to do this, let me know and I'll provide details.
nicmar wrote: Wed Oct 09, 2019 3:23 pm2) How can I catch the "New quest started" state? I tried QuestState.Active, but it gets triggered multiple times.
The message gets sent whenever the quest or one of its quest nodes changes state. Try this version, which also incorporates the suggestions in #1 above.

ReportQuestState.cs

Code: Select all

using UnityEngine;
using PixelCrushers;
using PixelCrushers.QuestMachine;

public class ReportQuestState : MonoBehaviour, IMessageHandler
{
    [StringFieldTextArea]
    public StringField questStartedMessage = new StringField("<color=green>Started: {QUEST}</color>");
    [StringFieldTextArea]
    public StringField questCompletedMessaged = new StringField("<color=red>Completed: {QUEST}</color>");

    private void OnEnable()
    {
        MessageSystem.AddListener(this, QuestMachineMessages.QuestStateChangedMessage, string.Empty);
    }

    private void OnDisable()
    {
        MessageSystem.RemoveListener(this);
    }

    public void OnMessage(MessageArgs messageArgs)
    {
        var quest = QuestMachine.GetQuestInstance(messageArgs.parameter);
        if (quest == null) return; // Invalid quest. Exit.
        var isMainQuestState = StringField.IsNullOrEmpty(messageArgs.values[0] as StringField);
        if (!isMainQuestState) return; // This message is for a quest node. Exit.
        var questState = (QuestState)messageArgs.values[1];
        switch (questState)
        {
            case QuestState.Active:
                ShowAlert(questStartedMessage, quest);
                break;
            case QuestState.Successful:
                ShowAlert(questCompletedMessaged, quest);
                break;
        }
    }

    public void ShowAlert(StringField message, Quest quest)
    {
        var s = message.value.Replace("{QUEST}", quest.title.value);
        s = QuestMachineTags.ReplaceTags(s, quest);
        QuestMachine.defaultQuestAlertUI.ShowAlert(s);
    }
}
nicmar wrote: Wed Oct 09, 2019 3:23 pm3) How can I override the animations when the alert panel opens using code? I'd like to use DoTween here instead of the animator. I see Show/Hide and the UIPanelAnimator. Should I somehow use the OnOpen and OnClose events of the UIPanel, and create a custom script on the same gameobject as the UIPanel?
Yes.
  • Get rid of the show animation. Instead, assign a DOTween-powered method to OnOpen().
  • Assign a DOTween-powered method to OnClose().
  • Replace the hide animation with a blank animation that lasts for the same duration as your OnClose() method. This ensures that it keeps the GameObject active until the DOTween method finishes.

Re: Default quest completed message?

Posted: Wed Oct 09, 2019 5:06 pm
by nicmar
Thanks a lot, it worked great! I used <size> to control the size, but I'm not able to get new lines to work. Neither <br> or \n works in the string. I did this workaround, and using semicolon in my text string but maybe there is an easier way? :)

Code: Select all

		public void ShowAlert(StringField message, Quest quest)
		{
			var s = message.value.Replace("{QUEST}", quest.title.value);
			var br = message.value.Replace(";", "\n");
			s = QuestMachineTags.ReplaceTags(s, quest);
			s = s.Replace(";", "\n");
			QuestMachine.defaultQuestAlertUI.ShowAlert(s);
		}

Re: Default quest completed message?

Posted: Wed Oct 09, 2019 5:16 pm
by Tony Li
Put the attribute [StringFieldTextArea] in front of the two StringField variables:

Code: Select all

    [StringFieldTextArea]
    public StringField questStartedMessage = new StringField("<color=green>Started: {QUEST}</color>");
    [StringFieldTextArea]
    public StringField questCompletedMessaged = new StringField("<color=red>Completed: {QUEST}</color>");
Then you can enter newlines in the expanded text area for each one.

I'll update the full script above, too.

Re: Default quest completed message?

Posted: Wed Oct 09, 2019 5:32 pm
by nicmar
Aha! Nice, thank you! Here's the result of tonights work :lol:


Re: Default quest completed message?

Posted: Wed Oct 09, 2019 5:41 pm
by nicmar
I had a little issue with the text inside the box disappearing before I hide it, which you can see in the video. Where can I set the duration for that independently from how long the box shows?

Also I noticed that if I have multiple alerts at the same time, it overflows the box, so I need to rethink that.. :)

Re: Default quest completed message?

Posted: Wed Oct 09, 2019 8:12 pm
by Tony Li
nicmar wrote: Wed Oct 09, 2019 5:41 pmI had a little issue with the text inside the box disappearing before I hide it, which you can see in the video. Where can I set the duration for that independently from how long the box shows?
The Quest Alert UI's Unity UI Quest Alert UI component has a Duration section with values for Min Display Duration and Chars Per Sec Duration. They work similarly to the Dialogue System's Subtitle Settings on the Dialogue Manager.

Re: Default quest completed message?

Posted: Thu Oct 10, 2019 5:30 am
by nicmar
Thanks, I found that setting. But no matter how I do, it still seems that the text disappears (without transition) at the same time the dotween starts. I'd like for it to stay in the dialog box, so i can tween the box, with the text still showing inside. You can see my video above for what I mean.

I'm trying to fiddle with the Expand animation, which seems to be played in reverse when hiding. The Hidden animation doesn't seem to do anything. I tried changing the length of the animation which you mentioned, and I have a keyframe for an item which actually doesn't change or do anything, but I don't see any difference no matter the duration of the Expand animation.

Any ideas? :)