Custom Input API
Meta Horizon Worlds custom input APIs are a set of interfaces that provide support for Meta Horizon World web and mobile. This is a version of Meta Horizon Worlds that can be accessed on non-VR devices such as desktop computers and smartphones. These custom input APIs allow you to bind player input actions to keyboard controls on PCs, and to on-screen controls on mobile devices.
This document shows you how you can use the Custom Input APIs to add a custom game-play input action, and demonstrates how to enable the player to jump when the user presses the spacebar on a PC keyboard, or when the user presses a button that is not associated with a grabbable entity. A detailed code example is provided at the end of this doc.
The custom input APIs (class, methods, and an enumeration) used in this example are introduced below. More specific details on each one are available in the
Meta Horizon Worlds API reference documentation.
The
PlayerControls
class provides static methods to bind and query data about custom player input bindings.
Note: The PlayerControls methods fail if you call them on the server. Make sure to set your scripts Execution Mode to Local , and in your script, set the Player as the owner of the entity that the script component is attached to.
The
PlayerControls.connectLocalInput() method connects to input events for the local player. On mobile platforms, which display on-screen buttons for actions, this causes a button to be displayed with the
specified icon. This method also takes an optional
options parameter object. You can use it to:
- Set the default placement of on-screen buttons.
- Specify the use of a disposable object that sets any additional dispose-time operations.
Note: On-screen buttons also appear on the PC desktop, but they’re not clickable; they just display the action keybind.
Note: Connecting to an unsupported input is allowed, but the input never becomes active, and its axis value remains 0.
disableSystemControls() / enableSystemControls() // This script Execution Mode must be set to Local.
import * as hz from 'horizon/core';
class DisableControls extends hz.Component {
static propsDefinition = {};
// Automatically called when the world starts.
start() {
// Disables the onscreen buttons for the mobile player who is set to the owner of the object this script is attached to.
PlayerControls.disableSystemControls();
}
}
PlayerInputAction is defined as an enumeration. The enumeration lists the 15 available actions for input. They specify the Input Action Name, Index, associated Oculus Touch button, associated Desktop key, and Mobile button values for each of the indexed items.
Note: Bindings on the Oculus touch controller can be changed in the settings for the Jump input game options.There are three options to choose from.
The TypeScript code example below demonstrates the PlayerControls methods and enumeration for creating a gameplay action. It shows how to configure the player input code to listen for a Jump action that occurs when the user presses the spacebar on a PC keyboard.
The following procedure explains how to access this example so you can see working code.
- You must set the script’s running mode to run locally, not on the server (the default).
- In your script, when the Player enters the world, set the Player as the owner of the entity that the script component is attached to.
This script code demonstrates:
- How to set the entity owner to the Player, giving the client ownership of the entity that the script is attached to.
- Setting the on-screen button placement.
- Testing to see if the Jump input action is supported on this platform.
- Connecting the local input to the Jump action, and setting the on-screen icon.
- Registering to receive the Jump action when the Player presses the spacebar on a PC keyboard.
Comments are included in the following code example to help explain what code blocks accomplish. Logging statements appear at various places in the code to help in debugging.
Tip: If you run this script in VS Code, you can peruse the API definitions in the Meta Horizon Worlds library. Position your cursor on horizon/core
in the import statement, and then press F12.
import * as hz from 'horizon/core';
class SimpleInputAPITest extends hz.Component {
static propsDefinition = {};
// Defines a variable for holding a player input action.
input?: hz.PlayerInput;
// Automatically called when the world starts.
start() {
// Check the Horizon Editor's Console pane for progress
// messages like this one.
console.log('Registering the player entering the world.');
// Register to receive the OnPlayerEnterWorld event.
this.connectCodeBlockEvent(
this.entity,
hz.CodeBlockEvents.OnPlayerEnterWorld,
player => {
console.log('Setting entity Owner ' + player.id);
this.entity.owner.set(player);
},
);
// This script must run on the client.
if (this.entity.owner.get().id != this.world.getServerPlayer().id) {
const options = {preferredButtonPlacement: hz.ButtonPlacement.Center};
// Test that the jump action is supported.
if (hz.PlayerControls.isInputActionSupported(hz.PlayerInputAction.Jump)) {
// Set player input to the jump action, set the on-screen button
// icon to the jump icon, and set the button placement to center.
// third parameter is the disposableObject, which is set to "this".
this.input = hz.PlayerControls.connectLocalInput(
hz.PlayerInputAction.Jump,
hz.ButtonIcon.Jump,
this,
options,
);
// Register to receive the jump action when the player presses the spacebar.
this.input.registerCallback((action, pressed) => {
// Set spacebar to the jump action.
const keyName = hz.PlayerControls.getPlatformKeyNames(action)[0];
console.log('Action pressed callback', action, keyName, pressed);
});
}
}
}
}
hz.Component.register(SimpleInputAPITest);
For simplicity, this code example demonstrates only one input action. You can modify the code to listen for other input actions. Change the PlayerInputActions enum value passed to isInputActionSupported(), connectLocalInput(), and getPlatformKeyNames().