Hi,
Quest Machine's UIs (journal, HUD, dialogue, alert) share a lot of functionality. That shared functionality is in their parent class, UnityUIBaseUI. Since we don't know ahead of time how much content the UIs will need to show, the UIs work by way of template UI elements (text, image, button, etc).
In addition, they use the MessageSystem to listen for messages such as "Refresh UIs" to know when to refresh their content, such as when the player accepts a new quest. When a UI refreshes itself, it gets a list of quests. For example, the UnityUIQuestJournalUI gets the QuestJournal's quest list. Then it goes through each quest and gets the quest's list of content to currently display. It starts with a container, which is just a UI subpanel to group UI elements. For each piece of content, it adds an instance of some type of template to the container.
jlhacode wrote: ↑Mon Apr 05, 2021 8:40 pm 1. In my journal UI prefab, I have a single "Track Quest" button.
- When I select a quest that doesn't have any HUD text for its current state, I would like the "Track Quest" button to be disabled. If the quest has HUD text for its current state, then I'd like to enable it.
- When pressed, the track quest button should start tracking the quest that's selected.
The UnityUIQuestNameButtonTemplate class is a template for a quest name, icon, and tracking toggle. Make a subclass of UnityUIQuestNameButtonTemplate and override the Assign method:
Code: Select all
public override void Assign(Quest quest, ToggleChangedDelegate trackToggleDelegate)
{
if (quest == null) return;
base.Assign(quest, trackToggleDelegate);
if ((quest.GetState() == QuestState.Active) && quest.isTrackable)
{
// If quest doesn't have HUD content, hide the tracking toggle:
var hudContents = quest.GetContentList(QuestContentCategory.HUD);
if (hudContents.Count == 0)
{
trackToggleTemplate.gameObject.SetActive(false);
}
}
}
Locate your quest journal UI's Active Quest Name Template GameObject. Replace the UnityUIQuestNameButtonTemplate script with your subclass. To replace it in place and keep the references, change the Inspector to Debug mode and drag your subclass script into the Script field.
jlhacode wrote: ↑Mon Apr 05, 2021 8:40 pm2. When I'm assigned a new quest, it should get tracked only if another quest isn't already being tracked.
Make a subclass of QuestJournal or add a new script to the player. If you subclass QuestJournal, override the AddQuest method:
Code: Select all
public override Quest AddQuest(Quest quest)
{
base.AddQuest(quest);
if (quest.isTrackable)
{
var currentTrackedQuest = questList.Find(x => x.showInTrackHUD);
if (currentTrackedQuest == null)
{
quest.showInTrackHUD = true;
RepaintUIs();
}
}
}
jlhacode wrote: ↑Mon Apr 05, 2021 8:40 pm3. I would like to add indicators for unread quests in the Quest Selection Panel.
Each quest has a tag dictionary. This is normally used to record values such as {QUESTER} and {QUESTGIVER}. But you can also add your own tags to it. You can add a "READ" tag when the player has read a quest.
In your UnityUIQuestNameButtonTemplate subclass's overridden Assign method, add something like:
Code: Select all
public GameObject unreadIndicator; //<--Assign in inspector.
public override void Assign(Quest quest, ToggleChangedDelegate trackToggleDelegate)
{
if (quest == null) return;
base.Assign(quest, trackToggleDelegate);
if (quest.GetState() == QuestState.Active) && quest.isTrackable)
{
// If quest doesn't have HUD content, hide the tracking toggle:
var hudContents = quest.GetContentList(QuestContentCategory.HUD);
if (hudContents.Count == 0)
{
trackToggleTemplate.gameObject.SetActive(false);
}
}
var isUnread = !quest.tagDictionary.Contains("READ");
unreadIndicator.SetActive(isUnread);
if (isUnread)
{
// If unread, configure the button to add the "READ" tag when clicked:
buttonTemplate.button.OnClick.AddListener(() =>
{
quest.tagDictionary.SetTag("READ", true);
});
}
}
(Note: I typed this code directly into the reply; it may have typos, but it should convey the gist of what you need to do.)