Quest HUD Text Animation

Announcements, support questions, and discussion for Quest Machine.
Post Reply
cptscrimshaw
Posts: 113
Joined: Sun Sep 20, 2020 8:21 pm

Quest HUD Text Animation

Post by cptscrimshaw »

Hi Tony,

I'm looking to implement a simple animation on the Quest HUD when node states change (e.g., when a node changes to True, it disappears from the HUD with an animation, or when a node changes to Active it animates in). I was going to create a custom version of the UnityUIQuestHUD class, but I wanted to check if there was a simpler/built-in way to add this functionality already. I didn't see anything in the code or on the forums about it, but I definitely could have missed it.

Thanks!
User avatar
Tony Li
Posts: 22886
Joined: Thu Jul 18, 2013 1:27 pm

Re: Quest HUD Text Animation

Post by Tony Li »

Hi,

I suggest making a subclass of UnityUIQuestHUD and overriding the RefreshNow() method.

The current method calls MakeVisible() (still do that), then clears the currentContentManager and adds new content for each tracked quest.

Your overridden method can call MakeVisible() and, instead of just outright clearing currentContentManager, animate any new or outgoing content.
User avatar
Tony Li
Posts: 22886
Joined: Thu Jul 18, 2013 1:27 pm

Re: Quest HUD Text Animation

Post by Tony Li »

Here's an example scene that fades in new HUD content instead of showing it instantly. You could replace the Fade() method with any other type of animation you prefer.

QM_HUDSubclassExample_2024-11-25.unitypackage

It uses this script (included in the package above).

CustomQuestHUD.cs

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PixelCrushers.QuestMachine;

/// <summary>
/// More info about subclassing: https://www.pixelcrushers.com/phpbb/viewtopic.php?t=5495
/// </summary>
public class CustomQuestHUD : UnityUIQuestHUD
{

    private List<QuestContent> oldQuestContent = new List<QuestContent>();
    private List<QuestContent> newQuestContent = new List<QuestContent>();

    protected override void RefreshNow()
    {
        // We override RefreshNow() to track new vs. old content:
        newQuestContent = new List<QuestContent>();
        StopAllCoroutines(); // Interrupt old fades
        base.RefreshNow();
        oldQuestContent = newQuestContent;
    }

    protected override void AddContent(QuestContent content)
    {
        // When we add content, check if it's new. If so, record it and fade it in.
        base.AddContent(content);
        if (!oldQuestContent.Contains(content))
        {
            newQuestContent.Add(content);
            var instance = currentContentManager.instancedContent[currentContentManager.instancedContent.Count - 1];
            StartCoroutine(Fade(instance));
        }
    }

    private IEnumerator Fade(UnityUIContentTemplate instance)
    {
        var canvasGroup = instance.GetComponent<CanvasGroup>();
        if (canvasGroup == null) canvasGroup = instance.gameObject.AddComponent<CanvasGroup>();
        canvasGroup.alpha = 0;
        const float duration = 0.5f; // Fade in over 0.5 seconds.
        float elapsed = 0;
        while (elapsed < duration)
        {
            float t = elapsed / duration;
            canvasGroup.alpha = Mathf.Lerp(0, 1, t);
            yield return null;
            elapsed += Time.deltaTime;
        }
        canvasGroup.alpha = 1;
    }
}
Post Reply