Counting up for quest time
Counting up for quest time
Hi,
I have been looking at Timers and Counters but I can't work out how I would go about when I start a quest it starts a timer that counts up and then if you complete the quest step within 1 minute it activates the next step but if it takes 2 mins or more it activates a different step. Basically activating different branches of the quest depending on how long it takes you to do something.
Could I modify timer to do this or would it be better with a counter counting up each second?
Thank you
I have been looking at Timers and Counters but I can't work out how I would go about when I start a quest it starts a timer that counts up and then if you complete the quest step within 1 minute it activates the next step but if it takes 2 mins or more it activates a different step. Basically activating different branches of the quest depending on how long it takes you to do something.
Could I modify timer to do this or would it be better with a counter counting up each second?
Thank you
Re: Counting up for quest time
Hi,
The Timer quest action condition uses a counter internally. This way you can set conditions on the counter's value.
It counts down, but you could make a copy of it that counts up. Use it on two child nodes that go active at the same time. Set the condition on one to be true when the counter is >= 60, and on the other when the counter is >= 120.
When one of the nodes becomes True, use its True state Actions list to set the other node Inactive.
The Timer quest action condition uses a counter internally. This way you can set conditions on the counter's value.
It counts down, but you could make a copy of it that counts up. Use it on two child nodes that go active at the same time. Set the condition on one to be true when the counter is >= 60, and on the other when the counter is >= 120.
When one of the nodes becomes True, use its True state Actions list to set the other node Inactive.
Re: Counting up for quest time
Hi,
Thanks for the quick reply. Which script would it be that I would need to make a copy of and change? Is it TimerQuestCondition, QuestTimerManager or something else?
Sorry for the silly question!
Thanks for the quick reply. Which script would it be that I would need to make a copy of and change? Is it TimerQuestCondition, QuestTimerManager or something else?
Sorry for the silly question!
Re: Counting up for quest time
Hi,
TimerQuestCondition. I see I accidentally typed action instead of condition above. I just fixed that. Sorry for the confusion!
TimerQuestCondition. I see I accidentally typed action instead of condition above. I just fixed that. Sorry for the confusion!
Re: Counting up for quest time
Hey,
I'm sorry to be a pain but I don't think I'm doing the right things with the script. I've added a variable at the top for maxTime and then changed the Tick method to countup and stop when it hits maxtime but I'm not really sure what I'm doing. Is this the right kind of thing? I have a counter index in the conditions inspector, do I still need that there? I also can't work out where I would put the number for each quest condition that I would want it to be >=, do I need to create that as a variable in this script?
Thanks
I'm sorry to be a pain but I don't think I'm doing the right things with the script. I've added a variable at the top for maxTime and then changed the Tick method to countup and stop when it hits maxtime but I'm not really sure what I'm doing. Is this the right kind of thing? I have a counter index in the conditions inspector, do I still need that there? I also can't work out where I would put the number for each quest condition that I would want it to be >=, do I need to create that as a variable in this script?
Thanks
Spoiler
Code: Select all
namespace PixelCrushers.QuestMachine
{
/// <summary>
/// Quest condition that becomes true after a specified duration.
/// </summary>
[Serializable]
public class TimerQuestConditionCountUp : QuestCondition, IQuestTimer
{
public int maxTime = 999;
[Tooltip("Counter to track time elapsed.")]
[SerializeField]
private int m_counterIndex;
/// <summary>
/// Index of a counter defined in the quest. Inspect the quest's main info to view/edit counters.
/// </summary>
public int counterIndex
{
get { return m_counterIndex; }
set { m_counterIndex = value; }
}
public override string GetEditorName()
{
var counter = (quest != null) ? quest.GetCounter(counterIndex) : null;
return (counter != null) ? ("TimerUp: " + counter.name) : "TimerUp";
}
private QuestCounter m_counter = null;
public override void StartChecking(System.Action trueAction)
{
base.StartChecking(trueAction);
m_counter = (quest != null) ? quest.GetCounter(counterIndex) : null;
QuestTimerManager.RegisterTimer(this);
}
public override void StopChecking()
{
base.StopChecking();
QuestTimerManager.UnregisterTimer(this);
}
public void Tick()
{
if (m_counter == null) return;
m_counter.currentValue++;
if (m_counter.currentValue >= maxTime)
{
if (QuestMachine.debug) Debug.Log("Quest Machine: TimerQuestCondition '" + m_counter.name + "' timer ran out. Setting condition true.", quest);
SetTrue();
}
}
}
}
Re: Counting up for quest time
That looks right so far. You'll also need a custom editor script to draw the special dropdown menu to select the counter:
Then structure your quest similarly to this:
When the quest starts, all 3 nodes (Run Timer, Done <60sec, and Done <120sec) will become Active.
The Run Timer node has the timer condition that increments the counter. If it reaches the max value, the quest fails. If you don't want to fail the quest when it reaches the max value, just remove the Failure node.
The Done <60sec node has two conditions:
1. The actual quest completion condition (in this example, receiving a message "Did The Thing").
2. And a requirement that the counter is <= 60.
Same for Done<120sec except the counter must be > 60 and the counter must be <= 120.
TimerQuestConditionCountUpEditor.cs
Code: Select all
using UnityEngine;
using UnityEditor;
namespace PixelCrushers.QuestMachine
{
[CustomEditor(typeof(TimerQuestConditionCountUp), true)]
public class TimerQuestConditionCountUpEditor : QuestSubassetEditor
{
private string[] m_nameList = null;
protected override void OnEnable()
{
base.OnEnable();
if (target == null || serializedObject == null) return;
m_nameList = QuestEditorUtility.GetCounterNames();
}
protected override void Draw()
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("maxTime"));
QuestEditorUtility.EditorGUILayoutCounterNamePopup(serializedObject.FindProperty("m_counterIndex"), m_nameList);
if (GUILayout.Button("Refresh Counter Names")) m_nameList = QuestEditorUtility.GetCounterNames();
}
}
}
Then structure your quest similarly to this:
When the quest starts, all 3 nodes (Run Timer, Done <60sec, and Done <120sec) will become Active.
The Run Timer node has the timer condition that increments the counter. If it reaches the max value, the quest fails. If you don't want to fail the quest when it reaches the max value, just remove the Failure node.
The Done <60sec node has two conditions:
1. The actual quest completion condition (in this example, receiving a message "Did The Thing").
2. And a requirement that the counter is <= 60.
Same for Done<120sec except the counter must be > 60 and the counter must be <= 120.
Re: Counting up for quest time
Hi,
That's great, thank you very much. The Timer seems to be counting up properly and the fail state is activated if you don't complete it in time but it seems to always activate the first condition when I send the message even when it takes over 10 seconds or more. Do you have any idea what I could be doing wrong? It's probably something simple but I can't figure it out. If I take out the first condition it activates the 20 second one but only if at least 11 seconds have passed so that condition appears to be working if the first condition isn't there and the same with less than 30 it only works if the other 2 aren't there.
Thank you
That's great, thank you very much. The Timer seems to be counting up properly and the fail state is activated if you don't complete it in time but it seems to always activate the first condition when I send the message even when it takes over 10 seconds or more. Do you have any idea what I could be doing wrong? It's probably something simple but I can't figure it out. If I take out the first condition it activates the 20 second one but only if at least 11 seconds have passed so that condition appears to be working if the first condition isn't there and the same with less than 30 it only works if the other 2 aren't there.
Thank you
- Attachments
-
- QuestTreeTimer.png (93.01 KiB) Viewed 1604 times
Re: Counting up for quest time
While playing, keep the Quest Editor open and inspect the player so you can inspect the player's instance of the quest. Are all 4 nodes linked from Start active (blue)?
If you inspect the Quest Machine GameObject, tick Debug Settings > Debug, and then reproduce the issue, the Console logs (there will be many) may offer some insight.
If not, and if you're stuck, please feel free to send a reproduction project to tony (at) pixelcrushers.com along with step-by-step instructions on how to reproduce the issue.
If you inspect the Quest Machine GameObject, tick Debug Settings > Debug, and then reproduce the issue, the Console logs (there will be many) may offer some insight.
If not, and if you're stuck, please feel free to send a reproduction project to tony (at) pixelcrushers.com along with step-by-step instructions on how to reproduce the issue.
Re: Counting up for quest time
Hi,
Yes, they are all activating. Ok great I will give the Debug Logs a try.
Thanks for all your help
Edit -
I think the issue might be that when the timer hits the minimum number for a node it sets it to true and then it always stays true so even when the number goes into the next bracket when the message is received it picks the first true node even if it is not the one with the correct time. Is there some way I can set the nodes to false or inactive when the timer goes past their max time?
Thanks
Yes, they are all activating. Ok great I will give the Debug Logs a try.
Thanks for all your help
Edit -
I think the issue might be that when the timer hits the minimum number for a node it sets it to true and then it always stays true so even when the number goes into the next bracket when the message is received it picks the first true node even if it is not the one with the correct time. Is there some way I can set the nodes to false or inactive when the timer goes past their max time?
Thanks
Re: Counting up for quest time
Hi,
Can you use the Set Quest Node State quest action?
Can you use the Set Quest Node State quest action?