Action With Force Time Until Next Action
v1.0
An Action which inherits from ActionWithForceTimeUntilNextAction.cs will hold the ActionExecutor execution until it releases. This is used in WaitAction and WaitRandomAction and similar Actions.
This is likely not a very common Action type.
These Actions override ForceTimeUntilNextAction() to return true, which tells the ActionExecutor that the action itself controls when the next action can startβtimeBeforeNextAction becomes a forced value derived from the action's internal logic rather than a user-configurable setting.
The release mechanism works through three paths.
Natural completion occurs when the wait condition is satisfied and ExecuteInternal() finishes normallyβfor example, when a WaitAction reaches the end of its wait duration or a ConditionalStepActiondetects its condition has become true. The coroutine simply completes its loop and exits, signaling the ActionExecutor that the action is finished and the sequence can proceed to the next action.
Timeout happens when CheckForTimeoutOrRelease() detects that elapsed time has exceeded the configured timeoutDuration. When this occurs, the method triggers the configured TimeoutBehavior (Continue, Stop, Fail, or Restart) and returns true, causing the action to immediately yield break and end the coroutine. This provides a safety mechanism to prevent actions from waiting indefinitely when conditions never resolve.
Forced early release is triggered when ForceRelease() is called externally, which sets the forceEarlyRelease flag to true. The next time CheckForTimeoutOrRelease() is called in the wait loop, it detects this flag and behaves exactly like a timeoutβtriggering the configured TimeoutBehavior and returning true to end the coroutine. This allows external systems or user interactions to interrupt wait-style actions on demand.
What to override
ExecuteInternal()
β No
β
Execution flow is handled by the base class
OnActionStart()
β Yes (primary hook)
Begin waiting logic
Subscribe to events, start timers, initialize state
Release() / ForceComplete()
β Optional
Manually unblock the executor
Call when your condition is satisfied
CanExecute()
β Optional
Prevent execution under certain conditions
Return false to skip the action
OnRestart()
β Optional
Reset state if the action restarts
Must be restart-safe
OnCleanupExecution()
β Optional
Unsubscribe / clean up
Always clean up event listeners
Execution lifecycle
ActionExecutor begins the action
Base class blocks execution
OnActionStart() is called
set up timers
register callbacks
begin waiting logic
One of the following occurs:
Release() is called manually
maximum forced time expires (if configured)
action is cancelled
Action unblocks the executor
Cleanup runs
Next action begins
Critical Rules
Do not override
ExecuteInternal()The base class controls timing and blocking behavior.
You must call
Release()(or allow timeout)Forgetting this will permanently stall the action sequence.
Always unsubscribe in cleanup
Event listeners must be removed to avoid leaks and duplicate callbacks.
Restarts must be idempotent
If the action restarts, your
OnRestart()logic must not double-subscribe or duplicate state.
Minimal Example
Common mistakes (and how to avoid them)
β Overriding
ExecuteInternal()β Use
OnActionStart()instead.β Forgetting to call
Release()β The action sequence will never continue.
β Subscribing in
OnActionStart()but not unsubscribingβ Leads to memory leaks or multiple callbacks on restart.
β Using this for timed lerps or animations
β Use
ActionOverTimeinstead.
Last updated