# Input Mapper

Input Mapper is a class that greatly simplifies the process of remapping controls. It handles listening for controller input, conflict checking, and creating Action-element assignments in a Controller Map.

Usage

The basic process is as follows:

1. Create an Input Mapper.
2. Configure Options.
3. Subscribe to events.
4. Create a mapping Context.
5. Start listening for input.
6. Handle assignment conflicts (optional).

1. Create an Input Mapper

You can either create a new instance of an Input Mapper or use the Default instance as shown below:

    // Create a new instance
    InputMapper inputMapper = new InputMapper();
    inputMapper.Start(context);

    // Or you can use the Default instance instead if you only need one Input Mapper
    InputMapper.Default.Start(context);

2. Configure Options

Each Input Mapper has an Options object which allows you to configure various settings to fit your needs. These settings should be configured before starting the Input Mapper.

    inputMapper.options.timeout = 5f; // set the timeout to 5 seconds
    inputMapper.options.ignoreMouseXAxis = true; // ignore the mouse X axis when polling for input
    inputMapper.options.ignoreMouseYAxis = true; // ignore the mouse Y axis when polling for input

3. Subscribe to events

There are numerous events to which you can subscribe to receive notifications when important events take place such as when an input assignment is made or when an assignment conflict is found.

    inputMapper.InputMappedEvent += OnInputMapped;
    inputMapper.ConflictFoundEvent += OnConflictFound;

4. Create a mapping Context

A mapping context provides information about the current mapping session. The mapping context is just a few pieces of information that informs the Input Mapper about what is being mapped.

    InputMapper.Context context = new InputMapper.Context() {
      actionId = action.id, // the id of the Action being mapped
      controllerMap = controllerMap, // the Controller Map which will have the new mapping added
      actionRange = AxisRange.Full, // the range of the Action being mapped
      actionElementMapToReplace = actionElementMap // the Action Element Map to be replaced (optional)
    };

5. Start listening for input

    inputMapper.Start(context);

6. Handle assignment conflicts (optional)

If you subscribed to the InputMapper.ConflictFoundEvent, you will receive a notification when a conflicting assignment was found during input mapping. The object returned contains complete information about the assignment, the conflicts that were found, and provides a callback to be used to respond to the event.

    private InputMapper.ConflictFoundEventData conflictData;

    void OnConflictFound(InputMapper.ConflictFoundEventData data) {
        conflictData = data; // store the event data for use in user response

        if(data.isProtected) { // the conflicting assignment was protected and cannot be replaced
            // Display some message to the user asking whether to cancel or add the new assignment.
            // Protected assignments cannot be replaced.
            // ...

            // ... After the user has made a decision
            conflictData.responseCallback(InputMapper.ConflictResponse.Cancel); // cancel polling

        } else {
            // Display some message to the user asking whether to cancel, replace the existing,
            // or add the new assignment.
            // ...

            // ... After the user has made a decision

            // Tell the Input Mapper to replace the conflicting assignments
            conflictData.responseCallback(InputMapper.ConflictResponse.Replace);
        }
    }

If you do not subscribe to the ConflictsFoundEvent and you have left conflict checking enabled in the Options.checkForConflicts property, the default action specified in Options.defaultActionWhenConflictFound will be used to resolve the conflict(s).

7. Advanced operations (optional)

Ignoring certain controller elements:

    void Setup() {
        // When setting up Options, add a callback to handle element confirmation
        inputMapper.options.isElementAllowedCallback = OnIsElementAllowed; // manually allow or ignore specific elements
    }

    // Called by InputMapper when a controller element is activated while polling
    bool OnIsElementAllowed(ControllerPollingInfo info) {
        // Ignore the Space key on the keyboard
        if(info.controllerType == ControllerType.Keyboard && info.keyboardKey == KeyCode.Space) return false;

        // Allow all other controller elements
        return true;
    }

Using multiple Input Mappers to listen to multiple input devices at the same time:

See Simple Combined Keyboard Mouse Remapping example for a working example.

    // Begin listening for input on both keyboard and mouse at the same time

    inputMapper_keyboard.Start(
            new InputMapper.Context() {
            actionId = actionId,
            controllerMap = keyboardMap,
            actionRange = actionRange,
            actionElementMapToReplace = keyboardMap.GetElementMap(actionElementMapToReplaceId)
        }
    );

    inputMapper_mouse.Start(
        new InputMapper.Context() {
            actionId = actionId,
            controllerMap = mouseMap,
            actionRange = actionRange,
            actionElementMapToReplace = mouseMap.GetElementMap(actionElementMapToReplaceId)
        }
    );

Documentation