Documentação do Steamworks
Action Set Layers
Action Set Layers are optional sets of action bindings which can be overlaid upon an existing set of controls. In contrast to Action Sets, layers draw their actions from the Action Set they exist within and do not wholesale replace what is already active when applied, but apply small modifications. These can consist of setting changes as well as adding or removing bindings from the base action set. More than one layer can be applied at a time and will be applied consecutively.

There is technically no limit to how many layers can be active at once, but as a practical matter, having too many layers in the configurator will be confusing for players.

Note that:
  • Activating an action set that's already active will have no effect on its layers.
  • Activating a new action set will clear all active layers from the old set.
  • Activating an action set layer that is already active will have no effect.
  • Activating an action set layer that is already active will not change its order in the stack.
  • Deactivating an action set layer, and then activating it, will set it to the top of the stack.
  • Chamar a função ActivateActionSetLayer não é dispendioso e pode ser chamada repetidamente sem problemas (mas leia o aviso abaixo).

    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.

    action_set_layers_basic_1.png

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

    action_set_layers_sniper_2.png

    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.

    action_set_layers_vehicle_1.png

    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.

    action_set_layers_scope.png

    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.

    action_set_layers_result_2.png

    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:

    add_action_layer.png

    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:

    bind_action_set.png

    This brings up the action set activation menu:

    change_action_set.png

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

    apply_action_set_layer.png

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

    select_action_set_layer.png

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