Page 1 of 2
HUD UI Groups
Posted: Thu Sep 05, 2024 11:32 am
by dlevel
Hey,
I see there is a Use Groups in Unity UI Quest HUD component but the Quest Group Template is empty (using the demo), so nothing changes in the hud, is there a group hud template I can check this feature with? Or what are the specs if I have to create one? thanks
Image:
https://ibb.co/nwgYhZr
Re: HUD UI Groups
Posted: Thu Sep 05, 2024 12:48 pm
by Tony Li
Hi,
Make sure you've assigned your quests' Group fields and that your HUD has a template UI assigned for groups.
Re: HUD UI Groups
Posted: Fri Sep 06, 2024 10:43 am
by dlevel
Yeap that was it, I didnt have a template attached.
1 more question, I m stuck, I have my journal scroll rect going out of the main panel when there are many quests in the journal, I have changed images etc but havent touched the actual game objects of the Quest Machine prefab, but obviously I have something done wrong. Demo one works fine. What property is responsible for this so I can go ahead and find the issue?
Thank you
Re: HUD UI Groups
Posted: Fri Sep 06, 2024 11:29 am
by Tony Li
Hi,
Can you share a screenshot?
Is the text content extending outside of the scroll rect? If so, is the Mask component enabled?
Or is the entire scroll rect GameObject positioned in the wrong place?
Re: HUD UI Groups
Posted: Sat Sep 07, 2024 1:54 am
by dlevel
Yes the text extending out side the scroll rect, at what gameobject is the mask that should be on to check it? Thanks
Re: HUD UI Groups
Posted: Sat Sep 07, 2024 8:56 am
by Tony Li
Hi,
It depends on how your scroll rect is set up. Yours may have a Scroll View in-between the Scroll Rect and the content. The prefab that ships with QM doesn't:
- mask.png (125.77 KiB) Viewed 313 times
Here's an example of how it masks the content when there's a lot of content:
- mask2.png (207.79 KiB) Viewed 313 times
(Note that I enabled the Content Size Fitter manually because the default prefab keeps it disabled and only enables it at runtime. That's for some obscure edge cases that your UI almost certainly doesn't need to worry about.)
And if I disable the mask, it looks like this:
- nomask.png (247.94 KiB) Viewed 313 times
Re: HUD UI Groups
Posted: Sun Sep 08, 2024 4:30 am
by dlevel
Ok perfect, had a weird issue that I had to have the mask's alpha >1 to work or else it would hide the quests in the main window but yeah I m good now.
One more question since I can't find it, is there a way to have max tracked quests in HUD? Since it overflows in th screen now
Re: HUD UI Groups
Posted: Sun Sep 08, 2024 8:36 am
by Tony Li
Here are two ideas:
1. Write a script that listens for the message "Quest Track Toggle Changed" (defined in a const string QuestMachineMessages.QuestTrackToggleChangedMessage) and, if the max number of quests has been tracked, automatically untrack some other quest. See
this post for an example of listening for messages.
2. Or make a subclass of UnityUIQuestJournalUI and override the behavior of the quest track checkbox toggles. Maybe set the unticked ones non-interactable if you're at the max. If the player UNticks a ticked checkbox, set the unticked ones interactable again.
Re: HUD UI Groups
Posted: Sun Sep 08, 2024 12:01 pm
by dlevel
ok that helped, created this script if you d like to implemented in a future update that does this, but even though it tracks quests fine and tries to untrack some, this feature doesnt work, so it doesnt untrack quests, can you help me on that? Thanks
Code: Select all
using UnityEngine;
using PixelCrushers;
using PixelCrushers.QuestMachine;
using System.Collections.Generic;
public class QuestTrackingLimiter : MonoBehaviour, IMessageHandler
{
public int maxTrackedQuests = 5; // Define your limit here
private List<string> trackedQuests = new List<string>();
private void OnEnable()
{
// Listen for Quest Track Toggle Changed messages:
MessageSystem.AddListener(this, QuestMachineMessages.QuestTrackToggleChangedMessage, string.Empty);
Debug.Log("QuestTrackingLimiter: Listening for quest track changes.");
}
private void OnDisable()
{
// Stop listening:
MessageSystem.RemoveListener(this);
Debug.Log("QuestTrackingLimiter: Stopped listening for quest track changes.");
}
public void OnMessage(MessageArgs messageArgs)
{
string questID = messageArgs.parameter;
bool isTracked = (bool)messageArgs.values[0]; // This will tell if the quest is being tracked or untracked
if (isTracked)
{
Debug.Log($"Quest '{questID}' is now being tracked.");
// Check if max tracked quests limit is reached
if (trackedQuests.Count >= maxTrackedQuests)
{
// Prevent tracking by immediately untracking the new quest
Debug.Log($"Max tracked quests limit reached: {maxTrackedQuests}. Untracking quest '{questID}'.");
UntrackQuest(questID);
return;
}
// Add the new tracked quest if below the limit
trackedQuests.Add(questID);
Debug.Log($"Quest '{questID}' added to the tracked list. Current number of tracked quests: {trackedQuests.Count}/{maxTrackedQuests}.");
}
else
{
// Remove the untracked quest
if (trackedQuests.Contains(questID))
{
trackedQuests.Remove(questID);
Debug.Log($"Quest '{questID}' was untracked. Current number of tracked quests: {trackedQuests.Count}/{maxTrackedQuests}.");
}
}
// Log the current list of tracked quests
LogTrackedQuests();
}
private void UntrackQuest(string questID)
{
// Send a message to untrack the quest using the messaging system
MessageSystem.SendMessage(this, QuestMachineMessages.QuestTrackToggleChangedMessage, questID, false);
Debug.Log($"Quest '{questID}' untracked.");
}
private void LogTrackedQuests()
{
if (trackedQuests.Count == 0)
{
Debug.Log("No quests are currently being tracked.");
}
else
{
Debug.Log("Currently tracked quests:");
foreach (var quest in trackedQuests)
{
Debug.Log($"- {quest}");
}
}
}
}
Also another question, I ll be having like 100 quests on the game, is it better to have everything on the player with WaitingToStart and using variables to start quests (that would help with management), or just use "Give quest to player" from other finished quests? These quests will not be given by NPCs etc, will be like achievements. So I ask is the first method (just add all these quests to player prefab) is bad on performance or saves etc?
Re: HUD UI Groups
Posted: Sun Sep 08, 2024 6:48 pm
by Tony Li
Hi,
Try this version:
Code: Select all
using UnityEngine;
using PixelCrushers;
using PixelCrushers.QuestMachine;
using System.Collections.Generic;
public class QuestTrackingLimiter : MonoBehaviour, IMessageHandler
{
public int maxTrackedQuests = 5; // Define your limit here
public List<string> trackedQuests = new List<string>();
private void OnEnable()
{
// Listen for Quest Track Toggle Changed messages:
MessageSystem.AddListener(this, QuestMachineMessages.QuestStateChangedMessage, string.Empty);
MessageSystem.AddListener(this, QuestMachineMessages.QuestTrackToggleChangedMessage, string.Empty);
Debug.Log("QuestTrackingLimiter: Listening for quest track changes.");
}
private void OnDisable()
{
// Stop listening:
MessageSystem.RemoveListener(this);
Debug.Log("QuestTrackingLimiter: Stopped listening for quest track changes.");
}
public void OnMessage(MessageArgs messageArgs)
{
string questID = messageArgs.parameter;
if (QuestMachine.GetQuestState(questID) == QuestState.WaitingToStart) return;
bool isTracked = false;
if (messageArgs.message == QuestMachineMessages.QuestStateChangedMessage)
{
bool isMainQuestState = (messageArgs.values[0] == null);
if (!isMainQuestState) return; // Only act if the main quest state has changed.
QuestState questState = (QuestState)messageArgs.values[1];
if (questState == QuestState.Disabled) return; // Quest giver disables its instance when given.
if (questState == QuestState.Active) // Was just activated
{
var questInstance = QuestMachine.GetQuestInstance(questID);
isTracked = questInstance.showInTrackHUD;
}
}
else if (messageArgs.message == QuestMachineMessages.QuestTrackToggleChangedMessage)
{
isTracked = (bool)messageArgs.values[0]; // This will tell if the quest is being tracked or untracked
}
else
{
return; // Neither Quest State Changed nor Quest Track Toggle Changed, so exit.
}
if (isTracked)
{
Debug.Log($"Quest '{questID}' is now being tracked.");
// Check if max tracked quests limit is reached
if (trackedQuests.Count >= maxTrackedQuests)
{
// Prevent tracking by immediately untracking the new quest
Debug.Log($"Max tracked quests limit reached: {maxTrackedQuests}. Untracking quest '{questID}'.");
UntrackQuest(questID);
return;
}
// Add the new tracked quest if below the limit
trackedQuests.Add(questID);
Debug.Log($"Quest '{questID}' added to the tracked list. Current number of tracked quests: {trackedQuests.Count}/{maxTrackedQuests}.");
}
else
{
// Remove the untracked quest
if (trackedQuests.Contains(questID))
{
trackedQuests.Remove(questID);
Debug.Log($"Quest '{questID}' was untracked. Current number of tracked quests: {trackedQuests.Count}/{maxTrackedQuests}.");
}
}
// Log the current list of tracked quests
LogTrackedQuests();
}
private void UntrackQuest(string questID)
{
// Send a message to untrack the quest using the messaging system
// Not this: MessageSystem.SendMessage(this, QuestMachineMessages.QuestTrackToggleChangedMessage, questID, false);
// Set the quest's showInTrackHUD property instead:
QuestMachine.GetQuestInstance(questID).showInTrackHUD = false;
Debug.Log($"Quest '{questID}' untracked.");
}
private void LogTrackedQuests()
{
if (trackedQuests.Count == 0)
{
Debug.Log("No quests are currently being tracked.");
}
else
{
Debug.Log("Currently tracked quests:");
foreach (var quest in trackedQuests)
{
Debug.Log($"- {quest}");
}
}
}
}
You can run a "diff" (e.g., using diffchecker.com or your code editor) to see the differences. Briefly, the script needs to also account for quest state changes.
dlevel wrote: ↑Sun Sep 08, 2024 12:01 pmAlso another question, I ll be having like 100 quests on the game, is it better to have everything on the player with WaitingToStart and using variables to start quests (that would help with management), or just use "Give quest to player" from other finished quests? These quests will not be given by NPCs etc, will be like achievements. So I ask is the first method (just add all these quests to player prefab) is bad on performance or saves etc?
Putting 100 WaitingToStart quests on the player should be fine for performance and saves. It would really only be a concern if all of those quests had Autostart conditions that use polling, such as checking conditions every frame. Most of Quest Machine's built-in conditions are event-based -- that is, they only check when a specific message or event happens -- so they don't do polling.