Action Over Time With Base Value
v1.0
This class extends ActionOverTime with restoration capabilities for actions that modify properties and need to return to original values (See examples: MoveAction, RotateAction, ScaleAction).
What to override
ExecuteInternal()
✅ Yes (required)
Implement the over-time behavior
Must begin with yield return base.ExecuteInternal();
SaveBaseValuesForTargets() (or equivalent hook)
⭕ Optional (recommended)
Cache per-target base/original values
Should run on fresh start only (guarded by base flags/keys)
LoadBaseValuesForTarget() (or equivalent)
⭕ Optional
Read cached base/original values
Use target-scoped keys; never execution scope
ComputeEndValueFromBase()(or goal builder)
⭕ Optional (recommended)
Compute end goal using cached base
Compute once at start, then interpolate
Tick(float t) (or per-frame apply)
⭕ Optional (recommended)
Apply interpolation each frame
Use normalized progress t 0→1
OnActionStart()
⭕ Optional
Run-level initialization
Don’t recache base here unless it’s guarded as “fresh only”
OnRestart()
⭕ Optional
Reset per-run progress
Must not overwrite base/original values
OnCleanupExecution()
⭕ Optional
Cleanup transient state
Base/original values typically remain cached
CanExecute()
⭕ Optional
Validation
Return false to skip
Target interface methods (GetTargets etc.)
⭕ Optional
If action operates on targets
Use standard selection helpers
Recommended Pattern
Instead of manually managing contexts and base values, use the built-in helper methods:
CreateContext<TValue>() — Creates typed context with automatic Blackboard key initialization
var ctx = CreateContext(transform, t => t.position, "Position");
// Returns ActionContext<Vector3> with BaseValueKey, HasBaseValueKey, ShouldStopKey pre-initializedStartAnimationOn<TTarget, TValue>() — Starts animation on a fresh (non-active) target
Automatically saves base value if not already saved
Sets
ShouldStop = falseDelegates to your animation coroutine
RestartAnimationOn<TTarget, TValue>() — Restarts animation on active target
Sets
ShouldStop = trueto signal existing animation to stopWaits one frame for graceful shutdown
Preserves original base value (doesn't re-save)
Resets
ShouldStop = falseand starts new animation
IsTargetActive<TTarget>() — Checks if target is currently being animated
Component Variants (For Non-Transform Targets)
For actions targeting components like Light, AudioSource, Image, etc., use the component-specific helpers:
CreateContextForComponent<TComponent, TValue>()— Same asCreateContextbut for any ComponentStartAnimationOnComponent<TComponent, TValue>()— Same asStartAnimationOnfor componentsRestartAnimationOnComponent<TComponent, TValue>()— Same asRestartAnimationOnfor components
Example
Critical Rules
✅ DO use target-scoped keys for base values: CreateTargetKey<T>(targetId, "BasePosition")
✅ DO check HasBase flag before saving to preserve original base across loops
✅ DO use StartAnimationOn / RestartAnimationOn helpers for Actions
✅ DO check ctx.ShouldStopKey each frame in your animation loop for graceful restarts
❌ DON'T use execution-scoped keys for base values (they’re execution-namespaced and effectively disposable, but not automatically purged—don’t use them for long-lived base values).
❌ DON'T unconditionally save base values (overwrites original with animated values)
❌ DON'T clear base values in OnCleanupExecution() (they must persist across executions)
If you generate many unique execution keys, consider reusing keys or explicitly removing them when appropriate.
Last updated