BaseWaitAction
BaseWaitAction is an abstract base class for actions designed to pause or delay execution within a state machine flow.
It provides the default update mode setup used by wait-style actions such as WaitForSeconds, WaitForNextFrame, and WaitForRandomTime.
Core Functionality
The class provides:
Wait Update Mode Setup
BaseWaitAction sets the appropriate UpdateModes for a wait action:
namespace HutongGames.PlayMaker.Actions
{
public abstract class BaseWaitAction : BaseAction
{
public override UpdateMode DefaultUpdateMode => UpdateMode.UpdateEveryFrame | UpdateMode.Blocking;
public override UpdateMode RequiredUpdateModes => DefaultUpdateMode;
public override bool CanFinish => true;
}
}
Every Frame Updates
BaseWaitAction uses UpdateMode.UpdateEveryFrame, which means the action is updated every frame until it finishes.
This is the usual behavior for wait-style actions because they need to keep checking whether their wait condition has been met.
Blocking
BaseWaitAction also includes the Blocking flag.
This means the wait action prevents later actions in the same state from starting until the wait has finished.
This is what makes actions like WaitForSeconds useful for sequencing behavior.
For example:
WaitForSecondsPlay SoundSend Event
In this case, Play Sound and Send Event will not start until the wait action finishes.
Can Finish
BaseWaitAction allows inheritors to finish normally:
Wait actions usually call Finish() when the wait time has elapsed or when the condition they are watching becomes true.
Typical Pattern
Actions that inherit from BaseWaitAction usually follow this pattern:
- Initialize timer or state in
OnStart() - Check progress or condition in
Execute() - Call
Finish()when the wait is over
Many wait actions also update the Progress property so the current completion status can be shown in the editor.
Example
WaitForSeconds is a typical example:
using System;
using UnityEngine;
namespace HutongGames.PlayMaker.Actions
{
[Serializable]
[ActionCategory(Category.Sequence)]
[ActionDescription("Wait before running more actions.")]
public class WaitForSeconds : BaseWaitAction
{
[DefaultValue(1f)]
[Tooltip("Time to wait in seconds.")]
public FloatVar Seconds;
[DefaultValue(false)]
[Tooltip("Use unscaled realtime. When enabled, this wait is not affected by Time.timeScale.")]
public BoolVar UseRealtime;
private float _elapsedTime;
private float _startTime;
private float CurrentTime => UseRealtime.Value
? TimeHelper.RealtimeSinceStartup
: InFixedUpdate ? Time.fixedTime : Time.time;
public override void OnStart()
{
_elapsedTime = 0;
_startTime = CurrentTime;
}
public override void Execute()
{
_elapsedTime = Mathf.Max(0f, CurrentTime - _startTime);
if (_elapsedTime > Seconds.Value)
{
Progress = 1;
Finish();
}
else
{
Progress = Seconds.Value > 0 ? _elapsedTime / Seconds.Value : 1;
}
}
}
}
With this setup, the base class handles the sequencing behavior through the update mode flags, and the derived action only needs to define when the wait starts and when it is complete.
When To Use It
Use BaseWaitAction when your action:
- delays later actions in the same state
- waits for a time interval
- waits for a condition to become true
- should finish automatically when the wait condition is met
If an action is only reacting to an external callback, BaseOnEventAction is usually a better fit than BaseWaitAction.