Overriding Action Values at Runtime
v1.0
Runtime overrides let you change the values an Action uses without modifying the asset. This is ideal for:
Contextual tweaks (e.g., speed up a move if the player is wounded)
Live tuning from UI sliders / difficulty systems
One-off variations per target
Overrides live on the
ActionExecutor
’s items, not on the ScriptableObject assets. Changing an override affects the next instantiation of that Action in the sequence. It does not mutate the asset and does not change a currently-running instance.
Prerequisites
Action fields must be marked with
[CanOverride]
or[MustOverride]
in the Action class.Your executor must contain an ActionItem that references that Action.
You can call the API directly on
ActionExecutor
, or through convenience wrappers onActionRunner
(shown below).
Override Methods
These are the main methods available on ActionExecutor
:
public bool SetFieldOverride<TAction>(string fieldName, object value, bool turnOverrideOn = true) where TAction : Action;
public bool SetFieldOverride(System.Type actionType, string fieldName, object value, bool turnOverrideOn = true);
public bool SetFieldOverrideByActionName(string actionName, string fieldName, object value, bool turnOverrideOn = true);
public int SetFieldOverrideForAllActions<TAction>(string fieldName, object value, bool turnOverrideOn = true) where TAction : Action;
public int SetFieldOverrideForAllActions(System.Type actionType, string fieldName, object value, bool turnOverrideOn = true);
public bool SetFieldOverrideEnabled<TAction>(string fieldName, bool enabled) where TAction : Action;
public bool SetFieldOverrideEnabled(System.Type actionType, string fieldName, bool enabled);
public bool SetFieldOverrideEnabledByActionName(string actionName, string fieldName, bool enabled);
public bool TryGetFieldOverride<TAction, TValue>(string fieldName, out TValue value) where TAction : Action;
public bool IsFieldOverrideEnabled<TAction>(string fieldName) where TAction : Action;
public bool IsFieldOverrideEnabled(System.Type actionType, string fieldName);
public bool ClearFieldOverrides<TAction>() where TAction : Action;
public bool ClearFieldOverrides(System.Type actionType);
public List<string> GetOverridableFieldNames<TAction>() where TAction : Action;
public List<string> GetOverridableFieldNames(System.Type actionType);
Example – change a float at runtime
// Assume MoveAction has [CanOverride] float "speed"
// Assume healthMotion field is an ActionExecutor
healthMotion.SetFieldOverride<MoveAction>("speed", 7.5f); // set & enable
healthMotion.SetFieldOverrideEnabled<MoveAction>("speed", true); // (optional) explicitly enable
Example – drive from a UI Slider
public class HealthIndicatorSpeedUI : MonoBehaviour
{
public ActionExecutor healthMotion;
public void OnSliderChanged(float value)
{
healthMotion.SetFieldOverride<MoveAction>("speed", value, true);
}
}
ActionRunner.cs
has a section for field overrides which you can copy/paste if you'd like, into your own code, replacing "alwaysRunningActions" with your own ActionExecutor
field name.
How overrides are applied
When an item executes, the executor instantiates a runtime copy of the Action asset.
The item’s
ActionOverrides
are then applied to that instance before execution:// (inside ActionExecutor) var actionInstance = Instantiate(actionItem.actionAsset); actionItem.overrides.ApplyToAction(actionInstance);
This means any change you make to the item’s overrides affects the next instantiation.
Already-running instances keep the values they were instantiated with.
If you need the new value to take effect immediately for an always-running sequence, call
RestartActions()
on theActionExecutor
(orActionRunner.RestartAlwaysRunningActions()
), which will cancel current instances and start fresh using the updated overrides.
Choosing a lookup strategy
Use one of these approaches to target actions:
Enabling / disabling an override flag
Setting a value does not always imply enabling its override. Use the turnOverrideOn
parameter or explicit enable:
runner.SetFieldOverride<MoveAction>("speed", 8f, turnOverrideOn: true);
// or toggle explicitly
runner.SetFieldOverrideEnabled<MoveAction>("speed", true);
Disable to fall back to the Action’s current serialized value:
runner.SetFieldOverrideEnabled<MoveAction>("speed", false);
Inspecting overrides
if (runner.TryGetFieldOverride<MoveAction, float>("speed", out var v))
{
Debug.Log($"Speed override is {v}");
}
bool isOn = runner.IsFieldOverrideEnabled<MoveAction>("speed");
Get a list of overridable fields for a given Action type:
var fields = runner.GetOverridableFieldNames<MoveAction>();
// e.g., ["speed", "accel", "decel"]
Clearing overrides
runner.ClearFieldOverrides<MoveAction>(); // first MoveAction in the list
runner.ClearFieldOverrides(typeof(MoveAction)); // non-generic
Timing & restarts (important)
Overrides affect future instantiations. If your Action is long-running, you won’t see changes immediately.
To apply new overrides to a long-running loop or always-running set:
Call
ActionExecutor.RestartActions()
; orIf using
ActionRunner
:runner.RestartAlwaysRunningActions();
The restart flow updates the run-key, cancels the current sequence, calls
OnRestart()
on each live Action instance, and then starts fresh using the latest overrides.
Flow diagram (how a new override takes effect)

Last updated
Was this helpful?