Switching between movement controllers (WASD / point &click

Hello,

We’re trying to develop a game in which the player can choose between WASD controls and point & click controls.

What would be the best way of going about this? I mean, the two will have different code blocks/modules to use. What’s the best practice in switching on/off two separate code blocks?

I think you should explore the Input Manager pattern.
Fast googling provide article for this subject, it looks that you need:

By this scheme (from article above):

Look at the input state manager, it gets events from several sources. It can be different input layouts that you can enable or disable by your custom logic.

Also you can read similar subject on this forum: Input Manager to rule them all

Here is the doucmentation about Input system: Input | Babylon.js Documentation

And of cource we can ask ChatGPT about this.

Can you explain me an input state manager that uses in game dev?

Sure! In game development, an input state manager is a tool used to manage and process user input. It is responsible for detecting and processing various user inputs, such as keyboard, mouse, or gamepad inputs, and translating them into meaningful actions within the game.

An input state manager typically consists of several components. The first component is an input detection system that listens for user inputs. This system is responsible for detecting key presses, mouse clicks, or joystick movements and translating them into a standardized input format.

The second component of an input state manager is the input mapping system. This system maps the detected inputs to specific game actions or commands. For example, the player pressing the “W” key on the keyboard might be mapped to the command to move the player character forward.

The third component of an input state manager is the input state buffer. This buffer stores the current state of all detected inputs, allowing the game to check the current state of inputs at any given time. This is useful for detecting and responding to inputs that are held down or repeatedly pressed, such as the player holding down the “jump” button to continuously jump in the game.

Finally, the input state manager may include a component for processing input events. This system responds to input events by executing the appropriate game actions or commands, such as moving the player character or initiating a game action.

By using an input state manager, game developers can create games that are responsive and easy to control, providing a more immersive and enjoyable gaming experience for players.

And can you provide some example of Input State Manager implementation for BabylonJS with their included InputManager class? And I want to see how to switch some input layouts like mouse and keyboard.

Certainly! BabylonJS is a popular game engine that provides an InputManager class for managing user input. Here’s an example implementation of an input state manager using the InputManager class in BabylonJS:

class InputStateManager {
  constructor(scene, camera) {
    this.scene = scene;
    this.camera = camera;
    this.inputManager = new BABYLON.InputManager(scene);

    // Set up default input layout
    this.useKeyboardAndMouseLayout();
  }

  useKeyboardAndMouseLayout() {
    this.inputManager.detachControl();
    this.inputManager.attachControl(this.scene.getEngine().getRenderingCanvas());

    // Map keyboard inputs to game actions
    this.inputManager.addKeyboard().onKeyDownObservable.add((kbInfo) => {
      switch(kbInfo.event.key) {
        case 'w': // Move forward
          // Execute game action to move player forward
          break;
        case 'a': // Strafe left
          // Execute game action to strafe player left
          break;
        case 's': // Move backward
          // Execute game action to move player backward
          break;
        case 'd': // Strafe right
          // Execute game action to strafe player right
          break;
        case 'space': // Jump
          // Execute game action to make player jump
          break;
      }
    });

    // Map mouse inputs to game actions
    this.inputManager.addMouse().onButtonDownObservable.add((mouseInfo) => {
      switch(mouseInfo.event.button) {
        case 0: // Left mouse button
          // Execute game action to fire weapon
          break;
        case 1: // Middle mouse button
          // Execute game action to switch weapon
          break;
        case 2: // Right mouse button
          // Execute game action to aim down sights
          break;
      }
    });
  }

  useGamepadLayout() {
    this.inputManager.detachControl();
    this.inputManager.attachGamepad();

    // Map gamepad inputs to game actions
    this.inputManager.getGamepad().onButtonDownObservable.add((buttonIndex) => {
      switch(buttonIndex) {
        case 0: // A button
          // Execute game action to jump
          break;
        case 1: // B button
          // Execute game action to fire weapon
          break;
        case 2: // X button
          // Execute game action to switch weapon
          break;
        case 3: // Y button
          // Execute game action to aim down sights
          break;
        case 4: // Left bumper
          // Execute game action to reload weapon
          break;
        case 5: // Right bumper
          // Execute game action to use grenade
          break;
        case 6: // Back button
          // Execute game action to show pause menu
          break;
        case 7: // Start button
          // Execute game action to show options menu
          break;
        case 8: // Left stick button
          // Execute game action to sprint
          break;
        case 9: // Right stick button
          // Execute game action to crouch
          break;
      }
    });
  }
}

In this example, the InputStateManager class takes a scene and a camera as arguments in its constructor. It then creates an InputManager object and sets up the default input layout using the useKeyboardAndMouseLayout() method.

The useKeyboardAndMouseLayout() method detaches the input manager from any existing control and attaches it to the rendering canvas. It then adds event listeners for keyboard inputs and mouse inputs, mapping them to specific game actions.

The useGamepadLayout() method detaches the input manager from any existing control and attaches it to a gamepad. It then adds event listeners for gamepad inputs, mapping them to specific game actions.

To switch between input layouts, you can call the useKeyboardAndMouseLayout() or useGamepadLayout() methods as needed. For example:

const inputStateManager = new InputStateManager(scene, camera);

// Switch to gamepad layout
inputStateManager.useGamepadLayout();

// Switch back to keyboard and mouse layout
inputStateManager.useKeyboardAndMouseLayout();

In this example, calling useGamepadLayout() detaches the input manager from the rendering canvas and attaches it to a gamepad, while calling useKeyboardAndMouseLayout() detaches the input manager from the gamepad and attaches it back to the rendering canvas.

I hope this helps! Let me know if you have any further questions.

© ChatGPT, an AI language model trained by OpenAI

Should to check, but it looks very close to your question.

1 Like