22 Babylonjs入门进阶 使用ActionManager添加模型交互事件

Action是在场景中添加模型交互的一种简单方式。触发器触发需要指定一个动作触发。例如,你可以指定用户单击(或者触摸)模型时,触发回调。
要使用Action,你必须实例化BABYLON.ActionManager并添加给模型或场景:

mesh.actionManager = new BABYLON.ActionManager(scene);

创建ActionManager后,你可以注册触发事件:

mesh.actionManager.registerAction(
    new BABYLON.InterpolateValueAction(
        BABYLON.ActionManager.OnPickTrigger,
        light,
        'diffuse',
        BABYLON.Color3.Black(),
        1000
    )
);

上面代码,在触发模型单击后,一秒后将light的diffuse设置为黑色。
你还可以实现链式操作:

mesh.actionManager.registerAction(
        new BABYLON.InterpolateValueAction(
            BABYLON.ActionManager.OnPickTrigger,
            light,
            'diffuse',
            BABYLON.Color3.Black(),
            1000
        )
    )
    .then(
        new BABYLON.SetValueAction(
            BABYLON.ActionManager.NothingTrigger,
            mesh.material,
            'wireframe',
            false
        )
    );

在这种点击情况下,第一次单击将光的颜色设置为黑色,第二次单击将模型的材质的网格设置为false。第三次将重新开始,触发第一个事件。。。
最后,你还可以增加判断。如果判断结果为true,则会触发相关事件:

mesh.actionManager.registerAction(
    new BABYLON.InterpolateValueAction(
        BABYLON.ActionManager.OnPickTrigger,
        camera,
        'alpha',
        0,
        500,
        new BABYLON.PredicateCondition(
            mesh.actionManager,
            function () {
                return light.diffuse.equals(BABYLON.Color3.Red());
            }
        )
    )
);

在此示例中,camera.alpha只有在light.diffuse的值等于红色时,才会在500毫秒设置为0。

触发器

目前,模型有14种不同的触发器,场景有三种。
可用于模型的触发器有:

  • BABYLON.ActionManager.NothingTrigger:无法触发,只用于具有action.then功能的子操作。
  • BABYLON.ActionManager.OnPickTrigger:当用户触摸/点击网格时触发。
  • BABYLON.ActionManager.OnDoublePickTrigger:当用户双击/点击网格时触发。
  • BABYLON.ActionManager.OnPickDownTrigger:当用户触摸/点击网格时触发
  • BABYLON.ActionManager.OnPickUpTrigger:当用户触摸/点击网格时触发。
  • BABYLON.ActionManager.OnPickOutTrigger:当用户触摸/点击网格然后离开网格时触发。
  • BABYLON.ActionManager.OnLeftPickTrigger:当用户使用左键触摸/点击网格时触发。
  • BABYLON.ActionManager.OnRightPickTrigger:当用户使用右键触摸/点击网格时触发。
  • BABYLON.ActionManager.OnCenterPickTrigger:当用户触摸/点击带有中心按钮的网格时触发。
  • BABYLON.ActionManager.OnLongPressTrigger:当用户长时间触摸/点击网格时提升(以BABYLON.Scene.LongPressDelay定义)。
  • BABYLON.ActionManager.OnPointerOverTrigger:当指针在网格上时触发。只触发一次。
  • BABYLON.ActionManager.OnPointerOutTrigger:当指针不再位于网格上时触发。只触发一次。
  • BABYLON.ActionManager.OnIntersectionEnterTrigger:当网格与特定网格交叉时触发。只触发一次。
  • BABYLON.ActionManager.OnIntersectionExitTrigger:当网格不再与特定网格交叉时触发。只触发一次。

请注意,两个模型交叉触发器需要你指定相关模型,可以这样做:

mesh.actionManager.registerAction(
    new BABYLON.SetValueAction(
        {
            trigger: BABYLON.ActionManager.OnIntersectionEnterTrigger, 
            parameter: { 
                mesh: otherMesh, 
                usePreciseIntersection: true
            }
        }, 
        mesh,
        "scaling",
        new BABYLON.Vector3(1.2, 1.2, 1.2)
    )
);

请注意可选的usePreciseIntersection属性。如果你不想计算精确交叉,只需要将目标模型作为值即可:

mesh.actionManager.registerAction(
    new BABYLON.SetValueAction(
        {
            trigger: BABYLON.ActionManager.OnIntersectionEnterTrigger,
            parameter: otherMesh
        },
        mesh,
        'scaling',
        new BABYLON.Vector3(1.2, 1.2, 1.2)
    )
);

可用于场景的触发器是:

  • BABYLON.ActionManager.OnEveryFrameTrigger:每帧触发一次。
  • BABYLON.ActionManager.OnKeyDownTrigger:按下某个键时触发。
  • BABYLON.ActionManager.OnKeyUpTrigger:抬起某个键时触发。

OnKeyUpTrigger和OnKeyDownTrigger触发器都接受一个字符串参数值,事件触发会判断该值是否与sourceEvent.key值是否相同。这允许你创建仅在某些键位才会触发的事件,如下所示:

scene.actionManager.registerAction(
    new BABYLON.ExecuteCodeAction(
        {
            trigger: BABYLON.ActionManager.OnKeyUpTrigger,
            parameter: 'r'
        },
        function () { console.log('按下了r键'); }
    )
);

可实现的操作

大多数操作都需要一个propertyPath值,该值是字符串类型用于定义操作修改模型的属性的路径。你可以设置position或diffuse值,你也可以提供更复杂的路径比如position.x

  • BABYLON.SwitchBooleanAction(trigger, target, propertyPath, condition):切换布尔属性。
  • BABYLON.SetValueAction(trigger, target, propertyPath, value, condition):设置属性的直接值。
  • BABYLON.IncrementValueAction(trigger, target, propertyPath, value, condition):将数字添加到数字属性。
  • BABYLON.PlayAnimationAction(trigger, target, from, to, loop, condition):在目标上播放动画。
  • BABYLON.StopAnimationAction(trigger, target, condition):停止目标正在播放的任何动画。
  • BABYLON.DoNothingAction(trigger, condition): 没做什么 :)
  • BABYLON.CombineAction(trigger, children[], condition):同时执行多个操作。children属性必须是一系列操作。
  • BABYLON.ExecuteCodeAction(trigger, func, condition):执行函数触发。
  • BABYLON.SetParentAction(trigger, target, parent, condition):设置目标的父级。
  • BABYLON.PlaySoundAction(trigger, sound, condition):播放给定的声音。
  • BABYLON.StopSoundAction(trigger, sound, condition):停止给定的声音
  • BABYLON.InterpolateValueActiontrigger, target, propertyPath, value, duration, condition, stopOtherAnimations):创建动画以将属性的当前值插入给定目标。支持以下类型:
  1. number
  2. BABYLON.Color3
  3. BABYLON.Vector3
  4. BABYLON.Quaternion

Conditions限制条件

限制条件属性的设置有三种:

  • BABYLON.ValueCondition(actionManager, target, propertyPath, value, operator):当给定的属性propertyPath和值value符合运算符operator时达到触发条件。支持以下运算符:
  1. BABYLON.ValueCondition.IsEqual
  2. BABYLON.ValueCondition.IsDifferent
  3. BABYLON.ValueCondition.IsGreater
  4. BABYLON.ValueCondition.IsLesser
  • BABYLON.PredicateCondition(actionManager, predicate):当给定的函数predicate返回true时,则达到触发条件。
  • BABYLON.StateCondition(actionManager, target, value):当目标的属性target与给定值value相同时,则达到触发条件。

实现一个动作

想想一下,当用户点击网格时,你需要隐藏模型。
首先,您将向相关模型添加一个BABYLON.ActionManager :

mesh.actionManager = new BABYLON.ActionManager(scene);

其次,您将注册与BABYLON.ActionManager.OnPickTrigger触发器关联的操作。此操作会将mesh.visibility属性插值为0.2。

mesh.actionManager.registerAction(
    new BABYLON.InterpolateValueAction(
        BABYLON.ActionManager.OnPickTrigger,
        mesh,
        'visibility',
        0.2,
        1000
    )
);

而且你已经完成了!容易,对吗?
如果在淡出网格后,您希望它重新淡入,您可以通过链式操作将mesh.visibility属性恢复为默认值来实现:

mesh.actionManager.registerAction(
            new BABYLON.InterpolateValueAction(
                BABYLON.ActionManager.OnPickTrigger,
                mesh,
                'visibility',
                0.2,
                1000
            )
        )
        .then(
            new BABYLON.InterpolateValueAction(
                BABYLON.ActionManager.OnPickTrigger,
                mesh,
                'visibility',
                1.0,
                1000
            )
        );

在这种情况下,第一次单击将隐藏按钮,以下单击将恢复它,依此类推…

精灵

从Babylon.js v2.3版本开始,精灵有一个动作管理器:https://www.babylonjs-playground.com/#9RUHH#5

请注意,精灵的动作管理器SpriteManager必须通过设置属性spriteManager.isPickable = true来启动精灵的拾取支持,也可以单独设置某个精灵的拾取sprite.isPickable = false / true(默认为False)

示例

https://www.babylonjs-playground.com/#J19GYK#0

发布了402 篇原创文章 · 获赞 544 · 访问量 212万+

猜你喜欢

转载自blog.csdn.net/qq_30100043/article/details/89317871
22