Package input arcade

This commit is contained in:
RiddimCrunch 2025-09-20 00:28:00 -04:00
commit 510a2961f6
24 changed files with 794 additions and 0 deletions

24
CHANGELOG.MD Normal file
View File

@ -0,0 +1,24 @@
# Changelog
All notable changes to this package will be documented in the notion.
## [1.0.0] - 2025-09-20
### Added
- Initial release of Conjure Arcade Controller package
- Custom Input Device implementation for Conjure Arcade Controllers
- Support for arcade joystick with directional buttons
- Support for 8 buttons (Home, Start, 1-3, A-C)
- Multi-controller support with controller indexing
- Input Action Asset extension methods for easy controller assignment
- Custom input processors for stick normalization
- Comprehensive documentation and examples
### Features
- `ConjureArcadeController` - Main controller device class
- `ConjureArcadeStickControl` - Custom stick control with directional buttons
- `ConjureArcadeControllerState` - HID input state definition
- `ConjureInputSystem` - Automatic registration and initialization
- `InputActionAssetExtension` - Helper methods for controller assignment
- Controller detection and management system
- Event system for controller connect/disconnect

7
CHANGELOG.MD.meta Normal file
View File

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

8
Documentation.meta Normal file
View File

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

174
README.md Normal file
View File

@ -0,0 +1,174 @@
# Conjure Arcade Controller Package
Unity Input System support for Conjure Arcade Controllers.
## Features
- Custom Input Device implementation for Conjure Arcade Controllers
- Arcade stick support with directional buttons (up, down, left, right)
- 8 button support (Home, Start, 1-3, A-C)
- Multi-controller support with controller indexing
- Integration with Unity's Input System
- Input Action Asset extensions for easy controller assignment
## Requirements
- Unity 2021.3 or later
- Unity Input System package (1.4.4 or later)
## Installation
### Via Package Manager (Git URL)
1. Open the Package Manager in Unity
2. Click the "+" button and select "Add package from git URL"
3. Enter the repository URL
### Via Package Manager (Local)
1. Download or clone this repository
2. Open the Package Manager in Unity
3. Click the "+" button and select "Add package from disk"
4. Select the `package.json` file from the downloaded folder
## Quick Start
### Basic Usage
```csharp
using ConjureOS.Input;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
void Update()
{
var controller = ConjureArcadeController.current;
if (controller == null) return;
// Read stick input
Vector2 stickInput = controller.stick.ReadValue();
// Check button presses
if (controller.buttonA.wasPressedThisFrame)
{
// Handle A button press
}
if (controller.start.wasPressedThisFrame)
{
// Handle start button press
}
}
}
```
### Using Input Actions
1. Create an Input Action Asset in your project
2. Add actions and bind them to Conjure controller inputs:
- Stick: `<ConjureArcadeController>/stick`
- Buttons: `<ConjureArcadeController>/buttonA`, `<ConjureArcadeController>/start`, etc.
```csharp
using ConjureOS.Input;
using UnityEngine;
using UnityEngine.InputSystem;
public class InputActionExample : MonoBehaviour
{
[SerializeField] private InputActionAsset inputActions;
void Start()
{
// Assign controller 0 to this input action asset
inputActions.AssignConjureController(0);
inputActions.Enable();
}
}
```
### Multi-Controller Support
```csharp
// Check how many controllers are connected
int controllerCount = ConjureArcadeController.ControllerCount;
// Get specific controller by index
ConjureArcadeController player1 = ConjureArcadeController.GetForIndex(0);
ConjureArcadeController player2 = ConjureArcadeController.GetForIndex(1);
// Check if controller exists for index
if (ConjureArcadeController.ExistForIndex(0))
{
// Controller 0 is available
}
```
## API Reference
### ConjureArcadeController
Main controller class that provides access to all inputs.
**Properties:**
- `stick` - ConjureArcadeStickControl for joystick input
- `home`, `start` - ButtonControl for system buttons
- `button1`, `button2`, `button3` - ButtonControl for numbered buttons
- `buttonA`, `buttonB`, `buttonC` - ButtonControl for lettered buttons
- `ControllerIndex` - The index of this controller instance
**Static Properties:**
- `current` - Currently active controller
- `allControllers` - Array of all connected controllers
- `ControllerCount` - Number of connected controllers
**Static Methods:**
- `ExistForIndex(int)` - Check if controller exists for index
- `GetForIndex(int)` - Get controller by index
**Events:**
- `OnControllerAdded` - Fired when a controller is connected
- `OnControllerRemoved` - Fired when a controller is disconnected
### ConjureArcadeStickControl
Custom stick control that provides both Vector2 input and directional buttons.
**Properties:**
- `up`, `down`, `left`, `right` - ButtonControl for directional input
- Standard Vector2Control properties for analog input
### InputActionAssetExtension
Extension methods for InputActionAsset to simplify controller assignment.
**Methods:**
- `AssignConjureController(int, bool)` - Assign specific controller to asset
- `CanAssignConjureController(int)` - Check if controller can be assigned
- `GetConjureControllerIndex()` - Get assigned controller index
- `GetConjureControllerIndexes()` - Get all assigned controller indexes
## Input Bindings
When setting up Input Actions, use these binding paths:
- **Stick (Vector2)**: `<ConjureArcadeController>/stick`
- **Stick Directions**:
- `<ConjureArcadeController>/stick/up`
- `<ConjureArcadeController>/stick/down`
- `<ConjureArcadeController>/stick/left`
- `<ConjureArcadeController>/stick/right`
- **Buttons**:
- `<ConjureArcadeController>/home`
- `<ConjureArcadeController>/start`
- `<ConjureArcadeController>/button1`
- `<ConjureArcadeController>/button2`
- `<ConjureArcadeController>/button3`
- `<ConjureArcadeController>/buttonA`
- `<ConjureArcadeController>/buttonB`
- `<ConjureArcadeController>/buttonC`
## Hardware Information
The controller is detected as:
- **Interface**: HID
- **Product**: "Generic USB Joystick " (note the extra spaces)

7
README.md.meta Normal file
View File

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

8
Runtime.meta Normal file
View File

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

View File

@ -0,0 +1,135 @@
#if ENABLE_INPUT_SYSTEM
using System;
using System.Collections.Generic;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Layouts;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable ClassNeverInstantiated.Global
// Reason: It's normal that some stuff is not used here because this is meant to be used as a library.
// ReSharper disable InconsistentNaming
// Reason: According to our code guidelines, property should be UpperCamelCase.
// However, to be consistent with other input devices in Unity (e.g. Joystick, Gamepad) we will use lowerCamelCase here.
namespace ConjureOS.Input
{
[InputControlLayout(stateType = typeof(ConjureArcadeControllerState), displayName = "Conjure Arcade Controller")]
public class ConjureArcadeController : InputDevice
{
public static event Action<ConjureArcadeController> OnControllerAdded;
public static event Action<ConjureArcadeController> OnControllerRemoved;
public ConjureArcadeStickControl stick { get; protected set; }
public ButtonControl home { get; protected set; }
public ButtonControl start { get; protected set; }
public ButtonControl button1 { get; protected set; }
public ButtonControl button2 { get; protected set; }
public ButtonControl button3 { get; protected set; }
public ButtonControl buttonA { get; protected set; }
public ButtonControl buttonB { get; protected set; }
public ButtonControl buttonC { get; protected set; }
public static ConjureArcadeController current { get; private set; }
public static ConjureArcadeController[] allControllers => allInstances.ToArray();
public static int ControllerCount => count;
/// <summary>
/// The controller index of this specific Conjure Arcade Controller.
/// The value will be between 0 and <see cref="ControllerCount"/> - 1.
/// If the value is -1, it means this controller was not initialized correctly and is not valid.
/// </summary>
public int ControllerIndex
{
get
{
try
{
return allInstances.IndexOf(this);
}
catch (ArgumentOutOfRangeException)
{
return -1;
}
}
}
/// <summary>
/// Whether or not a Conjure Arcade Controller exist for the following index.
/// </summary>
public static bool ExistForIndex(int controllerIndex)
{
return allInstances.Exists(instance => instance.ControllerIndex == controllerIndex);
}
/// <summary>
/// Get the Conjure Arcade Controller associated with the specific controller index.
/// </summary>
/// <returns>The controller if it exist for the specific index or null if it does not exist.</returns>
public static ConjureArcadeController GetForIndex(int controllerIndex)
{
return allInstances.Find(instance => instance.ControllerIndex == controllerIndex);
}
protected override void FinishSetup()
{
stick = GetChildControl<ConjureArcadeStickControl>("stick");
home = GetChildControl<ButtonControl>("home");
start = GetChildControl<ButtonControl>("start");
button1 = GetChildControl<ButtonControl>("button1");
button2 = GetChildControl<ButtonControl>("button2");
button3 = GetChildControl<ButtonControl>("button3");
buttonA = GetChildControl<ButtonControl>("buttonA");
buttonB = GetChildControl<ButtonControl>("buttonB");
buttonC = GetChildControl<ButtonControl>("buttonC");
base.FinishSetup();
}
public override void MakeCurrent()
{
base.MakeCurrent();
current = this;
}
protected override void OnAdded()
{
base.OnAdded();
if (!allInstances.Contains(this))
{
allInstances.Add(this);
++count;
OnControllerAdded?.Invoke(this);
}
}
protected override void OnRemoved()
{
if (current == this)
{
current = null;
}
if (allInstances.Remove(this))
{
--count;
OnControllerRemoved?.Invoke(this);
}
base.OnRemoved();
}
private static int count;
private static readonly List<ConjureArcadeController> allInstances = new();
}
}
#endif

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 036811b2c9f17694498f695d3074d167

View File

@ -0,0 +1,31 @@
namespace ConjureOS.Input
{
public static class ConjureArcadeControllerInfo
{
// The information in this class will need to change if we change the way the controller is made.
// Everything in this class needs to be static since it is used at compile time to setup the Conjure Arcade Controller state description.
public const string Interface = "HID";
public const string Product = "Generic USB Joystick "; // The extra spaces are normal as they are part of the product name created by the board's vendor
public const int StateSizeInBytes = 8;
public const int ReportIdByte = 0;
public const int StickXByte = 1;
public const int StickYByte = 1;
public const int ButtonByte = 7;
public enum ButtonBit : uint
{
Home = 0,
Start = 1,
One = 2,
Two = 3,
Three = 4,
A = 5,
B = 6,
C = 7,
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d8c08e87547cb3a4a8471054f99c9442

View File

@ -0,0 +1,53 @@
#if ENABLE_INPUT_SYSTEM
using System.Runtime.InteropServices;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.InputSystem.Utilities;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable FieldCanBeMadeReadOnly.Global
// Reason: This is a configuration class with specific requirements for its interface.
// ReSharper disable StringLiteralTypo
// ReSharper disable CommentTypo
// Reason: SHRT is not a typo in this case.
// Inspired by: https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/HID.html
// This class describes the data received by the controller in a way that can be read by the new input system.
// If the physical controller ever changes, this class will need to be reworked.
namespace ConjureOS.Input
{
[StructLayout(LayoutKind.Explicit, Size = ConjureArcadeControllerInfo.StateSizeInBytes)]
public struct ConjureArcadeControllerState : IInputStateTypeInfo
{
public FourCC format => new FourCC('H', 'I', 'D');
[FieldOffset(ConjureArcadeControllerInfo.ReportIdByte)]
public byte reportId;
[InputControl(name = "stick", layout = "ConjureArcadeStick", format = "VC2B", displayName = "Stick", processors = "ConjureArcadeVector2(minX=0.0, maxX=1.0, minY=0.0, maxY=1.0, invertY)")]
[InputControl(name = "stick/x", offset = 0, format = "BYTE", parameters = "clamp=false, invert=false, normalize=false")]
[InputControl(name = "stick/left", offset = 0, format = "BYTE")]
[InputControl(name = "stick/right", offset = 0, format = "BYTE")]
[InputControl(name = "stick/y", offset = 1, format = "BYTE", parameters = "clamp=false, invert=false, normalize=false")]
[InputControl(name = "stick/up", offset = 1, format = "BYTE")]
[InputControl(name = "stick/down", offset = 1, format = "BYTE")]
[FieldOffset(ConjureArcadeControllerInfo.StickXByte)]
public byte stickX;
[FieldOffset(ConjureArcadeControllerInfo.StickYByte)]
public byte stickY;
[InputControl(name = "home", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.Home, displayName = "Home")]
[InputControl(name = "start", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.Start, displayName = "Start")]
[InputControl(name = "button1", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.One, displayName = "Button 1", shortDisplayName = "1")]
[InputControl(name = "button2", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.Two, displayName = "Button 2", shortDisplayName = "2")]
[InputControl(name = "button3", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.Three, displayName = "Button 3", shortDisplayName = "3")]
[InputControl(name = "buttonA", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.A, displayName = "Button A", shortDisplayName = "A")]
[InputControl(name = "buttonB", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.B, displayName = "Button B", shortDisplayName = "B")]
[InputControl(name = "buttonC", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.C, displayName = "Button C", shortDisplayName = "C")]
[FieldOffset(ConjureArcadeControllerInfo.ButtonByte)]
public byte buttons;
}
}
#endif

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: afefdccae19d04943bdf5bb615f7325e

View File

@ -0,0 +1,46 @@
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Layouts;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// Reason: It's normal that some stuff is not used here because this is meant to be used as a library.
// ReSharper disable InconsistentNaming
// Reason: According to our code guidelines, property should be UpperCamelCase.
// However, to be consistent with other input controls in Unity (e.g. StickControl) we will use lowerCamelCase here.
// This class exists to allow the Conjure arcade stick input to work with the input system.
// It uses the ConjureArcadeValue processor in order to define the down/left/right/up buttons.
// It is registered in when ConjureInputSystem is initialized and is used for the stick input in the controller state.
namespace ConjureOS.Input
{
public class ConjureArcadeStickControl : Vector2Control
{
[InputControl(useStateFrom = "y", processors = "ConjureArcadeValue(min=0.0, max=1.0, invert)", synthetic = true, displayName = "Up")]
[InputControl(name = "x", minValue = -1f, maxValue = 1f, layout = "Axis", processors = "ConjureArcadeValue(min=0.0, max=1.0)", format = "BYTE", sizeInBits = 8)]
[InputControl(name = "y", minValue = -1f, maxValue = 1f, layout = "Axis", processors = "ConjureArcadeValue(min=0.0, max=1.0, invert)", format ="BYTE", sizeInBits = 8, offset = 1)]
public ButtonControl up { get; set; }
[InputControl(useStateFrom = "y" , processors = "ConjureArcadeValue(min=0.0, max=1.0)", synthetic = true, displayName = "Down")]
public ButtonControl down { get; set; }
[InputControl(useStateFrom = "x", processors = "ConjureArcadeValue(min=0.0, max=1.0, invert)", synthetic = true, displayName = "Left")]
public ButtonControl left { get; set; }
[InputControl(useStateFrom = "x", processors = "ConjureArcadeValue(min=0.0, max=1.0)", synthetic = true, displayName = "Right")]
public ButtonControl right { get; set; }
protected override void FinishSetup()
{
base.FinishSetup();
up = GetChildControl<ButtonControl>("up");
down = GetChildControl<ButtonControl>("down");
left = GetChildControl<ButtonControl>("left");
right = GetChildControl<ButtonControl>("right");
}
}
}
#endif

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ab2d6e2ab1431cf4faf722a4c7b0e16d

View File

@ -0,0 +1,79 @@
#if ENABLE_INPUT_SYSTEM
using JetBrains.Annotations;
using UnityEngine;
using UnityEngine.InputSystem;
// ReSharper disable ConvertToConstant.Local
// Reason: Attributes cannot be made into constants here since they are changed by Unity's internal input system.
// Those classes exist to allow the conversion of the stick input into a normalized (-1.0, 1.0) range.
// They are registered when ConjureInputSystem is initialized and are used for stick inputs in the controller state and the stick control.
namespace ConjureOS.Input
{
[UsedImplicitly]
public class ConjureArcadeVector2Processor : InputProcessor<Vector2>
{
private readonly float minX = -1.0f;
private readonly float maxX = 1.0f;
private readonly bool invertX = false;
private readonly float minY = -1.0f;
private readonly float maxY = 1.0f;
private readonly bool invertY = false;
private readonly float deadZone = 0.1f;
public override Vector2 Process(Vector2 value, InputControl control)
{
return new Vector2(
ConjureArcadeStickProcessorHelper.ProcessValue(value.x, minX, maxX, deadZone, invertX),
ConjureArcadeStickProcessorHelper.ProcessValue(value.y, minY, maxY, deadZone, invertY));
}
}
[UsedImplicitly]
public class ConjureArcadeValueProcessor : InputProcessor<float>
{
private readonly float min = -1.0f;
private readonly float max = 1.0f;
private readonly bool invert = false;
private readonly float deadZone = 0.1f;
public override float Process(float value, InputControl control)
{
return ConjureArcadeStickProcessorHelper.ProcessValue(value, min, max, deadZone, invert);
}
}
internal static class ConjureArcadeStickProcessorHelper
{
private const float MinStickValue = -1.0f;
private const float MaxStickValue = 1.0f;
private const float StickRange = MaxStickValue - MinStickValue;
internal static float ProcessValue(float originalValue, float min, float max, float deadZone, bool invert)
{
float zero = (min + max) / 2;
if (Mathf.Approximately(originalValue, zero))
{
return 0.0f;
}
float originalRange = max - min;
if (Mathf.Approximately(originalRange, 0.0f))
{
return 0.0f;
}
float processedValue = (((originalValue - min) * StickRange) / originalRange) + MinStickValue;
processedValue = Mathf.Clamp(processedValue, MinStickValue, MaxStickValue);
processedValue = invert ? -processedValue : processedValue;
processedValue = processedValue > -deadZone && processedValue < deadZone ? 0.0f : processedValue;
return processedValue;
}
}
}
#endif

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: eb4dcc44d20ac444ea46786d048561a3

View File

@ -0,0 +1,38 @@
using UnityEditor;
using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem;
#endif
namespace ConjureOS.Input
{
#if UNITY_EDITOR
[InitializeOnLoad]
#endif
public static class ConjureInputSystem
{
#if UNITY_EDITOR
static ConjureInputSystem()
{
Initialize();
}
#endif
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
private static void Initialize()
{
#if ENABLE_INPUT_SYSTEM
InputSystem.RegisterProcessor(typeof(ConjureArcadeVector2Processor), "ConjureArcadeVector2");
InputSystem.RegisterProcessor(typeof(ConjureArcadeValueProcessor), "ConjureArcadeValue");
InputSystem.RegisterLayout<ConjureArcadeStickControl>("ConjureArcadeStick");
InputSystem.RegisterLayout<ConjureArcadeController>(
matches: new InputDeviceMatcher()
.WithInterface(ConjureArcadeControllerInfo.Interface)
.WithProduct(ConjureArcadeControllerInfo.Product));
#endif
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: cb240260947f798488f8c7566ac4c85e

View File

@ -0,0 +1,24 @@
{
"name": "ConjureOS.Input",
"rootNamespace": "ConjureOS.Input",
"references": [
"Unity.InputSystem"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"ENABLE_INPUT_SYSTEM"
],
"versionDefines": [
{
"name": "com.unity.inputsystem",
"expression": "1.0.0",
"define": "ENABLE_INPUT_SYSTEM"
}
],
"noEngineReferences": false
}

View File

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

View File

@ -0,0 +1,109 @@
#if ENABLE_INPUT_SYSTEM
using System.Collections.Generic;
using System.Linq;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;
// ReSharper disable InvalidXmlDocComment
// Reason: We don't want to comment the "this" parameter in the extension functions.
namespace ConjureOS.Input
{
public static class InputActionAssetExtension
{
/// <summary>
/// Assign a specific Conjure Arcade Controller to this Input Action Asset.
/// All other Conjure Arcade Controllers will be disabled for this asset.
/// If the controller cannot be found for the controller index, there will be no assigned Conjure Arcade Controller.
/// </summary>
/// <param name="keepOtherDevices">
/// If this is false, all devices will be disabled for this Input Action Asset except for the Conjure Arcade Controller associated to the given controller index.
/// If this is true, the devices that are not Conjure Arcade Controller (e.g. mouse/keyboard) will not be disabled.
/// </param>
public static void AssignConjureController(this InputActionAsset inputActionAsset, int controllerIndex, bool keepOtherDevices = true)
{
List<InputDevice> inputDevices = new List<InputDevice>();
if (keepOtherDevices)
{
if (inputActionAsset.devices == null)
{
inputDevices.AddRange(InputSystem.devices);
}
else
{
inputDevices = new List<InputDevice>(inputActionAsset.devices);
}
inputDevices.RemoveAll(inputDevice => inputDevice is ConjureArcadeController);
}
ConjureArcadeController controller = ConjureArcadeController.GetForIndex(controllerIndex);
if (controller != null)
{
inputDevices.Add(controller);
}
inputActionAsset.devices = inputDevices.ToArray();
}
/// <summary>
/// Whether or not it is possible to assign a specific controller index to this Input Action Asset.
/// </summary>
public static bool CanAssignConjureController(this InputActionAsset inputActionAsset, int controllerIndex)
{
return ConjureArcadeController.ExistForIndex(controllerIndex);
}
/// <summary>
/// Get the controller index of the Conjure Arcade Controller associated with this Input Action Asset.
/// </summary>
/// <returns>
/// The controller index found.
/// If there was no Conjure Arcade Controller associated with this Input Action Asset, return false.
/// If there was multiple Conjure Arcade Controllers associated with this Input Action Asset, return the index of the first controller found.
/// </returns>
public static int GetConjureControllerIndex(this InputActionAsset inputActionAsset)
{
ConjureArcadeController[] controllers = GetConjureArcadeControllersFromDevices(inputActionAsset.devices);
if (controllers.Length == 0)
{
return -1;
}
return controllers[0].ControllerIndex;
}
/// <summary>
/// Get the controller index of all the Conjure Arcade Controllers associated with this Input Action Asset.
/// </summary>
/// <returns>
/// The controller indexes found.
/// If there was no Conjure Arcade Controller associated with this Input Action Asset, return an empty array.
/// </returns>
public static int[] GetConjureControllerIndexes(this InputActionAsset inputActionAsset)
{
ConjureArcadeController[] controllers = GetConjureArcadeControllersFromDevices(inputActionAsset.devices);
return controllers.Select(controller => controller.ControllerIndex).ToArray();
}
private static ConjureArcadeController[] GetConjureArcadeControllersFromDevices(ReadOnlyArray<InputDevice>? devices)
{
if (devices == null)
{
return ConjureArcadeController.allControllers;
}
List<ConjureArcadeController> controllers = new List<ConjureArcadeController>();
foreach (InputDevice inputDevice in devices)
{
if (inputDevice is ConjureArcadeController device)
{
controllers.Add(device);
}
}
return controllers.ToArray();
}
}
}
#endif

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bc3a0f8cabb44494e8be1efd5c3a73bf

23
package.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "com.conjureos.input",
"version": "1.0.0",
"displayName": "Conjure Arcade Controller",
"description": "Unity Input System support for Conjure Arcade Controllers. Provides custom input device implementation for arcade-style controllers with joystick and button controls.",
"unity": "2021.3",
"unityRelease": "0f1",
"dependencies": {
"com.unity.inputsystem": "1.4.4"
},
"keywords": [
"input",
"controller",
"arcade",
"joystick",
"hid"
],
"author": {
"name": "ConjureOS"
},
"type": "library",
"hideInEditor": false
}

7
package.json.meta Normal file
View File

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