Custom Quest Actions
-
- Posts: 178
- Joined: Fri Sep 21, 2018 8:38 pm
Re: Custom Quest Actions
Any event I can call to refresh the UI (example HUD) everytime some of the counters I want get updated?
Thanks
Thanks
Re: Custom Quest Actions
Yes, QuestMachineMessages.RefreshUIs().
-
- Posts: 178
- Joined: Fri Sep 21, 2018 8:38 pm
Re: Custom Quest Actions
yes sure, but i refer how do we suscribe to the Listener / event?
MessageSystem.AddListener(this, QuestMachineMessages.QuestCounterChangedMessage, questString);
Maybe?
One More thing: Counters do't refresh in real time in the editor Journal (runtime:Active) do they?
And...last one...is it possible to write on the UI from my script with this special tags so the counters got refresh?
{#EnemyFloodedWaves} / {>#EnemyFloodedWaves
I have tried but it shows like that and it doesn't convert.
MessageSystem.AddListener(this, QuestMachineMessages.QuestCounterChangedMessage, questString);
Maybe?
One More thing: Counters do't refresh in real time in the editor Journal (runtime:Active) do they?
And...last one...is it possible to write on the UI from my script with this special tags so the counters got refresh?
{#EnemyFloodedWaves} / {>#EnemyFloodedWaves
I have tried but it shows like that and it doesn't convert.
Re: Custom Quest Actions
Hi,
For QuestCounterChangedMessage, they are:
For example, BodyTextQuestContent overrides originalText to map it to its bodyText property.
QuestContent's runtimeText property returns a copy of originalText in which the tags have been replaced by their current values.
If you don't use originalText and runtimeText, you can always manually replace the tags with their values:
Also, make sure your counter tags (such as {#EnemyFloodedWaves}) match counter names in your quest.
Yes. The UIs already subscribe to the event. If you have an additional UI of your own, you can subscribe to it like that. The QuestMachineMessages API page explains what values Quest Machine send with each message.GorkaGames wrote: ↑Tue Feb 19, 2019 6:26 pmyes sure, but i refer how do we suscribe to the Listener / event?
MessageSystem.AddListener(this, QuestMachineMessages.QuestCounterChangedMessage, questString);
Maybe?
For QuestCounterChangedMessage, they are:
- parameter: Quest ID
- values[0]: Counter name (type: StringField)
- values[1]: New value (type: int)
Yes. They refresh in the Unity editor's Inspector view, and they refresh in the gameplay Quest Journal UI.GorkaGames wrote: ↑Tue Feb 19, 2019 6:26 pmOne More thing: Counters do't refresh in real time in the editor Journal (runtime:Active) do they?
If you're writing a new QuestContent type, override the originalText field.GorkaGames wrote: ↑Tue Feb 19, 2019 6:26 pmAnd...last one...is it possible to write on the UI from my script with this special tags so the counters got refresh?
{#EnemyFloodedWaves} / {>#EnemyFloodedWaves
I have tried but it shows like that and it doesn't convert.
For example, BodyTextQuestContent overrides originalText to map it to its bodyText property.
QuestContent's runtimeText property returns a copy of originalText in which the tags have been replaced by their current values.
If you don't use originalText and runtimeText, you can always manually replace the tags with their values:
Code: Select all
string preparedText = QuestMachineTags.ReplaceTags(text, quest);
-
- Posts: 178
- Joined: Fri Sep 21, 2018 8:38 pm
Re: Custom Quest Actions
ok, thanks very much for your awesome support, but for me it's a bit complicated the tag thing
I'm calling this from my custom Quest Action that you helped me yesterday to code.
And what I want it, it's to write in the Hud: "Chests: 0 of 7" and that it refresh every time the counter updates.
So now i have:
content1.bodyText = new StringField("Chests: " + quest.GetCounter(CounterName).currentValue + " / " + quest.GetCounter(CounterName).maxValue);
But this only works once as it doesn't refresh (I guess because Execute only executes once by design)
So I may need to change to:
//content.bodyText = new StringField("Chests: " + "{#Flooded2_Chests1} / {>#Flooded2_Chests1}");
But this it doesn't work as it shows the literal tags instead of the value inside the tags.
So how do I need to write this line so it gets on the Hud and refresh automatically?
Thanks! (I leave here the code just in case it's more clear for you)
And I leave you here a screenshot of the HUD and Dialogue:
https://1drv.ms/u/s!AgOs7p5LnVflkMAfksqndaIQpk_1vw
using UnityEngine;
using System;
namespace PixelCrushers.QuestMachine
{
public class ChestQuestAction : QuestAction, PixelCrushers.IMessageHandler
{
public string QuestParameterMessage = "IMPORTANTE: A rellenar, mismo que en el Prefab";
public string CounterName;
private string QuestMessageToActivate = "ActivateChest";
private string QuestMessageOpened = "ChestOpened";
private string QuestMessageToDeativated = "ChestDeativated";
private Quest questActual;
private QuestNode questNodeActual;
private string questString;
public EstadoChest EstadoChestAPoner = EstadoChest.Cerrado;
public bool isVisible => throw new NotImplementedException();
public override void Execute()
{
base.Execute();
// Add your code here. This code will run when the action runs.
switch (EstadoChestAPoner)
{
case EstadoChest.Cerrado:
//Envia mensaje para activar el chest (cerrado)
PixelCrushers.MessageSystem.SendMessage(this, QuestMessageToActivate, QuestParameterMessage);
break;
case EstadoChest.Bloqueado:
//Envia mensaje para desactivar el chest, no se utiliza mucho
PixelCrushers.MessageSystem.SendMessage(this, QuestMessageToDeativated, QuestParameterMessage); //No se utiliza mucho
break;
}
UpdateUI();
// Nos suscribimos a los mensajes de Quest Machine
MessageSystem.AddListener(this, QuestMachineMessages.QuestCounterChangedMessage, questString);
}
private void UpdateUI()
{
//Obtiene la quest donde estamos
questActual = this.quest;
questString = questActual.ToString();
//Obtiene el Nodo donde estamos
questNodeActual = this.questNode;
//Obtiene el estado del Nodo donde estamos
var stateInfo = questNode.GetStateInfo(QuestNodeState.Active);
// get the content list for a specific category
var hudContentList = stateInfo.GetContentList(QuestContentCategory.HUD);
var journalContentList = stateInfo.GetContentList(QuestContentCategory.Journal);
var dialogueContentList = stateInfo.GetContentList(QuestContentCategory.Dialogue);
var alertContentList = stateInfo.GetContentList(QuestContentCategory.Alert);
var content = BodyTextQuestContent.CreateInstance<BodyTextQuestContent>();
var content1 = BodyTextQuestContent.CreateInstance<BodyTextQuestContent>();
content.bodyText = new StringField("Now go find the chest");
if (quest.GetCounter(CounterName) != null)
{
content1.bodyText = new StringField("Chests: " + quest.GetCounter(CounterName).currentValue + " / " + quest.GetCounter(CounterName).maxValue);
//content.bodyText = new StringField("Chests: " + "{#Flooded2_Chests1} / {>#Flooded2_Chests1}");
}
if (hudContentList != null) hudContentList.Add(content);
if (hudContentList != null) hudContentList.Add(content1);
if (journalContentList != null) journalContentList.Add(content);
if (dialogueContentList != null) dialogueContentList.Add(content);
if (alertContentList != null) alertContentList.Add(content);
//Refresca los UIs
QuestMachineMessages.RefreshUIs(this);
//Envia al manager de UI Quest los datos de esta quest para que se pueda suscribir a refrescar el UI cuando cambian los contadores.
//if (QuestUIManager.instance != null) QuestUIManager.instance.RecibeInfoQuestNode(quest, questNode, CounterName);
}
public void OnMessage(MessageArgs messageArgs)
{
if (messageArgs.message == QuestMachineMessages.QuestCounterChangedMessage)
{
Debug.Log("Recibimos mensaje de counter change");
//Refrescamos los UIs (Journal, Hud, Dialogues, etc...)
QuestMachineMessages.RefreshUIs(this);
}
}
}
}
I'm calling this from my custom Quest Action that you helped me yesterday to code.
And what I want it, it's to write in the Hud: "Chests: 0 of 7" and that it refresh every time the counter updates.
So now i have:
content1.bodyText = new StringField("Chests: " + quest.GetCounter(CounterName).currentValue + " / " + quest.GetCounter(CounterName).maxValue);
But this only works once as it doesn't refresh (I guess because Execute only executes once by design)
So I may need to change to:
//content.bodyText = new StringField("Chests: " + "{#Flooded2_Chests1} / {>#Flooded2_Chests1}");
But this it doesn't work as it shows the literal tags instead of the value inside the tags.
So how do I need to write this line so it gets on the Hud and refresh automatically?
Thanks! (I leave here the code just in case it's more clear for you)
And I leave you here a screenshot of the HUD and Dialogue:
https://1drv.ms/u/s!AgOs7p5LnVflkMAfksqndaIQpk_1vw
using UnityEngine;
using System;
namespace PixelCrushers.QuestMachine
{
public class ChestQuestAction : QuestAction, PixelCrushers.IMessageHandler
{
public string QuestParameterMessage = "IMPORTANTE: A rellenar, mismo que en el Prefab";
public string CounterName;
private string QuestMessageToActivate = "ActivateChest";
private string QuestMessageOpened = "ChestOpened";
private string QuestMessageToDeativated = "ChestDeativated";
private Quest questActual;
private QuestNode questNodeActual;
private string questString;
public EstadoChest EstadoChestAPoner = EstadoChest.Cerrado;
public bool isVisible => throw new NotImplementedException();
public override void Execute()
{
base.Execute();
// Add your code here. This code will run when the action runs.
switch (EstadoChestAPoner)
{
case EstadoChest.Cerrado:
//Envia mensaje para activar el chest (cerrado)
PixelCrushers.MessageSystem.SendMessage(this, QuestMessageToActivate, QuestParameterMessage);
break;
case EstadoChest.Bloqueado:
//Envia mensaje para desactivar el chest, no se utiliza mucho
PixelCrushers.MessageSystem.SendMessage(this, QuestMessageToDeativated, QuestParameterMessage); //No se utiliza mucho
break;
}
UpdateUI();
// Nos suscribimos a los mensajes de Quest Machine
MessageSystem.AddListener(this, QuestMachineMessages.QuestCounterChangedMessage, questString);
}
private void UpdateUI()
{
//Obtiene la quest donde estamos
questActual = this.quest;
questString = questActual.ToString();
//Obtiene el Nodo donde estamos
questNodeActual = this.questNode;
//Obtiene el estado del Nodo donde estamos
var stateInfo = questNode.GetStateInfo(QuestNodeState.Active);
// get the content list for a specific category
var hudContentList = stateInfo.GetContentList(QuestContentCategory.HUD);
var journalContentList = stateInfo.GetContentList(QuestContentCategory.Journal);
var dialogueContentList = stateInfo.GetContentList(QuestContentCategory.Dialogue);
var alertContentList = stateInfo.GetContentList(QuestContentCategory.Alert);
var content = BodyTextQuestContent.CreateInstance<BodyTextQuestContent>();
var content1 = BodyTextQuestContent.CreateInstance<BodyTextQuestContent>();
content.bodyText = new StringField("Now go find the chest");
if (quest.GetCounter(CounterName) != null)
{
content1.bodyText = new StringField("Chests: " + quest.GetCounter(CounterName).currentValue + " / " + quest.GetCounter(CounterName).maxValue);
//content.bodyText = new StringField("Chests: " + "{#Flooded2_Chests1} / {>#Flooded2_Chests1}");
}
if (hudContentList != null) hudContentList.Add(content);
if (hudContentList != null) hudContentList.Add(content1);
if (journalContentList != null) journalContentList.Add(content);
if (dialogueContentList != null) dialogueContentList.Add(content);
if (alertContentList != null) alertContentList.Add(content);
//Refresca los UIs
QuestMachineMessages.RefreshUIs(this);
//Envia al manager de UI Quest los datos de esta quest para que se pueda suscribir a refrescar el UI cuando cambian los contadores.
//if (QuestUIManager.instance != null) QuestUIManager.instance.RecibeInfoQuestNode(quest, questNode, CounterName);
}
public void OnMessage(MessageArgs messageArgs)
{
if (messageArgs.message == QuestMachineMessages.QuestCounterChangedMessage)
{
Debug.Log("Recibimos mensaje de counter change");
//Refrescamos los UIs (Journal, Hud, Dialogues, etc...)
QuestMachineMessages.RefreshUIs(this);
}
}
}
}
-
- Posts: 178
- Joined: Fri Sep 21, 2018 8:38 pm
Re: Custom Quest Actions
Any Feedback on this? (I'm just working right now on this....
Thanks!
Thanks!
Re: Custom Quest Actions
I've set up a reproduction case, and I'm investigating now.
Re: Custom Quest Actions
Add these lines:
Note: Since Actions run when a node becomes True, I didn't use the action's questNode property. Instead, I used quest.GetNode() to get the next node, like this:
The SetRuntimeReferences() method initializes internal references. Normally the quest does this automatically. But since you're adding new content at runtime, you need to call it manually.
You don't really need AddTagsToDictionary() unless you're using new tags that aren't used anywhere else in the quest.
Code: Select all
content.SetRuntimeReferences(quest, node);
content1.SetRuntimeReferences(quest, node);
content1.AddTagsToDictionary();
Code: Select all
QuestNode node = quest.GetNode("getChests");
You don't really need AddTagsToDictionary() unless you're using new tags that aren't used anywhere else in the quest.
-
- Posts: 178
- Joined: Fri Sep 21, 2018 8:38 pm
Re: Custom Quest Actions
It works! Thanks very much, but even works with: questNodeActual = this.questNode; so I don't have to look for the next node as you mentioned (easier
And thanks for your time!
And thanks for your time!