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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章