Extension
Authoring Custom Instructions
Add a supported typed operation that designers can run inside an Action.
- Audience
- Unity developers
- Time
- 25 minutes
- Requires
- C#, Flow Core runtime assembly access, and codegen access
- Modules
- Flow Core, C#
On this page
Create a custom Instruction when Flow Core should perform a project-specific operation inside an Action list. Keep the runtime contract typed, explicit, and free of editor dependencies.
Define runtime data and behavior
The Instruction below resolves a typed string and logs it:
using System;
using System.Threading.Tasks;
using UnityEngine;
using TwoCatsCode.FlowCore;
[FlowInstruction("Log Project Message", "Project", "Log a typed string value.")]
public sealed class InstructionLogProjectMessage : IInstruction
{
[Serializable]
public sealed class Data : InstructionData
{
public FlowValueGetStringData Message = new();
public override InstructionData Clone()
{
return new Data
{
Message = Message?.Clone() as FlowValueGetStringData
?? new FlowValueGetStringData()
};
}
public override string Summary(FlowContext context)
{
return $"Message: {Message?.Summary(context)}";
}
}
private readonly Data data;
public InstructionLogProjectMessage(Data data)
{
this.data = data ?? new Data();
this.data.Message ??= new FlowValueGetStringData();
}
public ValueTask<InstructionResult> ExecuteAsync(FlowContext context)
{
if (FlowValueResolveHelper.TryResolveValue(
data.Message, context, out string value, out _))
{
Debug.Log(value);
}
return new ValueTask<InstructionResult>(InstructionResult.Continue);
}
public string Summary(FlowContext context) => string.Empty;
}
Preserve the contract
- Put the type in a runtime assembly.
- Keep serialized fields inside
Data. - Deep-clone nested Flow value data.
- Resolve typed values through the supplied
FlowContext. - Return an intentional
InstructionResult. - Keep editor UI code out of runtime assemblies.
- Avoid allocations and reflection in hot paths.
Register and verify
- Run the Flow Core code-generation and registry workflow used by the project.
- Wait for Unity to recompile.
- Add an Action to a test graph.
- Search for
Project > Log Project Messagein the Instruction picker. - Bind a literal and a Blackboard-backed string in separate tests.
- Enter Play Mode and confirm both resolve.
此处插图应该是 Action Instruction Picker 中 Project > Log Project Message 的截图;同时展示添加后的 typed Message 字段与 Summary,并框选自定义分类和运行结果。
Common Mistakes
- Registering the runtime type but not refreshing editor and runtime registries.
- Returning shared nested
DatafromClone. - Storing per-execution state on the shared graph asset or Instruction data.
- Adding UnityEditor references to the runtime assembly.
- Swallowing a failed value resolution while implying the operation succeeded.
- Using reflection in a frequently executed Instruction.
What You Built
You added a typed runtime operation that designers can place inside any Action, configure with literals or Blackboard values, serialize with a graph, and execute without editor-only dependencies.