Question: How to access selected node in Evaluate method when implementing custom Anim Graph Node

Hi, I am dealing with an issue is that I can not find a way to access the selected Skeleton Bone Index in my custom node from the Evaluate(ref Context context) method in class inheriting from AnimationGraph.CustomNode. Here are some snippets of my code:

First, I created the NodeFactory with the archetype as followed:

public static NodeArchetype GetMyCustomNodeArch()
        {
            return new NodeArchetype
            {
                // Define node title and metadata
                Title = "",
                Description = "",
                Flags = NodeFlags.AnimGraph,
                DefaultValues = new object[]
                {
                "MyCustomNode", // Runtime node typename
                "CustomNodes", // Group name
                new EmptyActor(), // Custom value stored per node
                      // ..here you can store more per-node data
                -1
                },
                
                // Define node visuals and elements
                Size = new Float2(250, 70),
                Elements = new[]
                {
                    NodeElementArchetype.Factory.Input(0, "Input", true, typeof(void), 0),
                    NodeElementArchetype.Factory.Input(1, "Actor", true, typeof(Actor), 1, 2),

                    NodeElementArchetype.Factory.Text(1, Constants.LayoutOffsetY * 2, "Target Node: "),
                    NodeElementArchetype.Factory.SkeletonBoneIndexSelect(Constants.BoxSize * 4, Constants.LayoutOffsetY * 2, 120, 3),

                    NodeElementArchetype.Factory.Output(0, "Output", typeof(void), 2),
                },
            };
        }

You can see that I have used SkeletonBoneIndexSelect to let Flax populate Skeleton Nodes. Now to the next snippet:

public override unsafe object Evaluate(ref Context context)
    {
        // Here node is getting called to evaluate the output for the given context

        // Evaluate the input bones pose
        var input = (Impulse*)(IntPtr)GetInputValue(ref context, 0);

        // Evaluate the input Actor
        var actor = HasConnection(ref context, 1) ? (Actor)GetInputValue(ref context, 1) : _defaultActor;
        

        // Get the output bones pose (cached internally to improve performance)
        var output = GetOutputImpulseData(ref context);

        // Copy the input and apply the scale to the root node (always the first one)
        CopyImpulseData(input, output);
        //output->Nodes[0].Name

        // Return the bone pose for further processing
        return new IntPtr(output);
    }

I wonder if I can extract the selected index (or name) of the skeleton bone in this method? Thanks a lot :smiley:

You can use Load method to read data from node (initData.Values) and you can cache some of it within that node object class to use it later during Evaluate.

Example code:

private string _nodeName;

public override void Load(ref InitData initData)
{
    int nodeIndex = (int)initData.Values[3]; // index from node values array
    var nodes = initData.BaseModel.Nodes;
    _nodeName = nodeIndex != -1 ? nodes[nodeIndex].Name : "";
}

(also you cannot use new EmptyActor() in node values as it can store only value-types)

1 Like

Thanks, it works now! :grinning_face_with_smiling_eyes:

Regarding the EmptyActor node values, is there another way I can store Actor-type within the custom node implementation?
My current use case is that I have a Anim Graph parameter, in a graph that parameter will be served as Input, then in my custom node, I will extract the Transform of that Actor, and then to perform additional logic.

Basically, I try to create a live-rigging solution where each bone/nodes can continously apply the transform of an target actor in the scene.

Anyway, here is the snippet:
image

To get it from node data then it would be better to store Actor as Guid Id reference but the current way with input field seams fine.

1 Like