Maze / Library /PackageCache /com.unity.inputsystem@1.6.1 /Samples~ /CustomDeviceUsages /CustomDeviceUsages.cs
| using UnityEngine; | |
| using UnityEngine.InputSystem; | |
| using UnityEditor; | |
| // 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: | |
| [] | |
| public static class InitCustomDeviceUsages | |
| { | |
| static InitCustomDeviceUsages() | |
| { | |
| Initialize(); | |
| } | |
| [] | |
| 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; | |
| } | |
| } | |