Author a Material Graph
A guided example: create a Material and build its node graph in one atomic call, then apply it to an actor.
A guided example: create a Material and build its node graph in one atomic call, then apply it to an actor.
This builds an emissive material from nothing: create the asset, assemble its node graph in one atomic call, expose a parameter so it can be tuned without editing the graph, make an instance, and put it on something in the level. Every command is real and copy-pasteable.
cfa health_check.Blend mode and shading model are set at creation. Creating over an existing asset fails unless you pass --force, which is deliberate: silently overwriting a material somebody is using is worse than an error.
An opaque, default-lit material:
cfa create_material --name "M_Glow" --path "/Game/Materials" --blend-mode opaque --shading-model default_litOr a translucent, two-sided one:
cfa create_material --name "M_Glass" --path "/Game/Materials" --blend-mode translucent --two-sided truebuild_material_graph takes nodes and connections together and wires them in a single operation. Nodes are addressed by their index in the array you passed, and the material's own output pins are addressed by name with "to_node":"material".
A colour and an intensity multiplied into Emissive Color:
cfa build_material_graph --material-path "/Game/Materials/M_Glow" --nodes '[{"type":"Constant3Vector","pos_x":-600,"pos_y":0,"properties":{"Constant":"(R=0.1,G=0.6,B=1.0)"}},{"type":"ScalarParameter","pos_x":-600,"pos_y":180,"properties":{"ParameterName":"Intensity","DefaultValue":"5.0"}},{"type":"Multiply","pos_x":-300,"pos_y":60}]' --connections '[{"from_node":0,"to_node":2,"to_pin":"A"},{"from_node":1,"to_node":2,"to_pin":"B"},{"from_node":2,"to_node":"material","to_pin":"EmissiveColor"}]'Multiply or MaterialExpressionMultiply, list them and read the pins first. get_expression_type_info returns a node's real input and output pins, which is what stops a connection silently going nowhere.Search the available expression types:
cfa list_material_expression_types --filter "Multiply"See a type's real pins and properties before wiring it:
cfa get_expression_type_info --type-name "Multiply"See which material output pins are available and connected:
cfa get_available_material_pins --material-path "/Game/Materials/M_Glow"By default the call clears the existing graph first, which makes a rebuild safe and repeatable. Pass --clear-existing false to append to a graph instead of replacing it.
A material that builds is not necessarily a material that works. Three checks catch almost everything: does it compile, are there orphaned nodes, and did the connections land where you meant.
Compilation errors, if any:
cfa get_material_errors --material-path "/Game/Materials/M_Glow"Find orphaned and dead-end nodes:
cfa validate_material_graph --material-path "/Game/Materials/M_Glow"Read the graph back with its connections:
cfa get_material_graph_nodes --material-path "/Game/Materials/M_Glow" --verbosity connectionsTrace what actually feeds a node:
cfa trace_material_connection --material-path "/Game/Materials/M_Glow" --node-index 2 --direction upstreamBecause step 2 exposed Intensity as a ScalarParameter, variants no longer need graph edits. A Material Instance overrides parameters and costs nothing to compile, which is the normal way to ship ten looks from one material.
Create an instance with an override:
cfa create_material_instance --parent-path "/Game/Materials/M_Glow" --name "MI_Glow_Hot" --scalar-params '{"Intensity":25.0}'Change a parameter later:
cfa set_material_instance_parameter --material-path "/Game/Materials/MI_Glow_Hot" --param-name "Intensity" --param-type scalar --value 40See what the parent exposes:
cfa get_material_info --material-path "/Game/Materials/M_Glow" --include parametersCheck the slots first, because assigning to slot 0 on a mesh with five slots is a common way to wonder why nothing changed.
See the material slots on a placed actor:
cfa get_material_slots --actor "Floor"Assign it to that actor:
cfa set_materials_batch --actor "Floor" --material "/Game/Materials/MI_Glow_Hot"Or a named slot on a Blueprint component:
cfa set_materials_batch --blueprint-path "/Game/BP/BP_Chair.BP_Chair" --component "Mesh" --slot-name "Seat" --material "/Game/Materials/MI_Glow_Hot"Or many actors at once by prefix:
cfa set_materials_batch --name-prefix "Wall_" --slot 0 --material "/Game/Materials/M_Glow"The node was created but nothing is connected. The pin name was wrong. Pin names are exact and case sensitive, and a bad one is not an error, it is simply a connection that does not happen. Run get_expression_type_info for the node and get_available_material_pins for the material output.
The material looks black. Usually nothing reached the output you expected, or an emissive value is too low to see. Run validate_material_graph first: a dead-end node is the usual cause.
Creating the material failed. An asset already exists at that path. Use a different name, or pass --force if you really do mean to replace it.
The instance ignores a parameter. The name must match the ScalarParameter or VectorParameter in the parent exactly. Confirm with get_material_info --include parameters.