Calling ActivateActionSetLayer is cheap and can be safely called repeatedly (but see callout below)Careful with multiple layers!
Just because you can re-apply action set layers every frame doesn't mean you should, especially if you're using more than one layer. The last layer applied will override any conflicting information that came before, so take special care to apply them in the correct order. Your code could easily have race conditions or other subtle timing bugs that could swap the order.
Action set layers are intended for narrow use cases and a good practice is to apply and remove them only on specific game state changes.
For games with native Steam Input support, the developer can define specific action set layers activated by the game's code. Additionally, in legacy mode, players can define their own action set layers and the inputs that trigger them, just as they can define their own player-triggered action sets.A practical example
Imagine a class-based shooter with vehicles. This game has native Steam Input support and makes use of action set layers. For basic gameplay, a base action set is always active and covers running around, picking up items, jumping, etc.

When the player selects a class, the appropriate layer is added, e.g. "sniper"

The code for this might look something like:
void changeClass(EClassID myClass)
{
if(myClass == SNIPER)
{
SteamInput()->ActivateActionSetLayer( controllerHandle1, sniperLayerHandle );
}
//logic for other classes
}
If the player enters or exits a vehicle, the controls for the vehicle layer are activated/deactivated on those state changes, adding or removing new controls for vehicle specific functions.

void changeVehicle(EVehicleID myVehicle, bool entering)
{
InputActionSetHandle_t layerHandle;
if(myVehicle == AUTOMATIC)
{
layerHandle = automaticHandle; //automatic transmission -- steer, gas, brake
}
else if(myVehicle == STICK_SHIFT)
{
layerHandle = stickShiftHandle; //manual transmission -- steer, gas, brake, clutch, shift gears, etc.
}
if(entering)
{
SteamInput()>ActivateActionSetLayer( controllerHandle1, layerHandle ); //apply the vehicle's action set layer when you get in it
}
else
{
SteamInput()>DeactivateActionSetLayer( controllerHandle1, layerHandle ); //remove the vehicle's action set layer when you get out of it
}
}
In this game, players can use their weapon even when riding in a vehicle. So when the sniper uses the scope on the sniper rifle, this activates a third action set layer, regardless of whether the player is on foot or riding in a vehicle.

void useScope(bool entering)
{
if(entering)
{
SteamInput()->ActivateActionSetLayer( controllerHandle1, scopeHandle ); //apply the scoped-in layer when you scope in
}
else
{
SteamInput()->DeactivateActionSetLayer( controllerHandle1, scopeHandle ); //remove the scoped-in layer when you lower the scope
}
}
Here's how all the layers combine.

Note how layers can not only add new actions on top of underyling layers, they can also override previous bindings -- in this case, the vehicle-specific "brake" and "gas" actions override the basic layer's "jump" and "interaction" actions, and "steer" overrides the "move" action bound to the trackpad and joystick on the base layer, and in turn is overriden by the "aim" action from the scoped-in action set layer. Once all three action set layers are stacked on top, the only remaining action from the base set is "shoot."Legacy Mode
You create action set layers almost exactly like regular action sets. Simply click on the button "Add Action Layer" in the configurator:

From here you can give your action set layer a name and specify bindings for it. Since this is a legacy action set layer, the game has no knowledge of it and the player will have to activate it themselves. Decide what input should trigger the action set layer, and open the binding menu, then click the action set activation icon, which is the leftmost special icon:

This brings up the action set activation menu:

In this case we want to apply a layer, not activate an action set. We'll select "Apply Action Layer" from the dropdown menu:

Finally, we need to select which layer we want to apply:

We can use the same procedure to assign a separate binding to remove the layer.