Created
August 30, 2021 11:27
-
-
Save Rene-Damm/ec75f7ea6806f21177742bd59d697037 to your computer and use it in GitHub Desktop.
Setting up mock input for InputActions automatically
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Take a set of actions and create an InputDevice for it that has a control | |
// for each of the actions. Also binds the actions to that those controls. | |
public static InputDevice SetUpMockInputForActions(InputActionAsset actions) | |
{ | |
var layoutName = actions.name; | |
// Build a device layout that simply has one control for each action in the asset. | |
InputSystem.RegisterLayoutBuilder(() => | |
{ | |
var builder = new InputControlLayout.Builder() | |
.WithName(layoutName); | |
foreach (var action in actions) | |
{ | |
builder.AddControl(action.name) // Must not have actions in separate maps with the same name. | |
.WithLayout(action.expectedControlType); | |
} | |
return builder.Build(); | |
}, name: layoutName); | |
// Create the device. | |
var device = InputSystem.AddDevice(layoutName); | |
// Add a control scheme for it to the actions. | |
actions.AddControlScheme("MockInput") | |
.WithRequiredDevice($"<{layoutName}>"); | |
// Bind the actions in the newly added control scheme. | |
foreach (var action in actions) | |
action.AddBinding($"<{layoutName}>/{action.name}", groups: "MockInput"); | |
// Restrict the actions to bind only to our newly created | |
// device using the bindings we just added. | |
actions.bindingMask = InputBinding.MaskByGroup("MockInput"); | |
actions.devices = new[] { device }; | |
return device; | |
} | |
[Test] | |
[Category("Actions")] | |
public void Actions_CanCreateMockInputDeviceForActions() | |
{ | |
var keyboard = InputSystem.AddDevice<Keyboard>(); | |
var mouse = InputSystem.AddDevice<Mouse>(); | |
var actions = ScriptableObject.CreateInstance<InputActionAsset>(); | |
actions.name = "MyActions"; | |
actions.AddControlScheme("KeyboardMouse") | |
.WithRequiredDevice<Keyboard>() | |
.WithRequiredDevice<Mouse>(); | |
var map = actions.AddActionMap("Gameplay"); | |
var move = map.AddAction("Move", type: InputActionType.Value, expectedControlLayout: "Vector2"); | |
var look = map.AddAction("Look", type: InputActionType.Value, expectedControlLayout: "Vector2"); | |
var fire = map.AddAction("Fire", type: InputActionType.Button, expectedControlLayout: "Button"); | |
move.AddCompositeBinding("Dpad") | |
.With("Up", "<Keyboard>/w", groups: "KeyboardMouse") | |
.With("Down", "<Keyboard>/s", groups: "KeyboardMouse") | |
.With("Left", "<Keyboard>/a", groups: "KeyboardMouse") | |
.With("Right", "<Keyboard>/d", groups: "KeyboardMouse"); | |
look.AddBinding("<Mouse>/delta", groups: "KeyboardMouse"); | |
fire.AddBinding("<Mouse>/leftButton", groups: "KeyboardMouse"); | |
// So, now we have a pretty standard action setup for kb&mouse. | |
// Automatically modify the asset to add a "mock" input method. | |
var mockInput = SetUpMockInputForActions(actions); | |
Assert.That(move.controls, Is.EquivalentTo(new[] { mockInput["move"] })); | |
Assert.That(look.controls, Is.EquivalentTo(new[] { mockInput["look"] })); | |
Assert.That(fire.controls, Is.EquivalentTo(new[] { mockInput["fire"] })); | |
actions.Enable(); | |
var fireWasPerformed = false; | |
fire.performed += _ => fireWasPerformed = true; | |
Press((ButtonControl)mockInput["fire"]); | |
Assert.That(fireWasPerformed, Is.True); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment