Actions
How to use Actions
Actions are a simple way to add interactions in your scenes. An action is launched when its trigger is fired. For instance, you can specify that when the user clicks (or touches) a mesh, an action is executed.
To use actions, you have to attach a BABYLON.ActionManager to a mesh or to your scene:
import { ActionManager } from "@babylonjs/core/Actions/actionManager";mesh.actionManager = new ActionManager(scene);Once the ActionManager is created, you can start registering actions:
import { ActionManager } from "@babylonjs/core/Actions/actionManager";import { InterpolateValueAction } from "@babylonjs/core/Actions/interpolateValueAction";import { Color3 } from "@babylonjs/core/Maths/math.color";mesh.actionManager.registerAction(new InterpolateValueAction(ActionManager.OnPickTrigger, light, "diffuse", Color3.Black(), 1000));For instance, this action will animate the light.diffuse property to black in 1000ms when the user picks the mesh.
You can also chain actions:
import { ActionManager } from "@babylonjs/core/Actions/actionManager";import { SetValueAction } from "@babylonjs/core/Actions/directActions";import { InterpolateValueAction } from "@babylonjs/core/Actions/interpolateValueAction";import { Color3 } from "@babylonjs/core/Maths/math.color";mesh.actionManager.registerAction(new InterpolateValueAction(ActionManager.OnPickTrigger, light, "diffuse", Color3.Black(), 1000)).then(new SetValueAction(ActionManager.NothingTrigger, mesh.material, "wireframe", false));In this case, the first click will animate the light.diffuse property, and the second click will set mesh.material.wireframe to false.
The third click will start again and animate the light.diffuse property, and so on...
Finally, you can add a condition to your actions. In this case, actions are launched when the trigger is fired if the condition is true:
import { ActionManager } from "@babylonjs/core/Actions/actionManager";import { PredicateCondition } from "@babylonjs/core/Actions/condition";import { InterpolateValueAction } from "@babylonjs/core/Actions/interpolateValueAction";import { Color3 } from "@babylonjs/core/Maths/math.color";mesh.actionManager.registerAction(new InterpolateValueAction(ActionManager.OnPickTrigger, camera, "alpha", 0, 500, new PredicateCondition(mesh.actionManager, function () { return light.diffuse.equals(Color3.Red());})));In this example, the camera.alpha property will be animated to 0 in 500ms when the user clicks the mesh only if the light.diffuse property is equal to red.
Triggers
Currently, there are 14 different triggers available for meshes, and three for scenes.
The triggers available for meshes are:
BABYLON.ActionManager.NothingTrigger: Never raised. Used for sub-actions with theaction.thenfunction.BABYLON.ActionManager.OnPickTrigger: Raised when the user touches/clicks on a mesh.BABYLON.ActionManager.OnDoublePickTrigger: Raised when the user double touches/clicks on a mesh.BABYLON.ActionManager.OnPickDownTrigger: Raised when the user touches/clicks down on a mesh.BABYLON.ActionManager.OnPickUpTrigger: Raised when the user touches/clicks up on a mesh.BABYLON.ActionManager.OnPickOutTrigger: Raised when the user touches/clicks down on a mesh and then moves off the mesh.BABYLON.ActionManager.OnLeftPickTrigger: Raised when the user touches/clicks on a mesh with the left button.BABYLON.ActionManager.OnRightPickTrigger: Raised when the user touches/clicks on a mesh with the right button.BABYLON.ActionManager.OnCenterPickTrigger: Raised when the user touches/clicks on a mesh with the center button.BABYLON.ActionManager.OnLongPressTrigger: Raised when the user touches/clicks up on a mesh for a long period of time in milliseconds (defined by BABYLON.Scene.LongPressDelay).BABYLON.ActionManager.OnPointerOverTrigger: Raised when the pointer is over a mesh. Raised just once.- Warning: if you set
AbstractMesh.pointerOverDisableMeshTestingtotrue, this trigger will be triggered every time you move the mouse and you are still over the mesh!
- Warning: if you set
BABYLON.ActionManager.OnPointerOutTrigger: Raised when the pointer is no longer over a mesh. Raised just once.BABYLON.ActionManager.OnIntersectionEnterTrigger: Raised when the mesh intersects with a specific mesh. Raised just once.BABYLON.ActionManager.OnIntersectionExitTrigger: Raised when the mesh no longer intersects with a specific mesh. Raised just once.
Note that the two intersection triggers require you to specify a specific mesh, which can be done like so:
import { ActionManager } from "@babylonjs/core/Actions/actionManager";import { SetValueAction } from "@babylonjs/core/Actions/directActions";import { Vector3 } from "@babylonjs/core/Maths/math.vector";mesh.actionManager.registerAction(new SetValueAction({ trigger: ActionManager.OnIntersectionEnterTrigger, parameter: { mesh: otherMesh, usePreciseIntersection: true, },}, mesh, "scaling", new Vector3(1.2, 1.2, 1.2)));Note the optional usePreciseIntersection property. If you don't want to use precise intersections, you can simply pass the mesh being targeted as the value of the parameter property:
import { ActionManager } from "@babylonjs/core/Actions/actionManager";import { SetValueAction } from "@babylonjs/core/Actions/directActions";import { Vector3 } from "@babylonjs/core/Maths/math.vector";mesh.actionManager.registerAction(new SetValueAction({ trigger: ActionManager.OnIntersectionEnterTrigger, parameter: otherMesh,}, mesh, "scaling", new Vector3(1.2, 1.2, 1.2)));The triggers available for scenes are:
BABYLON.ActionManager.OnEveryFrameTrigger: Raised once per frame.BABYLON.ActionManager.OnKeyDownTrigger: Raised when a key is pressed.BABYLON.ActionManager.OnKeyUpTrigger: Raised when a key is released.
Both the OnKeyUpTrigger and OnKeyDownTrigger triggers accept a string parameter value, which is compared to the event's sourceEvent.key value.
This allows you to create key triggers that will only trigger on specific keys, like so:
import { ActionManager } from "@babylonjs/core/Actions/actionManager";import { ExecuteCodeAction } from "@babylonjs/core/Actions/directActions";scene.actionManager.registerAction(new ExecuteCodeAction({ trigger: ActionManager.OnKeyUpTrigger, parameter: "r",}, function () { console.log("r button was pressed");}));For more advanced use cases, you can pass a callback function as a parameter value (available since 5.47.0):
import { ActionManager } from "@babylonjs/core/Actions/actionManager";import { ExecuteCodeAction } from "@babylonjs/core/Actions/directActions";scene.actionManager.registerAction(new ExecuteCodeAction({ trigger: ActionManager.OnKeyUpTrigger, parameter: function (actionEvent) { return actionEvent.sourceEvent.key === "R"; },}, function () { console.log("R button was pressed");}));Available Actions
Most actions have a propertyPath property. This string defines the path to the property affected by the action.
You can use direct values like position or diffuse, but you can also provide complex paths like position.x.
BABYLON.SwitchBooleanAction(trigger, target, propertyPath, condition): Switches a boolean property.BABYLON.SetValueAction(trigger, target, propertyPath, value, condition): Sets a direct value for a property.BABYLON.IncrementValueAction(trigger, target, propertyPath, value, condition): Adds a number to a number property.BABYLON.PlayAnimationAction(trigger, target, from, to, loop, condition): Plays an animation on a target.BABYLON.StopAnimationAction(trigger, target, condition): Stops any animation being played by the target.BABYLON.DoNothingAction(trigger, condition): Does nothing :)BABYLON.CombineAction(trigger, children[], condition): Executes multiple actions simultaneously. The children property must be an array of actions.BABYLON.ExecuteCodeAction(trigger, func, condition): Executes code.BABYLON.SetParentAction(trigger, target, parent, condition): Sets the parent of the target.BABYLON.PlaySoundAction(trigger, sound, condition): Plays a given sound.BABYLON.StopSoundAction(trigger, sound, condition): Stops a given soundBABYLON.InterpolateValueAction(trigger, target, propertyPath, value, duration, condition, stopOtherAnimations): Creates an animation to interpolate the current value of a property to a given target. The following types are supported:numberBABYLON.Color3BABYLON.Vector3BABYLON.Quaternion
Conditions
There are three kinds of conditions:
BABYLON.ValueCondition(actionManager, target, propertyPath, value, operator): true when the given property and value conform to the operator. The following operators are supported:BABYLON.ValueCondition.IsEqualBABYLON.ValueCondition.IsDifferentBABYLON.ValueCondition.IsGreaterBABYLON.ValueCondition.IsLesser
BABYLON.PredicateCondition(actionManager, predicate): true when the given predicate function returns true.BABYLON.StateCondition(actionManager, target, value): true when thestateproperty of the target matches the given value.
Experimenting with Actions
Imagine you want to almost hide a mesh when the user touches it.
First, you'd add a BABYLON.ActionManager to the mesh in question:
import { ActionManager } from "@babylonjs/core/Actions/actionManager";mesh.actionManager = new ActionManager(scene);Secondly, you'd register an action associated with the BABYLON.ActionManager.OnPickTrigger trigger.
This action will interpolate the mesh.visibility property to 0.2.
import { ActionManager } from "@babylonjs/core/Actions/actionManager";import { InterpolateValueAction } from "@babylonjs/core/Actions/interpolateValueAction";mesh.actionManager.registerAction(new InterpolateValueAction(ActionManager.OnPickTrigger, mesh, "visibility", 0.2, 1000));And you're done! Easy, right?
If, after fading out the mesh, you want it to fade back in, you can do so by chaining an action
to restore the mesh.visibility property to its default value:
import { ActionManager } from "@babylonjs/core/Actions/actionManager";import { InterpolateValueAction } from "@babylonjs/core/Actions/interpolateValueAction";mesh.actionManager.registerAction(new InterpolateValueAction(ActionManager.OnPickTrigger, mesh, "visibility", 0.2, 1000)).then(new InterpolateValueAction(ActionManager.OnPickTrigger, mesh, "visibility", 1.0, 1000));In this case, the first click will hide the mesh, the following click will restore it, and so on...
Sprites
Starting with Babylon.js 2.3, sprites can have an action manager: Sprite Action Manager
Please note that the SpriteManager must enable picking support by using spriteManager.isPickable = true.
Sprites can also control picking with sprite.isPickable = false / true (false by default).
Playground
If you want to play with actions, you can try them out in our playground here: Play with Actions