event OnQuestStatusChanged(string quest, QuestStatus status)?
event OnQuestStatusChanged(string quest, QuestStatus status)?
Hi Tony!
i have some objects disabled at the start of the scene and need to enable when a quest changed the state. At the start of the scene is not a problem, the problem is how track the quest state changed while the scene is playing and a event like the title will be great
exist any event like that?
Thanks
i have some objects disabled at the start of the scene and need to enable when a quest changed the state. At the start of the scene is not a problem, the problem is how track the quest state changed while the scene is playing and a event like the title will be great
exist any event like that?
Thanks
Re: event OnQuestStatusChanged(string quest, QuestStatus status)?
Hi Alfonso!
It depends on how you change the quest state.
If you change it with a trigger such as Dialogue System Trigger, you can configure the trigger to show an alert message, send a message to another GameObject, etc.
If you change the quest state during a conversation, you can use the Script field to set Variable["Alert"]. This will show an alert message when the conversation is done. For example:
Script:
You can also use the SetActive() sequencer command to activate GameObjects. For example, say you want to activate a GameObject named "ratSpawner":
Sequence:
You can also register one of your C# methods as a Lua function and call it in the Script field:
Script:
And your C# method:
You can also use a Condition Observer or Quest State Observer. These are polling methods, which means they run on a regular frequency, so they're not necessarily as efficient as the other methods above.
Condition Observer is a component. You can set it to check every 1 second, for example. It can check the quest state. When it changes to a specific value, it can run actions such as showing alert messages, etc.
QuestLog.SetQuestStateObserver() is a method. It registers a C# method that will be called when the quest state changes. But it only checks for quest state changes at specified times: every Update(), every dialogue entry, or only at the end of conversations. For example:
It depends on how you change the quest state.
If you change it with a trigger such as Dialogue System Trigger, you can configure the trigger to show an alert message, send a message to another GameObject, etc.
If you change the quest state during a conversation, you can use the Script field to set Variable["Alert"]. This will show an alert message when the conversation is done. For example:
Script:
Code: Select all
Quest["Escape"].State = "success";
Variable["Alert"] = "You escaped the dungeon!"
Sequence:
Code: Select all
SetActive(ratSpawner)
Script:
Code: Select all
ActivateQuest("Kill 5 Rats", "ratSpawner");
Code: Select all
void ActivateQuest(string title, string gameObjectToActivate) {
QuestLog.StartQuest(title);
Tools.GameObjectHardFind(gameObjectToActivate).SetActive(true);
DialogueManager.ShowAlert("New Quest: " + title);
}
You can also use a Condition Observer or Quest State Observer. These are polling methods, which means they run on a regular frequency, so they're not necessarily as efficient as the other methods above.
Condition Observer is a component. You can set it to check every 1 second, for example. It can check the quest state. When it changes to a specific value, it can run actions such as showing alert messages, etc.
QuestLog.SetQuestStateObserver() is a method. It registers a C# method that will be called when the quest state changes. But it only checks for quest state changes at specified times: every Update(), every dialogue entry, or only at the end of conversations. For example:
Code: Select all
QuestLog.AddQuestStateObserver("Kill 5 Rats", LuaWatchFrequency.EndOfConversation, OnQuestStateChanged);
void OnQuestStateChanged(string title, QuestState newState) {
if (string.Equals(title, "Kill 5 Rats") && (newState == QuestState.Active)) {
ratSpawner.SetActive(true);
}
}
Re: event OnQuestStatusChanged(string quest, QuestStatus status)?
woo men this is so long thanks i try to explain my idea
my idea was that each object in the scene was "aware" about the quest state he is watching. and if i need to change some behaviour on a object go to the object instead each conversation node looking for where i change it.
for that i made a QuestTrackerObject is the base of each component how need any behaviour on a quest changed.
for example i have a tv with an animator, if quets is active show the animation "Alert" and if is success show the animation "Done".
so i can extend this base clase an create QuestTrackerAnimator and attach to the tv.
other example, and the 90% of the case, is active o disable a gamebject according to the state of a quest. the problem is if the gameobject is disable the sendMenssage dont work so i need a reference of the gameObject to call the SetActive(bool) method.
for now i only need this two ones but if i need another one i can easily extent to the base clase and put the behaviour desired.
then only need someone how tell to all this components that a quest was changed, for that i have a QuestTrackerController
if i change any quest status and call OnQuestChanged any Object who was watching the quest will update their visibility or their animatior. this is why i wanted the event, but i can create my own script to update the state of a quest and call the OnQuestChanged of QuestTrackerController.
by the way any advice in the code or improve will be great
my idea was that each object in the scene was "aware" about the quest state he is watching. and if i need to change some behaviour on a object go to the object instead each conversation node looking for where i change it.
for that i made a QuestTrackerObject is the base of each component how need any behaviour on a quest changed.
Code: Select all
public class QuestTrackerObject: MonoBehaviour
{
[QuestPopup] public string quest;
public virtual void Execute(){ }
}
so i can extend this base clase an create QuestTrackerAnimator and attach to the tv.
Code: Select all
[AddComponentMenu("QuestTracker/Animator")]
public class QuestTrackerAnimator : QuestTrackerObject
{
public AnimatorStringTuple[] objects;
public override void Execute ()
{
foreach(AnimatorStringTuple o in objects)
{
if(o.Item1 == QuestLog.GetQuestState(quest))
{
this.GetComponent<Animator> ().Play (o.Item2);
}
}
}
[System.Serializable]
public class AnimatorStringTuple : Tuple<QuestState, string> {}
Code: Select all
[AddComponentMenu("QuestTracker/ GameObject")]
public class QuestTrackerGameObject : QuestTrackerObject {
public GameObjectBoolTuple[] objects;
public override void Execute ()
{
foreach(GameObjectBoolTuple o in objects)
{
if(o.Item1 == QuestLog.GetQuestState(quest))
{
this.gameObject.SetActive (o.Item2);
}
}
}
[System.Serializable]
public class GameObjectBoolTuple : Tuple<QuestState, bool> {}
}
then only need someone how tell to all this components that a quest was changed, for that i have a QuestTrackerController
Code: Select all
public class TestQuestObjectController : MonoBehaviour
{
QuestTrackerObject[] questObjects;
//every time we goes to a new scene update behaviour.
public void OnLevelWasLoaded()
{
//cache of all objects at start of each new scene.
questObjects = Resources.FindObjectsOfTypeAll (typeof(QuestTrackerObject)) as QuestTrackerObject[];
OnQuestChanged ();
}
public void OnQuestChanged()
{
for(int i = 0; i<questObjects.Length; i++)
{
questObjects[i].Execute ();
}
}
}
by the way any advice in the code or improve will be great
Re: event OnQuestStatusChanged(string quest, QuestStatus status)?
That should work fine.
The problem is that quest states are just strings. As you said, you can create your own script to update quest states. For example, you could add this to TestQuestObjectController:
When you change a quest state in code, use TestQuestObjectController.SetQuestState(). For example:
When you change a quest state in a conversation, use Lua to call SetQuestState() in the dialogue entry's Script field. For example:
The problem is that quest states are just strings. As you said, you can create your own script to update quest states. For example, you could add this to TestQuestObjectController:
Code: Select all
public void SetQuestState(string questTitle, string state) {
QuestLog.SetQuestState(questTitle, QuestLog.StringToState(state));
OnQuestChanged();
}
void Start() {
// Register the function above with Lua:
Lua.RegisterFunction("SetQuestState", null, SymbolExtensions.GetMethodInfo(() => SetQuestState(string.Empty, string.Empty)));
}
Code: Select all
FindObjectOfType<TestQuestObjectController>().SetQuestState("Kill 5 Rats", "success");
- Script: SetQuestState("Kill 5 Rats", "success");
Re: event OnQuestStatusChanged(string quest, QuestStatus status)?
yes this will be work so well for me
thanks you for the help
thanks you for the help
Re: event OnQuestStatusChanged(string quest, QuestStatus status)?
mmmm i am receiving an error, it seem that the target cant go to null in the lua register, whats is the target in this context?
EDIT: i think i fixed passing "this" as target, (/// <param name='target'> Target object containing the registered method. Can be <c>null</c> if a static method.) but if i set the quest state in a script work while the dialogue is open, when i press X and call OnContinue, change the state T_T
Code: Select all
Dialogue System: Lua code 'SetQuestState("Quest1","active");' threw exception 'Non-static method requires a target.'
UnityEngine.Debug:LogError(Object)
Re: event OnQuestStatusChanged(string quest, QuestStatus status)?
Sorry, I cut and pasted without testing. I'm glad it wasn't too hard to fix.
I don't understand. Is it working the way you want it to work?alfonso wrote:...but if i set the quest state in a script work while the dialogue is open, when i press X and call OnContinue, change the state T_T
Re: event OnQuestStatusChanged(string quest, QuestStatus status)?
not at all
i start the quest with unnasigned state and i have a npc for test with two options (first change the quest to active and the second to success) if i select any of them the quest change well but when i finish the dialogue the quest goes to unnasigned again.
EDIT: i tried with Quest["Quest1"].State = "success" in the script field of the node and i have same issue, it look like that when i press the OnContinue button and close the dialogue it reset the value to default.
i tried to put to the quest other default start value (active) and when i choose the option to put to success, change fine, but when i close the dialogue goes to unnasigned.
i start the quest with unnasigned state and i have a npc for test with two options (first change the quest to active and the second to success) if i select any of them the quest change well but when i finish the dialogue the quest goes to unnasigned again.
EDIT: i tried with Quest["Quest1"].State = "success" in the script field of the node and i have same issue, it look like that when i press the OnContinue button and close the dialogue it reset the value to default.
i tried to put to the quest other default start value (active) and when i choose the option to put to success, change fine, but when i close the dialogue goes to unnasigned.
Re: event OnQuestStatusChanged(string quest, QuestStatus status)?
That's very strange. Do you have a Set Quest State On Dialogue Event component that's resetting the quest state? Or maybe another script somewhere that's resetting it? Or is another dialogue entry setting it back?
While playing, open the Dialogue Editor. On the Watch tab, add a Lua watch for your quest:
Tick Auto-Update. Then keep an eye on the quest state while you go through the conversation. Maybe it will help pinpoint when the quest is being reset.
While playing, open the Dialogue Editor. On the Watch tab, add a Lua watch for your quest:
Code: Select all
Quest["Your Quest Name"].State