123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- using UnityEngine;
- using UnityEngine.InputSystem;
- #if UNITY_EDITOR
- using UnityEditor;
- #endif
- // Say you want to distinguish a device not only by its type (e.g. "PS4 Controller")
- // but also by the way it is used. This is a common scenario for VR controllers, for
- // example, where the same type of controller may be used once in the left hand and
- // once in the right hand. However, the need for distinguishing devices in a similar
- // manner can pop up in a variety of situations. For example, on Switch it is used
- // to distinguish the current orientation of the Joy-Con controller ("Horizontal" vs.
- // "Vertical") allowing you to take orientation into account when binding actions.
- //
- // The input system allows you to distinguish devices based on the "usages" assigned
- // to them. This is a generic mechanism that can be used to tag devices with arbitrary
- // custom usages.
- //
- // To make this more concrete, let's say we have a game where two players control
- // the game together each one using a gamepad but each receiving control over half
- // the actions in the game.
- //
- // NOTE: What we do here is only one way to achieve this kind of setup. We could
- // alternatively go and just create one control scheme for the first player
- // and one control scheme for the second one and then have two PlayerInputs
- // each using one of the two.
- //
- // So, what we'd like to do is tag one gamepad with "Player1" and one gamepad with
- // with "Player2". Then, in the actions we can set up a binding scheme specifically
- // for this style of play and bind actions such that are driven either from the
- // first player's gamepad or from the second player's gamepad (or from either).
- //
- // The first bit we need for this is to tell the input system that "Player1" and
- // "Player2" are usages that we intend to apply to gamepads. For this, we need
- // to modify the "Gamepad" layout. We do so by applying what's called a "layout
- // override". This needs to happen during initialization so here we go:
- #if UNITY_EDITOR
- [InitializeOnLoad]
- #endif
- public static class InitCustomDeviceUsages
- {
- static InitCustomDeviceUsages()
- {
- Initialize();
- }
- [RuntimeInitializeOnLoadMethod]
- private static void Initialize()
- {
- // Here we register the layout override with the system.
- //
- // The layout override is just a fragment of layout information
- // in JSON format.
- //
- // The key property here is "commonUsages" which tells the system
- // that "Player1" and "Player2" are possible usages applied to devices
- // using the given layout ("Gamepad" in our case).
- InputSystem.RegisterLayoutOverride(@"
- {
- ""name"" : ""GamepadPlayerUsageTags"",
- ""extend"" : ""Gamepad"",
- ""commonUsages"" : [
- ""Player1"", ""Player2""
- ]
- }
- ");
- // Now that we have done this, you will see that when using the
- // control picker in the action editor, that there is now a
- // "Gamepad (Player1)" and "Gamepad (Player2)" entry underneath
- // "Gamepad". When you select those, you can bind specifically
- // to a gamepad with the respective device usage.
- //
- // Also, you will now be able to *require* a device with the
- // given usage in a control scheme. So, when creating a control
- // scheme representing the shared Player1+Player2 controls,
- // you can add one "Gamepad (Player1)" and one "Gamepad (Player2)"
- // requirement.
- //
- // You can see an example setup for how this would look in an
- // .inputactions file in the TwoPlayerControls.inputactions file
- // that is part of this sample.
- }
- }
- // However, we are still missing a piece. At runtime, no gamepad will
- // receive either the "Player1" or the "Player2" usage assignment yet.
- // So none of the bindings will work yet.
- //
- // To assign the usage tags to the devices, we need to call
- // InputSystem.AddDeviceUsage or SetDeviceUsage.
- //
- // We could set this up any which way. As a demonstration, let's create
- // a MonoBehaviour here that simply associates a specific tag with a
- // specific gamepad index.
- //
- // In practice, you would probably want to do the assignment in a place
- // where you handle your player setup/joining.
- public class CustomDeviceUsages : MonoBehaviour
- {
- public int gamepadIndex;
- public string usageTag;
- private Gamepad m_Gamepad;
- protected void OnEnable()
- {
- if (gamepadIndex >= 0 && gamepadIndex < Gamepad.all.Count)
- {
- m_Gamepad = Gamepad.all[gamepadIndex];
- InputSystem.AddDeviceUsage(m_Gamepad, usageTag);
- }
- }
- protected void OnDisable()
- {
- // If we grabbed a gamepad and it's still added to the system,
- // remove the usage tag we added.
- if (m_Gamepad != null && m_Gamepad.added)
- InputSystem.RemoveDeviceUsage(m_Gamepad, usageTag);
- m_Gamepad = null;
- }
- }
|