A game about forced loneliness, made by TACStudios
1#if UNITY_EDITOR || UNITY_ANDROID
2using System.Linq;
3using UnityEngine.InputSystem.Layouts;
4using UnityEngine.InputSystem.LowLevel;
5using UnityEngine.InputSystem.Android.LowLevel;
6
7namespace UnityEngine.InputSystem.Android
8{
9 /// <summary>
10 /// Initializes custom android devices.
11 /// You can use 'adb shell dumpsys input' from terminal to output information about all input devices.
12 /// </summary>
13#if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
14 public
15#else
16 internal
17#endif
18 class AndroidSupport
19 {
20 internal const string kAndroidInterface = "Android";
21
22 public static void Initialize()
23 {
24 InputSystem.RegisterLayout<AndroidGamepad>(
25 matches: new InputDeviceMatcher()
26 .WithInterface(kAndroidInterface)
27 .WithDeviceClass("AndroidGameController"));
28 InputSystem.RegisterLayout<AndroidJoystick>(
29 matches: new InputDeviceMatcher()
30 .WithInterface(kAndroidInterface)
31 .WithDeviceClass("AndroidGameController"));
32 InputSystem.RegisterLayout<DualShock4GamepadAndroid>();
33 InputSystem.RegisterLayout<XboxOneGamepadAndroid>();
34
35 ////TODO: capability matching does not yet support bitmasking so these remain handled by OnFindLayoutForDevice for now
36 InputSystem.RegisterLayout<AndroidGamepadWithDpadAxes>();
37 InputSystem.RegisterLayout<AndroidGamepadWithDpadButtons>();
38
39 InputSystem.RegisterProcessor<AndroidCompensateDirectionProcessor>();
40 InputSystem.RegisterProcessor<AndroidCompensateRotationProcessor>();
41
42 // Add sensors
43 InputSystem.RegisterLayout<AndroidAccelerometer>(
44 matches: new InputDeviceMatcher()
45 .WithInterface(kAndroidInterface)
46 .WithDeviceClass("AndroidSensor")
47 .WithCapability("sensorType", AndroidSensorType.Accelerometer));
48 InputSystem.RegisterLayout<AndroidMagneticFieldSensor>(
49 matches: new InputDeviceMatcher()
50 .WithInterface(kAndroidInterface)
51 .WithDeviceClass("AndroidSensor")
52 .WithCapability("sensorType", AndroidSensorType.MagneticField));
53 InputSystem.RegisterLayout<AndroidGyroscope>(
54 matches: new InputDeviceMatcher()
55 .WithInterface(kAndroidInterface)
56 .WithDeviceClass("AndroidSensor")
57 .WithCapability("sensorType", AndroidSensorType.Gyroscope));
58 InputSystem.RegisterLayout<AndroidLightSensor>(
59 matches: new InputDeviceMatcher()
60 .WithInterface(kAndroidInterface)
61 .WithDeviceClass("AndroidSensor")
62 .WithCapability("sensorType", AndroidSensorType.Light));
63 InputSystem.RegisterLayout<AndroidPressureSensor>(
64 matches: new InputDeviceMatcher()
65 .WithInterface(kAndroidInterface)
66 .WithDeviceClass("AndroidSensor")
67 .WithCapability("sensorType", AndroidSensorType.Pressure));
68 InputSystem.RegisterLayout<AndroidProximity>(
69 matches: new InputDeviceMatcher()
70 .WithInterface(kAndroidInterface)
71 .WithDeviceClass("AndroidSensor")
72 .WithCapability("sensorType", AndroidSensorType.Proximity));
73 InputSystem.RegisterLayout<AndroidGravitySensor>(
74 matches: new InputDeviceMatcher()
75 .WithInterface(kAndroidInterface)
76 .WithDeviceClass("AndroidSensor")
77 .WithCapability("sensorType", AndroidSensorType.Gravity));
78 InputSystem.RegisterLayout<AndroidLinearAccelerationSensor>(
79 matches: new InputDeviceMatcher()
80 .WithInterface(kAndroidInterface)
81 .WithDeviceClass("AndroidSensor")
82 .WithCapability("sensorType", AndroidSensorType.LinearAcceleration));
83 InputSystem.RegisterLayout<AndroidRotationVector>(
84 matches: new InputDeviceMatcher()
85 .WithInterface(kAndroidInterface)
86 .WithDeviceClass("AndroidSensor")
87 .WithCapability("sensorType", AndroidSensorType.RotationVector));
88 InputSystem.RegisterLayout<AndroidRelativeHumidity>(
89 matches: new InputDeviceMatcher()
90 .WithInterface(kAndroidInterface)
91 .WithDeviceClass("AndroidSensor")
92 .WithCapability("sensorType", AndroidSensorType.RelativeHumidity));
93 InputSystem.RegisterLayout<AndroidAmbientTemperature>(
94 matches: new InputDeviceMatcher()
95 .WithInterface(kAndroidInterface)
96 .WithDeviceClass("AndroidSensor")
97 .WithCapability("sensorType", AndroidSensorType.AmbientTemperature));
98 InputSystem.RegisterLayout<AndroidGameRotationVector>(
99 matches: new InputDeviceMatcher()
100 .WithInterface(kAndroidInterface)
101 .WithDeviceClass("AndroidSensor")
102 .WithCapability("sensorType", AndroidSensorType.GameRotationVector));
103 InputSystem.RegisterLayout<AndroidStepCounter>(
104 matches: new InputDeviceMatcher()
105 .WithInterface(kAndroidInterface)
106 .WithDeviceClass("AndroidSensor")
107 .WithCapability("sensorType", AndroidSensorType.StepCounter));
108 InputSystem.RegisterLayout<AndroidHingeAngle>(
109 matches: new InputDeviceMatcher()
110 .WithInterface(kAndroidInterface)
111 .WithDeviceClass("AndroidSensor")
112 .WithCapability("sensorType", AndroidSensorType.HingeAngle));
113
114 InputSystem.onFindLayoutForDevice += OnFindLayoutForDevice;
115 }
116
117 internal static string OnFindLayoutForDevice(ref InputDeviceDescription description,
118 string matchedLayout, InputDeviceExecuteCommandDelegate executeCommandDelegate)
119 {
120 // If we already have a matching layout, someone registered a better match.
121 // We only want to act as a fallback.
122 if (!string.IsNullOrEmpty(matchedLayout) && matchedLayout != "AndroidGamepad" && matchedLayout != "AndroidJoystick")
123 return null;
124
125 if (description.interfaceName != "Android" || string.IsNullOrEmpty(description.capabilities))
126 return null;
127
128 ////TODO: these should just be Controller and Sensor; the interface is already Android
129 switch (description.deviceClass)
130 {
131 case "AndroidGameController":
132 {
133 var caps = AndroidDeviceCapabilities.FromJson(description.capabilities);
134
135 // Note: Gamepads have both AndroidInputSource.Gamepad and AndroidInputSource.Joystick in input source, while
136 // Joysticks don't have AndroidInputSource.Gamepad in their input source
137 if ((caps.inputSources & AndroidInputSource.Gamepad) != AndroidInputSource.Gamepad)
138 return "AndroidJoystick";
139
140 if (caps.motionAxes == null)
141 return "AndroidGamepadWithDpadButtons";
142
143 // Vendor Ids, Product Ids can be found here http://www.linux-usb.org/usb.ids
144 const int kVendorMicrosoft = 0x045e;
145 const int kVendorSony = 0x054c;
146
147 // Tested with controllers: PS4 DualShock; XboxOne; Nvidia Shield
148 // Tested on devices: Shield console Android 9; Galaxy s9+ Android 10
149 if (caps.motionAxes.Contains(AndroidAxis.Z) &&
150 caps.motionAxes.Contains(AndroidAxis.Rz) &&
151 caps.motionAxes.Contains(AndroidAxis.HatX) &&
152 caps.motionAxes.Contains(AndroidAxis.HatY))
153 {
154 if (caps.vendorId == kVendorMicrosoft)
155 return "XboxOneGamepadAndroid";
156 if (caps.vendorId == kVendorSony)
157 return "DualShock4GamepadAndroid";
158 }
159
160
161 // Fallback to generic gamepads
162 if (caps.motionAxes.Contains(AndroidAxis.HatX) &&
163 caps.motionAxes.Contains(AndroidAxis.HatY))
164 return "AndroidGamepadWithDpadAxes";
165
166 return "AndroidGamepadWithDpadButtons";
167 }
168 default:
169 return null;
170 }
171 }
172 }
173}
174#endif // UNITY_EDITOR || UNITY_ANDROID