This commit is contained in:
sin365 2025-08-19 10:21:17 +08:00
parent 0a45c4fbbd
commit 0f27fa328c
24 changed files with 1249 additions and 20 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 25ea535c006d6544d9b301a2dcde95b9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,5 @@
{
"timestamp": 1648458313,
"signature": "DWppfmRE13R6S+n/9p1BkuJhH8i4OF2aZu3uXd+7pP8L9LaFr+oymbRCxdy+8l1IFlQzQbQL1ewVCMnKQIonn36dYoZpneipJbUa4CBvwiDObtwD1WSasTq8d9smbhOmeBewyLfkHsGmI4z0WvSJFyq11ISeMXe8pCVoq/PNi5gKfxwvOh4Cy49Y65MZOGAI0MOcOyfQjRS7cR5oPEtAQJysVRtcJPcbPSgr5tjbM9dLf7h5/J6AWXCBav4m6h6932umoOv5FsBQhNQquKqbC984E5ku8G45UKX7t7V0pJFBQe0y1++MN8aSVyJ08IV6h206tTOfIyZVRwswMGGyoAvbF5SF0CmL12QbkW7giZJTa23fvOv09sM3nlA2JpyVSvPWgMmv5HGsLvaboXxSVAp6HcN1M83rMPiQaS34YW/f+JgrHumKa/TTwpzml7kG5xdk3dOACLHRlyDag3oHYmC1OpaI1rnlt7r+z3gCYz5dGTavkHHnNRBukliZYft/",
"publicKey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQm9qQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FZOEFNSUlCaWdLQ0FZRUFzdUhXYUhsZ0I1cVF4ZEJjTlJKSAordHR4SmoxcVY1NTdvMlZaRE1XaXhYRVBkRTBEMVFkT1JIRXNSS1RscmplUXlERU83ZlNQS0ZwZ1A3MU5TTnJCCkFHM2NFSU45aHNQVDhOVmllZmdWem5QTkVMenFkVmdEbFhpb2VpUnV6OERKWFgvblpmU1JWKytwbk9ySTRibG4KS0twelJlNW14OTc1SjhxZ1FvRktKT0NNRlpHdkJMR2MxSzZZaEIzOHJFODZCZzgzbUovWjBEYkVmQjBxZm13cgo2ZDVFUXFsd0E5Y3JZT1YyV1VpWXprSnBLNmJZNzRZNmM1TmpBcEFKeGNiaTFOaDlRVEhUcU44N0ZtMDF0R1ZwCjVNd1pXSWZuYVRUemEvTGZLelR5U0pka0tldEZMVGdkYXpMYlpzUEE2aHBSK0FJRTJhc0tLTi84UUk1N3UzU2cKL2xyMnZKS1IvU2l5eEN1Q20vQWJkYnJMbXk0WjlSdm1jMGdpclA4T0lLQWxBRWZ2TzV5Z2hSKy8vd1RpTFlzUQp1SllDM0V2UE16ZGdKUzdGR2FscnFLZzlPTCsxVzROY05yNWdveVdSUUJ0cktKaWlTZEJVWmVxb0RvSUY5NHpCCndGbzJJT1JFdXFqcU51M3diMWZIM3p1dGdtalFra3IxVjJhd3hmcExLWlROQWdNQkFBRT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg"
}

View File

@ -0,0 +1,49 @@
# Changelog
All notable changes to the input system package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
Due to package verification, the latest version below is the unpublished version and the date is meaningless.
however, it has to be formatted properly to pass verification tests.
## [0.1.0-preview] - 2019-9-2
First release from develop branch.
## [0.1.1-preview] - 2019-10-29
Updated package dependencies to use latest `com.unity.inputsystem` package version 1.0.0-preview.1
## [0.1.2-preview] - 2021-05-17
Updated package dependencies to `com.unity.inputsystem` package version 1.1.0-preview.2 and Unity 2019.4
Overrides added for aButton, bButton, xButton, yButton functions to map to north, south, east, west buttons correctly for Nintendo layout.
Fixed incorrect shortDisplayName values inherited from Gamepad.cs
Added "Submit" & "Cancel" UI usage tags to A and B buttons.
Added Joy-Con attrbutes to NPad.cs as a bit field, with accessors to get connected and wired states.
Minium Unity versions for checking m_Attributes functions (IsWired/IsConnected)
2021.2.0a10, 2021.1.1f1, 2020.3.4f1, 2019.4.24f1
Added code to parse the Unity application version string and test for NPad attributes support (Assert if attempting to use attributes and Unity version is below minimum required).
## [0.1.3-pre] - 2021-07-06
Updated package dependencies to use `com.unity.inputsystem` package 1.1.0-pre.5
This fixes an issue where earlier 'com.unity.inputsystem' packages (1.1.0-preview.X) were considered more recent than 1.1.0-pre.5 due to the Semantic Versioning spec and that prevented upgrading to 1.1.0-pre.5 or later.
Updated the package name to the use the "Pre-release" label following the new package lifecycle naming convention & patch version increased.
## [0.1.4-pre] - 2021-11-03
Fixed logic error in minimum version check (IsVersionOrHigher) for checking support for m_Attributes.
The Unity version type (alpha, beta, final etc) should be checked ahead of the revision, so 2021.2.0f1 (final 1) is recognised as a later version than 2021.2.0a10 (alpha 10)
## [0.1.5-pre] - 2021-11-15
The package is now signed.
## [0.1.6-pre] - 2022-03-55
Fixed a bug where ResetHaptics and PauseHaptics functions were not specifying a RumblePosition flag (Was None, should be All) and so had no effect when called.
NPadDeviceIOCTLOutputCommand Create function now takes RumblePosition as an argument (defaulting to All)
Fixed a bug in NPadRumbleValues.Reset() where frequencyHigh was not being reset.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2fe913aba0c6c104ca6b05e2a1def256
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3b3482582c1bb9341aacbb0a24c53938
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aaa7ef903a2a1a041b6888d1a259bda3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9177521509a3da24cb1e37e9eb8d7248
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,27 @@
#if UNITY_EDITOR || UNITY_SWITCH
using UnityEngine.InputSystem.Haptics;
namespace UnityEngine.InputSystem.Switch
{
/// <summary>
/// Extended dual motor gamepad that adds seperate controls for rumble frequency and amplitude.
/// </summary>
public interface INPadRumble : IDualMotorRumble
{
/// <summary>
/// Set rumble for all motors
/// </summary>
void SetMotorSpeeds(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency);
/// <summary>
/// Set rumble for left motor
/// </summary>
void SetMotorSpeedLeft(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency);
/// <summary>
/// Set rumble for right motor
/// </summary>
void SetMotorSpeedRight(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency);
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f7abf5d9c0bddda4cb82a5d0b3525c0b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,746 @@
#if UNITY_EDITOR || UNITY_SWITCH || PACKAGE_DOCS_GENERATION
using System;
using System.Runtime.InteropServices;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.InputSystem.Switch.LowLevel;
using UnityEngine.InputSystem.Utilities;
////REVIEW: The Switch controller can be used to point at things; can we somehow help leverage that?
namespace UnityEngine.InputSystem.Switch.LowLevel
{
/// <summary>
/// Structure of native input reports for Switch NPad controllers.
/// </summary>
/// <seealso href="http://en-americas-support.nintendo.com/app/answers/detail/a_id/22634/~/joy-con-controller-diagram"/>
[StructLayout(LayoutKind.Explicit, Size = 60)]
internal struct NPadInputState : IInputStateTypeInfo
{
public FourCC format
{
get { return new FourCC('N', 'P', 'A', 'D'); }
}
[InputControl(name = "dpad")]
[InputControl(name = "buttonNorth", displayName = "X", shortDisplayName = "X", bit = (uint)Button.North)]
[InputControl(name = "buttonSouth", displayName = "B", shortDisplayName = "B", bit = (uint)Button.South, usages = new[] { "Back", "Cancel" })]
[InputControl(name = "buttonWest", displayName = "Y", shortDisplayName = "Y", bit = (uint)Button.West, usage = "SecondaryAction")]
[InputControl(name = "buttonEast", displayName = "A", shortDisplayName = "A", bit = (uint)Button.East, usages = new[] { "PrimaryAction", "Submit" })]
[InputControl(name = "leftStickPress", displayName = "Left Stick", bit = (uint)Button.StickL)]
[InputControl(name = "rightStickPress", displayName = "Right Stick", bit = (uint)Button.StickR)]
[InputControl(name = "leftShoulder", displayName = "L", shortDisplayName = "L", bit = (uint)Button.L)]
[InputControl(name = "rightShoulder", displayName = "R", shortDisplayName = "R", bit = (uint)Button.R)]
[InputControl(name = "leftTrigger", displayName = "ZL", shortDisplayName = "ZL", format = "BIT", bit = (uint)Button.ZL)]
[InputControl(name = "rightTrigger", displayName = "ZR", shortDisplayName = "ZR", format = "BIT", bit = (uint)Button.ZR)]
[InputControl(name = "start", displayName = "Plus", bit = (uint)Button.Plus, usage = "Menu")]
[InputControl(name = "select", displayName = "Minus", bit = (uint)Button.Minus)]
[InputControl(name = "leftSL", displayName = "SL (Left)", shortDisplayName = "LSL", layout = "Button", bit = (uint)Button.LSL)]
[InputControl(name = "leftSR", displayName = "SR (Left)", shortDisplayName = "LSR", layout = "Button", bit = (uint)Button.LSR)]
[InputControl(name = "rightSL", displayName = "SL (Right)", shortDisplayName = "RSL", layout = "Button", bit = (uint)Button.RSL)]
[InputControl(name = "rightSR", displayName = "SR (Right)", shortDisplayName = "RSR", layout = "Button", bit = (uint)Button.RSR)]
[FieldOffset(0)]
public uint buttons;
[FieldOffset(4)]
public Vector2 leftStick;
[FieldOffset(12)]
public Vector2 rightStick;
[InputControl(name = "acceleration", noisy = true)]
[FieldOffset(20)]
public Vector3 acceleration;
[InputControl(name = "attitude", noisy = true)]
[FieldOffset(32)]
public Quaternion attitude;
[InputControl(name = "angularVelocity", noisy = true)]
[FieldOffset(48)]
public Vector3 angularVelocity;
public float leftTrigger => ((buttons & (1 << (int)Button.ZL)) != 0) ? 1f : 0f;
public float rightTrigger => ((buttons & (1 << (int)Button.ZR)) != 0) ? 1f : 0f;
public enum Button
{
// Dpad buttons. Important to be first in the bitfield as we'll
// point the DpadControl to it.
// IMPORTANT: Order has to match what is expected by DpadControl.
Up,
Down,
Left,
Right,
North,
South,
West,
East,
StickL,
StickR,
L,
R,
ZL,
ZR,
Plus,
Minus,
LSL,
LSR,
RSL,
RSR,
X = North,
B = South,
Y = West,
A = East,
}
public NPadInputState WithButton(Button button, bool value = true)
{
var bit = (uint)1 << (int)button;
if (value)
buttons |= bit;
else
buttons &= ~bit;
return this;
}
}
/// <summary>
/// Switch output report sent as command to the backend.
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = kSize)]
internal struct NPadStatusReport : IInputDeviceCommandInfo
{
public static FourCC Type => new FourCC('N', 'P', 'D', 'S');
internal const int kSize = InputDeviceCommand.BaseCommandSize + 24;
[FieldOffset(0)]
public InputDeviceCommand baseCommand;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 0)]
public NPad.NpadId npadId;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 1)]
public NPad.Orientation orientation;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 2)]
public NPad.Attributes attributes;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 3)]
public char padding0;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 4)]
public NPad.NpadStyles styleMask;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 8)]
public int colorLeftMain;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 12)]
public int colorLeftSub;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 16)]
public int colorRightMain;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 20)]
public int colorRightSub;
public FourCC typeStatic
{
get { return Type; }
}
public static NPadStatusReport Create()
{
return new NPadStatusReport
{
baseCommand = new InputDeviceCommand(Type, kSize),
};
}
}
[StructLayout(LayoutKind.Explicit, Size = kSize)]
internal struct NPadControllerSupportCommand : IInputDeviceCommandInfo
{
public static FourCC Type => new FourCC('N', 'P', 'D', 'U');
internal const int kSize = InputDeviceCommand.BaseCommandSize + 8;
[FieldOffset(0)]
public InputDeviceCommand baseCommand;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 0)]
public int command;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 4)]
public int option;
public enum Command : int
{
kShowUI,
kSetHorizontalLayout,
kStartSixAxisSensor,
kStopSixAxisSensor,
}
public FourCC typeStatic
{
get { return Type; }
}
public static NPadControllerSupportCommand Create(NPadControllerSupportCommand.Command command, int option = 0)
{
return new NPadControllerSupportCommand
{
baseCommand = new InputDeviceCommand(Type, kSize),
command = (int)command,
option = option,
};
}
}
[StructLayout(LayoutKind.Explicit, Size = kSize)]
internal struct NpadDeviceIOCTLShowUI : IInputDeviceCommandInfo
{
public static FourCC Type => new FourCC("NSUI");
internal const int kSize = InputDeviceCommand.BaseCommandSize;
[FieldOffset(0)]
public InputDeviceCommand baseCommand;
public FourCC typeStatic
{
get { return Type; }
}
public static NpadDeviceIOCTLShowUI Create()
{
return new NpadDeviceIOCTLShowUI
{
baseCommand = new InputDeviceCommand(Type, kSize),
};
}
}
[StructLayout(LayoutKind.Explicit, Size = kSize)]
internal struct NpadDeviceIOCTLSetOrientation : IInputDeviceCommandInfo
{
public static FourCC Type => new FourCC("NSOR");
internal const int kSize = InputDeviceCommand.BaseCommandSize + 1;
[FieldOffset(0)]
public InputDeviceCommand baseCommand;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 0)]
public NPad.Orientation orientation;
public FourCC typeStatic
{
get { return Type; }
}
public static NpadDeviceIOCTLSetOrientation Create(NPad.Orientation orientation)
{
return new NpadDeviceIOCTLSetOrientation
{
baseCommand = new InputDeviceCommand(Type, kSize),
orientation = orientation,
};
}
}
[StructLayout(LayoutKind.Explicit, Size = kSize)]
internal struct NpadDeviceIOCTLStartSixAxisSensor : IInputDeviceCommandInfo
{
public static FourCC Type => new FourCC("SXST");
internal const int kSize = InputDeviceCommand.BaseCommandSize;
[FieldOffset(0)]
public InputDeviceCommand baseCommand;
public FourCC typeStatic
{
get { return Type; }
}
public static NpadDeviceIOCTLStartSixAxisSensor Create()
{
return new NpadDeviceIOCTLStartSixAxisSensor
{
baseCommand = new InputDeviceCommand(Type, kSize),
};
}
}
[StructLayout(LayoutKind.Explicit, Size = kSize)]
internal struct NpadDeviceIOCTLStopSixAxisSensor : IInputDeviceCommandInfo
{
public static FourCC Type => new FourCC("SXSP");
internal const int kSize = InputDeviceCommand.BaseCommandSize;
[FieldOffset(0)]
public InputDeviceCommand baseCommand;
public FourCC typeStatic
{
get { return Type; }
}
public static NpadDeviceIOCTLStopSixAxisSensor Create()
{
return new NpadDeviceIOCTLStopSixAxisSensor
{
baseCommand = new InputDeviceCommand(Type, kSize),
};
}
}
/// <summary>
/// Switch output report sent as command to backend.
/// </summary>
// IMPORTANT: Struct must match the NpadDeviceIOCTLOutputReport in native
[StructLayout(LayoutKind.Explicit, Size = kSize)]
internal struct NPadDeviceIOCTLOutputCommand : IInputDeviceCommandInfo
{
public static FourCC Type { get { return new FourCC('N', 'P', 'G', 'O'); } }
internal const int kSize = InputDeviceCommand.BaseCommandSize + 20;
public const float DefaultFrequencyLow = 160.0f;
public const float DefaultFrequencyHigh = 320.0f;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification = "Need to match native struct data size")]
public enum NPadRumblePostion : byte
{
Left = 0x02,
Right = 0x04,
All = 0xFF,
None = 0x00,
}
[FieldOffset(0)] public InputDeviceCommand baseCommand;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 0)]
public byte positions;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 4)]
public float amplitudeLow;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 8)]
public float frequencyLow;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 12)]
public float amplitudeHigh;
[FieldOffset(InputDeviceCommand.BaseCommandSize + 16)]
public float frequencyHigh;
public FourCC typeStatic
{
get { return Type; }
}
public static NPadDeviceIOCTLOutputCommand Create(NPadRumblePostion rumblePos = NPadRumblePostion.All)
{
return new NPadDeviceIOCTLOutputCommand()
{
baseCommand = new InputDeviceCommand(Type, kSize),
positions = (byte)rumblePos,
amplitudeLow = 0,
frequencyLow = DefaultFrequencyLow,
amplitudeHigh = 0,
frequencyHigh = DefaultFrequencyHigh
};
}
}
}
namespace UnityEngine.InputSystem.Switch
{
/// <summary>
/// An NPad controller for Switch, which can be a Joy-Con.
/// </summary>
/// <seealso cref="NPadInputState"/>
[InputControlLayout(stateType = typeof(NPadInputState), displayName = "Switch Controller (on Switch)")]
[Scripting.Preserve]
public class NPad : Gamepad, INPadRumble
{
public ButtonControl leftSL { get; private set; }
public ButtonControl leftSR { get; private set; }
public ButtonControl rightSL { get; private set; }
public ButtonControl rightSR { get; private set; }
public Vector3Control acceleration { get; private set; }
public QuaternionControl attitude { get; private set; }
public Vector3Control angularVelocity { get; private set; }
// Override inherited a/b/x/y mappings to match the JoyCon layout
public new ButtonControl bButton => buttonSouth;
public new ButtonControl aButton => buttonEast;
public new ButtonControl yButton => buttonWest;
public new ButtonControl xButton => buttonNorth;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification = "Need to match native struct data size")]
public enum Orientation : byte
{
Vertical,
Horizontal,
Default = Vertical,
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification = "Need to match native struct data size")]
public enum NpadId : byte
{
No1 = 0x00,
No2 = 0x01,
No3 = 0x02,
No4 = 0x03,
No5 = 0x04,
No6 = 0x05,
No7 = 0x06,
No8 = 0x07,
Handheld = 0x20,
Debug = 0xF0,
Invalid = 0xFF,
}
[Flags]
public enum Attributes
{
IsConnected = 0x01,
IsWired = 0x02,
IsLeftConnected = 0x04,
IsLeftWired = 0x08,
IsRightConnected = 0x10,
IsRightWired = 0x20,
}
//orientation matters for stick axes!!!!
//there's a touchpad and 90% of games don't support it
//each person could play with a different style
[Flags]
public enum NpadStyles
{
FullKey = 1 << 0,//separate;or pro controller;only one accel
Handheld = 1 << 1,//docked to switch
JoyDual = 1 << 2,//separate; one accel per joycon
JoyLeft = 1 << 3,//just one; orientation matters
JoyRight = 1 << 4,//just one; orientation matters
}
public struct JoyConColor
{
public Color32 Main;
public Color32 Sub;
}
public Orientation orientation
{
get
{
RefreshConfigurationIfNeeded();
return m_Orientation;
}
}
public NpadId npadId
{
get
{
RefreshConfigurationIfNeeded();
return m_NpadId;
}
}
public NpadStyles styleMask
{
get
{
RefreshConfigurationIfNeeded();
return m_StyleMask;
}
}
public JoyConColor leftControllerColor
{
get
{
RefreshConfigurationIfNeeded();
return m_LeftControllerColor;
}
}
public JoyConColor rightControllerColor
{
get
{
RefreshConfigurationIfNeeded();
return m_RightControllerColor;
}
}
public bool isConnected
{
get
{
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
RefreshConfigurationIfNeeded();
return (m_Attributes & Attributes.IsConnected) != 0;
}
}
public bool isLeftConnected
{
get
{
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
RefreshConfigurationIfNeeded();
return (m_Attributes & Attributes.IsLeftConnected) != 0;
}
}
public bool isRightConnected
{
get
{
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(),k_StringAttributesNotSupported);
RefreshConfigurationIfNeeded();
return (m_Attributes & Attributes.IsRightConnected) != 0;
}
}
public bool isWired
{
get
{
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
RefreshConfigurationIfNeeded();
return (m_Attributes & Attributes.IsWired) != 0;
}
}
public bool isLeftWired
{
get
{
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
RefreshConfigurationIfNeeded();
return (m_Attributes & Attributes.IsLeftWired) != 0;
}
}
public bool isRightWired
{
get
{
Debug.Assert(SwitchConsoleSupport.NpadAttributesSupported(), k_StringAttributesNotSupported);
RefreshConfigurationIfNeeded();
return (m_Attributes & Attributes.IsRightWired) != 0;
}
}
private Orientation m_Orientation;
private NpadId m_NpadId = NpadId.Invalid;
private NpadStyles m_StyleMask;
private JoyConColor m_LeftControllerColor;
private JoyConColor m_RightControllerColor;
private Attributes m_Attributes;
private const string k_StringAttributesNotSupported = "Attributes not supported in this Unity version! Requires 2021.2.0a10, 2021.1.1f1, 2020.3.4f1, 2019.4.24f1 or higher";
private struct NPadRumbleValues
{
public float? amplitudeLow;
public float? frequencyLow;
public float? amplitudeHigh;
public float? frequencyHigh;
public bool HasValues => amplitudeLow.HasValue && frequencyLow.HasValue && amplitudeHigh.HasValue && frequencyHigh.HasValue;
public void SetRumbleValues(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency)
{
amplitudeLow = Mathf.Clamp01(lowAmplitude);
frequencyLow = lowFrequency;
amplitudeHigh = Mathf.Clamp01(highAmplitude);
frequencyHigh = highFrequency;
}
public void Reset()
{
amplitudeLow = null;
frequencyLow = null;
amplitudeHigh = null;
frequencyHigh = null;
}
public void ApplyRumbleValues(ref NPadDeviceIOCTLOutputCommand cmd)
{
cmd.amplitudeLow = (float)amplitudeLow;
cmd.frequencyLow = (float)frequencyLow;
cmd.amplitudeHigh = (float)amplitudeHigh;
cmd.frequencyHigh = (float)frequencyHigh;
}
}
private NPadRumbleValues m_leftRumbleValues;
private NPadRumbleValues m_rightRumbleValues;
protected override void RefreshConfiguration()
{
base.RefreshConfiguration();
var command = NPadStatusReport.Create();
if (ExecuteCommand(ref command) > 0)
{
m_NpadId = command.npadId;
m_Orientation = command.orientation;
m_StyleMask = command.styleMask;
m_Attributes = command.attributes;
ReadNNColorIntoJoyConColor(ref m_LeftControllerColor, command.colorLeftMain, command.colorLeftSub);
ReadNNColorIntoJoyConColor(ref m_RightControllerColor, command.colorRightMain, command.colorRightSub);
}
}
// NOTE: This function should be static
public long SetOrientationToSingleJoyCon(Orientation orientation)
{
var supportCommand = NpadDeviceIOCTLSetOrientation.Create(orientation);
return ExecuteCommand(ref supportCommand);
}
public long StartSixAxisSensor()
{
var supportCommand = NpadDeviceIOCTLStartSixAxisSensor.Create();
return ExecuteCommand(ref supportCommand);
}
public long StopSixAxisSensor()
{
var supportCommand = NpadDeviceIOCTLStopSixAxisSensor.Create();
return ExecuteCommand(ref supportCommand);
}
protected override void FinishSetup()
{
base.FinishSetup();
leftSL = GetChildControl<ButtonControl>("leftSL");
leftSR = GetChildControl<ButtonControl>("leftSR");
rightSL = GetChildControl<ButtonControl>("rightSL");
rightSR = GetChildControl<ButtonControl>("rightSR");
acceleration = GetChildControl<Vector3Control>("acceleration");
attitude = GetChildControl<QuaternionControl>("attitude");
angularVelocity = GetChildControl<Vector3Control>("angularVelocity");
}
private static void ReadNNColorIntoJoyConColor(ref JoyConColor controllerColor, int mainColor, int subColor)
{
controllerColor.Main = ConvertNNColorToColor32(mainColor);
controllerColor.Sub = ConvertNNColorToColor32(subColor);
}
private static Color32 ConvertNNColorToColor32(int color)
{
return new Color32((byte)(color & 0xFF), (byte)((color >> 8) & 0xFF), (byte)((color >> 16) & 0xFF), (byte)((color >> 24) & 0xFF));
}
public override void PauseHaptics()
{
var cmd = NPadDeviceIOCTLOutputCommand.Create();
ExecuteCommand(ref cmd);
}
public override void ResetHaptics()
{
var cmd = NPadDeviceIOCTLOutputCommand.Create();
ExecuteCommand(ref cmd);
m_leftRumbleValues.Reset();
m_rightRumbleValues.Reset();
}
public override void ResumeHaptics()
{
if (m_leftRumbleValues.Equals(m_rightRumbleValues) && m_leftRumbleValues.HasValues)
{
var cmd = NPadDeviceIOCTLOutputCommand.Create();
m_leftRumbleValues.ApplyRumbleValues(ref cmd);
ExecuteCommand(ref cmd);
}
else
{
if (m_leftRumbleValues.HasValues)
{
var cmd = NPadDeviceIOCTLOutputCommand.Create(NPadDeviceIOCTLOutputCommand.NPadRumblePostion.Left);
m_leftRumbleValues.ApplyRumbleValues(ref cmd);
ExecuteCommand(ref cmd);
}
if (m_rightRumbleValues.HasValues)
{
var cmd = NPadDeviceIOCTLOutputCommand.Create(NPadDeviceIOCTLOutputCommand.NPadRumblePostion.Right);
m_rightRumbleValues.ApplyRumbleValues(ref cmd);
ExecuteCommand(ref cmd);
}
}
}
/// <summary>
/// Set rummble intensity for all low and high frequency rumble motors
/// </summary>
/// <param name="lowFrequency">Low frequency motor's vibration intensity, 0..1 range</param>
/// <param name="highFrequency">High frequency motor's vibration intensity, 0..1 range</param>
public override void SetMotorSpeeds(float lowFrequency, float highFrequency)
{
SetMotorSpeeds(lowFrequency, NPadDeviceIOCTLOutputCommand.DefaultFrequencyLow, highFrequency, NPadDeviceIOCTLOutputCommand.DefaultFrequencyHigh);
}
/// <summary>
/// Set the intensity and vibration frequency for all low and high frequency rumble motors
/// </summary>
/// <param name="lowAmplitude">Low frequency motor's vibration intensity, 0..1 range</param>
/// <param name="lowFrequency">Low frequency motor's vibration frequency in Hz</param>
/// <param name="highAmplitude">High frequency motor's vibration intensity, 0..1 range</param>
/// <param name="highFrequency">High frequency motor's vibration frequency in Hz</param>
public void SetMotorSpeeds(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency)
{
m_leftRumbleValues.SetRumbleValues(lowAmplitude, lowFrequency, highAmplitude, highFrequency);
m_rightRumbleValues.SetRumbleValues(lowAmplitude, lowFrequency, highAmplitude, highFrequency);
var cmd = NPadDeviceIOCTLOutputCommand.Create();
m_leftRumbleValues.ApplyRumbleValues(ref cmd);
ExecuteCommand(ref cmd);
}
/// <summary>
/// Set the intensity and vibration frequency for the left low and high frequency rumble motors
/// </summary>
/// <param name="lowAmplitude">Low frequency motor's vibration intensity, 0..1 range</param>
/// <param name="lowFrequency">Low frequency motor's vibration frequency in Hz</param>
/// <param name="highAmplitude">High frequency motor's vibration intensity, 0..1 range</param>
/// <param name="highFrequency">High frequency motor's vibration frequency in Hz</param>
public void SetMotorSpeedLeft(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency)
{
m_leftRumbleValues.SetRumbleValues(lowAmplitude, lowFrequency, highAmplitude, highFrequency);
var cmd = NPadDeviceIOCTLOutputCommand.Create(NPadDeviceIOCTLOutputCommand.NPadRumblePostion.Left);
m_leftRumbleValues.ApplyRumbleValues(ref cmd);
ExecuteCommand(ref cmd);
}
/// <summary>
/// Set the intensity and vibration frequency for the right low and high frequency rumble motors
/// </summary>
/// <param name="lowAmplitude">Low frequency motor's vibration intensity, 0..1 range</param>
/// <param name="lowFrequency">Low frequency motor's vibration frequency in Hz</param>
/// <param name="highAmplitude">High frequency motor's vibration intensity, 0..1 range</param>
/// <param name="highFrequency">High frequency motor's vibration frequency in Hz</param>
public void SetMotorSpeedRight(float lowAmplitude, float lowFrequency, float highAmplitude, float highFrequency)
{
m_rightRumbleValues.SetRumbleValues(lowAmplitude, lowFrequency, highAmplitude, highFrequency);
var cmd = NPadDeviceIOCTLOutputCommand.Create(NPadDeviceIOCTLOutputCommand.NPadRumblePostion.Right);
m_rightRumbleValues.ApplyRumbleValues(ref cmd);
ExecuteCommand(ref cmd);
}
}
}
#endif // UNITY_EDITOR || UNITY_SWITCH

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 10b79550bec1ec546ac93d5768427df9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,189 @@
#if UNITY_EDITOR || UNITY_SWITCH
using UnityEngine.InputSystem.Layouts;
using UnityEngine.Scripting;
#if UNITY_EDITOR
using UnityEditor;
#endif
[assembly: AlwaysLinkAssembly]
namespace UnityEngine.InputSystem.Switch
{
/// <summary>
/// Adds support for Switch NPad controllers.
/// </summary>
#if UNITY_EDITOR
[InitializeOnLoad]
#endif
#if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
public
#else
internal
#endif
static class SwitchConsoleSupport
{
static SwitchConsoleSupport()
{
#if UNITY_EDITOR || UNITY_SWITCH
InputSystem.RegisterLayout<NPad>(
matches: new InputDeviceMatcher()
.WithInterface("Switch")
.WithManufacturer("Nintendo")
.WithProduct("Wireless Controller"));
#endif
}
[RuntimeInitializeOnLoadMethod]
private static void InitializeInPlayer()
{
s_UnityVersion.ParseUnityVersion();
}
struct UnityVersion
{
public enum EType
{
Unknown,
Alpha,
Beta,
Final,
Patch,
Experimental
}
// [Version].[Major].[Minor][Type][Revision][Suffix]
// Example 2020.3.1f1
// Type being one of:
// a: alpha
// b: beta
// f: public ("final") release
// p: patch release(after final)
// x: experimental
private int Version { get; set; } // Main version (2018, 2019, 2020, 2021 etc)
private int Major { get; set; } // Tech-stream or LTS, e.g .1, .2, .3, .4
private int Minor { get; set; }
private int Revision { get; set; }
private EType Type{ get; set; }
// Must match main version
public bool IsVersionOrHigher(int versionIn, int majorIn = 0, int minorIn = 0, EType typeIn = EType.Unknown, int revisionIn = 0)
{
return Version == versionIn && Major >= majorIn && Minor >= minorIn && ((Type > typeIn || Type == typeIn && Revision >= revisionIn) || Type == EType.Unknown);
}
public bool IsMainVersionOrLater(int versionIn)
{
return Version >= versionIn;
}
// Package min Unity version compatibility is 2019.4 LTS so we don't expect to parse older version strings
public void ParseUnityVersion()
{
string unityVer = Application.unityVersion;
// Parse up to first '.' to read Unity version (year)
var startIdx = 0;
var endIdx = unityVer.IndexOf('.');
var verStr = unityVer.Substring(startIdx, endIdx - startIdx);
if(int.TryParse(verStr, out var version))
{
Version = version;
}
else
{
Debug.LogWarning("Failed to parse Unity version: " + unityVer);
}
// Parse up to second '.' for major revision
startIdx = endIdx + 1;
endIdx = unityVer.IndexOf('.', startIdx);
var majStr = unityVer.Substring(startIdx, endIdx - startIdx);
if (int.TryParse(majStr, out var major))
{
Major = major;
}
// Break down final part of version string, minor revision, type & suffix ([Minor][Type][Revision][Suffix])
startIdx = endIdx + 1;
// Check for -dots suffix and discard.
var suffixIdx = unityVer.IndexOf('-', startIdx);
string minStr = (suffixIdx != -1) ? unityVer.Substring(startIdx, suffixIdx - startIdx) : unityVer.Substring(startIdx);
// Check for China suffix ('c') and discard.
suffixIdx = minStr.IndexOf('c');
if (suffixIdx != -1)
{
minStr = minStr.Substring(0, suffixIdx);
}
Minor = 0;
Revision = 0;
Type = EType.Unknown;
char[] versionTypes = { 'a', 'b', 'f', 'p', 'x' }; // Known version identifiers
var typeIdx = minStr.IndexOfAny(versionTypes);
if (typeIdx != -1)
{
var type = minStr[typeIdx];
switch (type)
{
case 'a': Type = EType.Alpha; break;
case 'b': Type = EType.Beta; break;
case 'f': Type = EType.Final; break;
case 'p': Type = EType.Patch; break;
case 'x': Type = EType.Experimental; break;
default:
Debug.LogWarningFormat("Unrecognized type identifier ({0}) in Unity version string: {1}", type, unityVer);
break;
}
if (int.TryParse(minStr.Substring(0, typeIdx), out var minor))
{
Minor = minor;
}
else
{
Debug.LogWarning("Failed to parse minor version from Unity version string: " + unityVer);
}
if (int.TryParse(minStr.Substring(typeIdx + 1), out var revision))
{
Revision = revision;
}
else
{
Debug.LogWarning("Failed to parse revision from Unity version string: " + unityVer);
}
}
//Debug.LogFormat("Version: {0} Major: {1} Minor: {2} Type: {3} Revision: {4}\n", Version, Major, Minor, Type, Revision);
}
}
static UnityVersion s_UnityVersion;
// Attributes queries require a fix in the Switch player available in the following versions onwards
// (The attributes field is reusing part of the struct that was padding in older versions)
// 2021.2.0a10, 2021.1.1f1, 2020.3.4f1, 2019.4.24f1, Not supported in 2018 or older
public static bool NpadAttributesSupported()
{
if (s_UnityVersion.IsMainVersionOrLater(2022) // Will be supported in all versions of 2022 onward
|| s_UnityVersion.IsVersionOrHigher(2021, 2, 0, UnityVersion.EType.Alpha, 10)
|| s_UnityVersion.IsVersionOrHigher(2020, 3, 4, UnityVersion.EType.Final, 1)
|| s_UnityVersion.IsVersionOrHigher(2019, 4, 24, UnityVersion.EType.Final, 1))
{
return true;
}
else
{
return false;
}
}
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc10b23f19793734895f4ef18a67daf7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,17 @@
{
"name": "Unity.InputSystem.Switch",
"references": [
"Unity.InputSystem"
],
"includePlatforms": [
"Editor",
"Switch"
],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": []
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6374799de9bd44442818ee6dd5dbbfc5
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,31 @@
**Unity Companion Package License v1.0 ("_License_")**
Copyright © 2019 Unity Technologies ApS ("**_Unity_**")
Unity hereby grants to you a worldwide, non-exclusive, no-charge, and royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute the software that is made available with this License ("**_Software_**"), subject to the following terms and conditions:
1. *Unity Companion Use Only*. Exercise of the license granted herein is limited to exercise for the creation, use, and/or distribution of applications, software, or other content pursuant to a valid Unity development engine software license ("**_Engine License_**"). That means while use of the Software is not limited to use in the software licensed under the Engine License, the Software may not be used for any purpose other than the creation, use, and/or distribution of Engine License-dependent applications, software, or other content. No other exercise of the license granted herein is permitted.
1. *No Modification of Engine License*. Neither this License nor any exercise of the license granted herein modifies the Engine License in any way.
1. *Ownership & Grant Back to You*.
3.1. You own your content. In this License, "derivative works" means derivatives of the Software itself--works derived only from the Software by you under this License (for example, modifying the code of the Software itself to improve its efficacy); “derivative works” of the Software do not include, for example, games, apps, or content that you create using the Software. You keep all right, title, and interest to your own content.
3.2. Unity owns its content. While you keep all right, title, and interest to your own content per the above, as between Unity and you, Unity will own all right, title, and interest to all intellectual property rights (including patent, trademark, and copyright) in the Software and derivative works of the Software, and you hereby assign and agree to assign all such rights in those derivative works to Unity.
3.3. You have a license to those derivative works. Subject to this License, Unity grants to you the same worldwide, non-exclusive, no-charge, and royalty-free copyright license to derivative works of the Software you create as is granted to you for the Software under this License.
1. *Trademarks*. You are not granted any right or license under this License to use any trademarks, service marks, trade names, products names, or branding of Unity or its affiliates ("**_Trademarks_**"). Descriptive uses of Trademarks are permitted; see, for example, Unitys Branding Usage Guidelines at [https://unity3d.com/public-relations/brand](https://unity3d.com/public-relations/brand).
1. *Notices & Third-Party Rights*. This License, including the copyright notice above, must be provided in all substantial portions of the Software and derivative works thereof (or, if that is impracticable, in any other location where such notices are customarily placed). Further, if the Software is accompanied by a Unity "third-party notices" or similar file, you acknowledge and agree that software identified in that file is governed by those separate license terms.
1. *DISCLAIMER, LIMITATION OF LIABILITY*. THE SOFTWARE AND ANY DERIVATIVE WORKS THEREOF IS PROVIDED ON AN "AS IS" BASIS, AND IS PROVIDED WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR NONINFRINGEMENT. IN NO EVENT SHALL ANY COPYRIGHT HOLDER OR AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES (WHETHER DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL, INCLUDING PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS, AND BUSINESS INTERRUPTION), OR OTHER LIABILITY WHATSOEVER, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM OR OUT OF, OR IN CONNECTION WITH, THE SOFTWARE OR ANY DERIVATIVE WORKS THEREOF OR THE USE OF OR OTHER DEALINGS IN SAME, EVEN WHERE ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1. *USE IS ACCEPTANCE and License Versions*. Your receipt and use of the Software constitutes your acceptance of this License and its terms and conditions. Software released by Unity under this License may be modified or updated and the License with it; upon any such modification or update, you will comply with the terms of the updated License for any use of any of the Software under the updated License.
1. *Use in Compliance with Law and Termination*. Your exercise of the license granted herein will at all times be in compliance with applicable law and will not infringe any proprietary rights (including intellectual property rights); this License will terminate immediately on any breach by you of this License.
1. *Severability*. If any provision of this License is held to be unenforceable or invalid, that provision will be enforced to the maximum extent possible and the other provisions will remain in full force and effect.
1. *Governing Law and Venue*. This License is governed by and construed in accordance with the laws of Denmark, except for its conflict of laws rules; the United Nations Convention on Contracts for the International Sale of Goods will not apply. If you reside (or your principal place of business is) within the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the state and federal courts located in San Francisco County, California concerning any dispute arising out of this License ("**_Dispute_**"). If you reside (or your principal place of business is) outside the United States, you and Unity agree to submit to the personal and exclusive jurisdiction of and venue in the courts located in Copenhagen, Denmark concerning any Dispute.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0fc53242e6c9fbd4c88f90fb1e7eff9e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1 @@
Switch Devices and extension for new input system.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d07bdabda6639b447b233e47dca4e09f
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
{
"SuiteConfig":
{
"Targets":
[
"+Switch"
]
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fe4afccdf24f4148b8719f9a4ba5872a
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,17 @@
{
"name": "com.unity.inputsystem.switch",
"displayName": "Input System Switch",
"version": "0.1.6-pre",
"unity": "2019.4",
"description": "Switch Devices for new Input System",
"keywords": [
"input",
"keyboard",
"mouse",
"gamepad",
"touch"
],
"dependencies": {
"com.unity.inputsystem": "1.1.0-pre.5"
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f5132f131fbc3d14da629fca5b83a5e7
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Android;
using UnityEngine.InputSystem.DualShock;
using UnityEngine.InputSystem.XInput;
@ -24,6 +23,9 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
{
InputDevice_D newDevice = null;
if (ipdev is Keyboard) newDevice = new Keyboard_D(this);
#if UNITY_STANDALONE || UNITY_PS5 || UNITY_PS4 || UNITY_PS3 //PC/Mac/Linux/PS345 才能用 DualShock
else if (ipdev is DualShockGamepad)
{
if (ipdev is DualShock3GamepadHID) newDevice = new DualShockController_D(this, ps3: true);
@ -32,10 +34,15 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
else newDevice = new DualShockController_D(this);
}
#endif
#if UNITY_STANDALONE_WIN //仅Windows 才能用Xinput
else if (ipdev is XInputController)
{
newDevice = new XboxController_D(this);
}
#endif
else if (ipdev is Gamepad) newDevice = new GamePad_D(this); //注意Gamepad的优先级,因为任何手柄,Inputsystem中的基类都是GamePad
if (newDevice != null)
@ -281,25 +288,49 @@ namespace AxibugEmuOnline.Client.InputDevices.ForInputSystem
}
else if (device_d is GamePad_D gamepad_d)
{
var ipGamepad = ipdevice as Gamepad;
mapper[gamepad_d.Up] = ipGamepad.dpad.up;
mapper[gamepad_d.Down] = ipGamepad.dpad.down;
mapper[gamepad_d.Left] = ipGamepad.dpad.left;
mapper[gamepad_d.Right] = ipGamepad.dpad.right;
mapper[gamepad_d.Select] = ipGamepad.selectButton;
mapper[gamepad_d.Start] = ipGamepad.startButton;
mapper[gamepad_d.North] = ipGamepad.buttonNorth;
mapper[gamepad_d.South] = ipGamepad.buttonSouth;
mapper[gamepad_d.West] = ipGamepad.buttonWest;
mapper[gamepad_d.East] = ipGamepad.buttonEast;
mapper[gamepad_d.LeftShoulder] = ipGamepad.leftShoulder;
mapper[gamepad_d.RightShoulder] = ipGamepad.rightShoulder;
mapper[gamepad_d.LeftTrigger] = ipGamepad.leftTrigger;
mapper[gamepad_d.RightTrigger] = ipGamepad.rightTrigger;
mapper[gamepad_d.LeftStickPress] = ipGamepad.leftStickButton;
mapper[gamepad_d.RightStickPress] = ipGamepad.rightStickButton;
mapper[gamepad_d.LeftStick] = ipGamepad.leftStick;
mapper[gamepad_d.RightStick] = ipGamepad.rightStick;
if (ipdevice is UnityEngine.InputSystem.Switch.NPad ipdevice_ns)
{
mapper[gamepad_d.Up] = ipdevice_ns.dpad.up;
mapper[gamepad_d.Down] = ipdevice_ns.dpad.down;
mapper[gamepad_d.Left] = ipdevice_ns.dpad.left;
mapper[gamepad_d.Right] = ipdevice_ns.dpad.right;
mapper[gamepad_d.Select] = ipdevice_ns.selectButton;
mapper[gamepad_d.Start] = ipdevice_ns.startButton;
mapper[gamepad_d.North] = ipdevice_ns.xButton;
mapper[gamepad_d.South] = ipdevice_ns.bButton;
mapper[gamepad_d.West] = ipdevice_ns.yButton;
mapper[gamepad_d.East] = ipdevice_ns.aButton;
mapper[gamepad_d.LeftShoulder] = ipdevice_ns;
mapper[gamepad_d.RightShoulder] = ipdevice_ns.rightShoulder;
mapper[gamepad_d.LeftTrigger] = ipdevice_ns.leftTrigger;
mapper[gamepad_d.RightTrigger] = ipdevice_ns.rightTrigger;
mapper[gamepad_d.LeftStickPress] = ipdevice_ns.leftStickButton;
mapper[gamepad_d.RightStickPress] = ipdevice_ns.rightStickButton;
mapper[gamepad_d.LeftStick] = ipdevice_ns.leftStick;
mapper[gamepad_d.RightStick] = ipdevice_ns.rightStick;
}
else
{
var ipGamepad = ipdevice as Gamepad;
mapper[gamepad_d.Up] = ipGamepad.dpad.up;
mapper[gamepad_d.Down] = ipGamepad.dpad.down;
mapper[gamepad_d.Left] = ipGamepad.dpad.left;
mapper[gamepad_d.Right] = ipGamepad.dpad.right;
mapper[gamepad_d.Select] = ipGamepad.selectButton;
mapper[gamepad_d.Start] = ipGamepad.startButton;
mapper[gamepad_d.North] = ipGamepad.buttonNorth;
mapper[gamepad_d.South] = ipGamepad.buttonSouth;
mapper[gamepad_d.West] = ipGamepad.buttonWest;
mapper[gamepad_d.East] = ipGamepad.buttonEast;
mapper[gamepad_d.LeftShoulder] = ipGamepad.leftShoulder;
mapper[gamepad_d.RightShoulder] = ipGamepad.rightShoulder;
mapper[gamepad_d.LeftTrigger] = ipGamepad.leftTrigger;
mapper[gamepad_d.RightTrigger] = ipGamepad.rightTrigger;
mapper[gamepad_d.LeftStickPress] = ipGamepad.leftStickButton;
mapper[gamepad_d.RightStickPress] = ipGamepad.rightStickButton;
mapper[gamepad_d.LeftStick] = ipGamepad.leftStick;
mapper[gamepad_d.RightStick] = ipGamepad.rightStick;
}
}
else throw new System.NotImplementedException($"初始化设备失败,未实现的物理按键映射 for {device_d.GetType()}");
}