Babylon自定义相机输入

如何自定义相机输入

一旦您调用相机的attachControl功能,每个Babylon.js相机都会自动为你处理输入。您可以使用detachControl函数撤消控件。大多数Babylon.js开发者使用两步过程来激活和连接相机:

1. scene.activeCamera = myCamera;

2. scene.activeCamera.attachControl(canvas, true);

更简单的版本可能如下所示:

myCamera.attachControl(canvas);

默认情况下,noPreventDefault设置为false,这意味着在所有画布鼠标单击和触摸事件上自动调用preventDefault()。

Babylon.js v2.4引入了一种不同的方式来管理摄像机输入,以提供一种面向输入可组合性的方法。您现在可以使用输入管理器,并且每个输入都可以被视为特定于此摄像机系列的插件,以及给定的输入类型(鼠标,键盘,游戏手柄,设备方向等)。

使用输入管理器,您可以添加,删除,启用或禁用相机可用的任何输入。您还可以非常轻松地实现自己的输入机制或覆盖现有的输入机制。

例如,输入管理器可通过名为inputs的属性获得

var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
var inputManager = camera.inputs;

配置你的输入

大多数输入提供设置以自定义敏感度并使其适应您自己的场景。

每个输入都在管理器上提供了一个简短的名称。目标是在玩输入时提供友好的语法。

var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.add(new BABYLON.FreeCameraGamepadInput());
camera.inputs.attached.gamepad.gamepadAngularSensibility = 250;

添加现有输入

ArcRotateCamera和FreeCamera的输入管理器都公开了用于添加内置输入的简写函数。

var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.addGamepad();

如果您愿意,您还可以添加自己输入的实例(我们将在本文末尾介绍如何实现您自己的输入)。

var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.add(new BABYLON.FreeCameraGamepadInput());

启用或禁用输入

当您在相机上调用“attachControl”时,您将激活连接到输入管理器的所有输入。以同样的方式,您可以通过在相机上调用“detachControl”来关闭所有输入。

如果要暂时禁用输入,可以直接在输入上调用“detachControl”...如下所示:

var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.attached.mouse.detachControl();
camera.inputs.addGamepad();

然后,当您想再次打开它时,可以调用“attachInput”。

camera.inputs.attachInput(camera.inputs.attached.mouse);

删除输入

有时你需要一个非常具体的输入机制。在这种情况下,最好的方法可能是清除所有输入并仅添加场景中可能需要的输入。

var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.clear();
camera.inputs.addMouse();

您还可以从输入管理器中删除单个输入。您可以按实例或类型名称删除它们

var camera = new BABYLON.FreeCamera("sceneCamera", new BABYLON.Vector3(0, 1, -15), scene);
camera.inputs.remove(camera.inputs.attached.mouse);
camera.inputs.removeByType("FreeCameraKeyboardMoveInput");

实现自己的输入

您的输入法创建为函数对象。您必须为具有所需名称的多个方法编写代码,这些方法由输入函数对象调用。方法名称和目的是

//此方法必须返回摄像机的类型名称,它可用于序列化场景

getTypeName();

//此函数必须返回将作为速记输入管理器中注入的简单名称
//例如“mouse”将变成camera.inputs.attached.mouse

getSimpleName();

//此函数必须激活输入事件。即使输入不需要dom元素
//元素和nopreventdefault必须存在并用作参数名。

attachControl(element, noPreventDefault);

//分离控件必须停用输入并释放所有指针、闭包或事件侦听器
//元素必须作为参数名存在。

detachControl(element);        

//如果要将输入同步到渲染,将为每个渲染帧调用此可选函数,
//不需要使用RequestAnimationFrame。

checkInputs();

---------------------------------------------------------------------------hz

这改变了键的正常使用,使相机左右移动,前后移动到当前位置旋转。

首先删除默认键盘输入。

camera.inputs.removeByType("FreeCameraKeyboardMoveInput");

现在创建新的输入法FreeCameraKeyboardRotateInput

var FreeCameraKeyboardRotateInput = function () {
    this._keys = [];
    this.keysLeft = [37];
    this.keysRight = [39];
    this.sensibility = 0.01;
}

添加获取名称方法

FreeCameraKeyboardRotateInput.prototype.getTypeName = function () {
    return "FreeCameraKeyboardRotateInput";
};
FreeCameraKeyboardRotateInput.prototype.getSimpleName = function () {
    return "keyboardRotate";
};

和附着和分离方法

FreeCameraKeyboardRotateInput.prototype.attachControl = function (element, noPreventDefault) {
    var _this = this;
    if (!this._onKeyDown) {
        element.tabIndex = 1;
        this._onKeyDown = function (evt) {
            if (_this.keysLeft.indexOf(evt.keyCode) !== -1 ||
                _this.keysRight.indexOf(evt.keyCode) !== -1) {
                var index = _this._keys.indexOf(evt.keyCode);
                if (index === -1) {
                    _this._keys.push(evt.keyCode);
                }
                if (!noPreventDefault) {
                    evt.preventDefault();
                }
            }
        };
        this._onKeyUp = function (evt) {
            if (_this.keysLeft.indexOf(evt.keyCode) !== -1 ||
                 _this.keysRight.indexOf(evt.keyCode) !== -1) {
                var index = _this._keys.indexOf(evt.keyCode);
                if (index >= 0) {
                    _this._keys.splice(index, 1);
                }
                if (!noPreventDefault) {
                    evt.preventDefault();
                }
            }
        };

        element.addEventListener("keydown", this._onKeyDown, false);
        element.addEventListener("keyup", this._onKeyUp, false);
        BABYLON.Tools.RegisterTopRootEvents([
            { name: "blur", handler: this._onLostFocus }
        ]);
    }
};


FreeCameraKeyboardRotateInput.prototype.detachControl = function (element) {
    if (this._onKeyDown) {
        element.removeEventListener("keydown", this._onKeyDown);
        element.removeEventListener("keyup", this._onKeyUp);
        BABYLON.Tools.UnregisterTopRootEvents([
            { name: "blur", handler: this._onLostFocus }
        ]);
        this._keys = [];
        this._onKeyDown = null;
        this._onKeyUp = null;
    }
};

可选择添加检查输入

FreeCameraKeyboardRotateInput.prototype.checkInputs = function () {
    if (this._onKeyDown) {
        var camera = this.camera;
        // Keyboard
        for (var index = 0; index < this._keys.length; index++) {
            var keyCode = this._keys[index];
            if (this.keysLeft.indexOf(keyCode) !== -1) {
                camera.cameraRotation.y += this.sensibility;
            }
            else if (this.keysRight.indexOf(keyCode) !== -1) {
                camera.cameraRotation.y -= this.sensibility;
            }
        }
    }
};

最后将这种新的输入方法添加到相机输入

    camera.inputs.add(new FreeCameraKeyboardRotateInput());

 

 

上一篇:[UVa-437] The Tower of Babylon


下一篇:在vue项目中,执行 npm run dev 时提示 { parser: "babylon" } is deprecated; we now treat it as { pars