Search Results for

    Show / Hide Table of Contents

    Executable Function

    You can define ExecutableFunction in three ways.

    Instance Function

    For instance method, add ExecutableFunctionAttribute directly.

    public class MyComponent: Component
    {
        [ExecutableFunction]
        public void DoSomething(int arg1, float arg2)
        {
            // DoSomething
        }
    }
    

    Static Function

    For static method, create a new partial class and implement ExecutableFunctionLibrary to add static executable functions, then add ExecutableFunctionAttribute.

    You must add partial modifier to let source generator work. Source generator will register static function pointer to the flow reflection system instead of using MethodInfo to enhance runtime performance.

    public partial class UnityExecutableFunctionLibrary: ExecutableFunctionLibrary
    {
        // IsScriptMethod will consider UObject as function target type
        // IsSelfTarget will let graph pass self reference as first parameter if self is UObject
        [ExecutableFunction(IsScriptMethod = true, IsSelfTarget = true), CeresLabel("GetName")]
        public static string Flow_UObjectGetName(UObject uObject)
        {
            return uObject.name;
        }
    
        // ResolveReturnAttribute will let graph editor display return type by this parameter result
        // Only support SerializedType<T> from Chris.Serialization
        [ExecutableFunction]
        public static UObject Flow_FindObjectOfType(
            [ResolveReturn] 
            SerializedType<UObject> type)
        {
            return UObject.FindObjectOfType(type);
        }
    }
    

    Always Included Assemblies

    Flow will include assemblies matched by Always Included Assmebly Wildcards defined in Project Settings/Ceres/Flow Settings into internal reflection system which allows you to invoke method without adding attribute.

    Conventions and Restrictions

    1. For methods defined in the same class and its inheritance hierarchy, methods with the same name and the same parameter count can only have one marker ExecutableFunctionAttribute.

    2. For methods with the same name but different number of parameters in 1, recommend to use CeresLabelAttribute to distinguish their names displayed in the editor, or they will be named with full method signature.

    3. Generic methods are not supported using ExecutableFunctionAttribute, they need to be defined in a generic node which will be explained in Advanced/Generic Node below.

    4. Try to keep the number of input parameters less than or equal to 6, otherwise the editor will use Uber nodes to support method calls with any parameters. The default parameter values ​​will not be serialized and the runtime overhead will be greater.

    Wrong example:

    [ExecutableFunction]
    public static string Flow_GetName(UObject uObject)
    {
        return uObject.name;
    }
    
    [ExecutableFunction]
    public static string Flow_GetName(Component component)
    {
        return component.name;
    }
    
    [ExecutableFunction]
    public static void Flow_DoSomething(string arg1, int arg2)
    {
        
    }
    
    [ExecutableFunction]
    public static string Flow_DoSomething(string arg1)
    {
        
    }
    

    Correct example:

    [ExecutableFunction]
    public static string Flow_UObjectGetName(UObject uObject)
    {
        return uObject.name;
    }
    [ExecutableFunction]
    public static string Flow_ComponentGetName(Component component)
    {
        return component.name;
    }
    
    [ExecutableFunction, CeresLabel("DoSomething with 2 Arguements")]
    public static void Flow_DoSomething(string arg1, int arg2)
    {
        
    }
    
    [ExecutableFunction]
    public static string Flow_DoSomething(string arg1)
    {
        
    }
    

    Next Steps

    • Learn about Function Library for optimal performance with static functions
    • Explore Generic Nodes for generic method support
    • Check Custom Nodes for creating reusable node logic
    • See Code Generation for technical details on function registration
    • Improve this Doc
    In This Article
    Back to top Copyright © 2025 AkiKurisu
    Generated with DocFX