I just had to swtich because of the issues the old system was giving me on a game that supports kb, gamepad and steeringwheels. If it wasn´t for the steering there would be no need to switch.
Do I find the new system a conptraption or and endless rabithole? kinda. YET. I present you a way to switch smoothly
Build a singleton script that receives all the input. You can process all the inputs in there, and from other scripts just read theese input values.
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;
using System.Linq;
public class NewInputSystem_Manager : MonoBehaviour
{
public static NewInputSystem_Manager Instance;
public PlayerInput pInput;
public InputActionAsset actionAsset;
[Space]
[Space]
public InputActionReference action_accel;
public InputActionReference action_brake;
public InputActionReference action_clutch;
public InputActionReference action_steer;
public InputActionReference action_steerStrong;
public InputActionReference action_handbrake;
public InputActionReference action_gearUp;
public InputActionReference action_gearDown;
public InputActionReference action_H_Gear_1;
public InputActionReference action_H_Gear_2;
public InputActionReference action_H_Gear_3;
public InputActionReference action_H_Gear_4;
public InputActionReference action_H_Gear_5;
public InputActionReference action_H_Gear_6;
public InputActionReference action_H_Gear_R;
public InputActionReference action_changeCam;
public InputActionReference action_CarReset;
public InputActionReference action_Pause;
public InputActionReference action_LightsOn;
public InputActionReference action_StartEngine;
public InputActionReference action_DebugInfo;
public float Input_Accel;
public float Input_Brake;
public float Input_Clutch;
public float Input_Steer;
public float Input_SteerStrong ;
public float Input_Handbrake;
public bool Input_GearUp;
public bool Input_GearDown;
public bool Input_H_Gear_1;
public bool Input_H_Gear_2;
public bool Input_H_Gear_3;
public bool Input_H_Gear_4;
public bool Input_H_Gear_5;
public bool Input_H_Gear_6;
public bool Input_H_Gear_R;
public bool Input_changeCam;
public bool Input_CarReset;
public bool Input_Pause;
public bool Input_LightsOn;
public bool Input_StartEngine;
public bool Input_DebugInfo;
[System.Serializable]
public struct AxisConfig
{
public bool invert;
public bool normalize;
public float deadzone; // Valor entre 0 y 1 (por ejemplo, 0.05 para una pequeña deadzone)
// Constructor
public AxisConfig(bool invert, bool normalize, float deadzone)
{
this.invert = invert;
this.normalize = normalize;
this.deadzone = deadzone;
}
}
public AxisConfig accelConfig;
public AxisConfig brakeConfig;
public AxisConfig clutchConfig = new AxisConfig(false,true,0);
public AxisConfig steerConfig;
public AxisConfig handbrakeConfig;
private void Start()
{
Instance = this;
}
void SetScheme(InputControlScheme Scheme)
{
Debug.Log( "SCHEME RECEIVED = " + Scheme);
/*
for (int i = 0; i < actionAsset.controlSchemes.Count; i++)
{
Debug.Log($"[{i}] {actionAsset.controlSchemes[i].name}");
}
*/
// string SchemeName = Scheme.name;
switch (Scheme.name)
{
case "Keyboard":
pInput.SwitchCurrentControlScheme(Scheme.name);//, Keyboard.current
break;
case "Gamepad":
pInput.SwitchCurrentControlScheme(Scheme.name );//UnityEngine.InputSystem.Gamepad.current
break;
case "SteeringWheel":
//InputDevice wheelDevice = default;
// Lista de fabricantes y productos conocidos (logitech, thrustmaster, fanatec, moza, simucube, saitek)
string[] knownManufacturers = { "Logitech", "Thrustmaster", "Fanatec", "MOZA", "Simucube", "Saitek", "Mad Catz" };
string[] knownProducts = {
// Logitech (desde G25 hasta los más nuevos)
"G25", "G27", "G29", "G920", "G923", "G923 Racing Wheel", "G923", "Logitech G Pro Racing",
// Thrustmaster
"T300", "T500", "T150", "TX", "T300 RS", "T300 Ferrari GTE", "T-GT",
"T-GT II", "T500 RS", "TS-PC Racer", "TS-XW Racer", "T150 Pro", "T80", "T150 Ferrari", "T-LCM",
"Thrustmaster T500RS",
// Fanatec
"DD1", "DD2", "Clubsport", "Clubsport V2", "Clubsport V2.5", "CSL Elite",
"Podium Racing Wheel", "CSL Elite Racing", "CSL DD", "Podium DD1", "Podium DD2",
// MOZA
"R5", "R9", "R16",
// Simucube
"Simucube 2", "Simucube 2 Pro", "Simucube 2 Ultimate",
// Saitek (Mad Catz)
"R440", "R100", "Pro Racing Wheel", "Dual Force Racing Wheel", "Mad Catz Racing Wheel"
};
// Buscar dispositivo compatible
foreach (var device in InputSystem.devices)
{
if (device.description.interfaceName.Contains("HID") || device.description.product.Contains("Wheel")) // Dispositivos HID
{
bool isKnownManufacturer = knownManufacturers.Any(m => device.description.manufacturer.Contains(m));
bool isKnownProduct = knownProducts.Any(p => device.description.product.Contains(p));
bool isGenericWheel = device.description.product.Contains("Wheel") || device.description.product.Contains("Joystick");
// Almacenamos el primer volante que coincida
if (isKnownManufacturer || isKnownProduct || isGenericWheel)
{
// Verificar que el dispositivo sea adecuado (en lugar de asignarlo directamente)
//wheelDevice = InputDevice.steeringWheel;
Debug.Log($"✅ Volante detectado: {UnityEngine.InputSystem.Joystick.current.description.manufacturer} - {UnityEngine.InputSystem.Joystick.current.description.product}");
pInput.SwitchCurrentControlScheme(Scheme.name, UnityEngine.InputSystem.Joystick.current);
return; // Termina la ejecución de la función después de encontrar un volante
}
}
}
return; // Termina la ejecución de la función después de encontrar un volante
}
// pInput.SwitchCurrentControlScheme(Scheme);
}
private void Update()
{
/*
Input_Accel = action_accel.action.ReadValue<float>();
Input_Brake = action_brake.action.ReadValue<float>();
Input_Clutch = action_clutch.action.ReadValue<float>();
Input_Handbrake = action_handbrake.action.ReadValue<float>();
var device = InputSystem.GetDevice<Joystick>(); // o usa Gamepad si prefieres
if (device != null)
{
// Si el dispositivo es un mando de PlayStation (DualSense)
if (device.name.Contains("DualSense"))
{
// Lee el Vector2 completo del stick izquierdo
Input_Steer = action_steer.action.ReadValue<Vector2>().x;
}
else Input_Steer = action_steer.action.ReadValue<float>();
}
else if( device == null || !device.name.Contains("DualSense")) Input_Steer = action_steer.action.ReadValue<float>();
*/
//STEERING INPUT
//--------------------------------------------------------------------------------------
var device = InputSystem.GetDevice<Joystick>(); // o usa Gamepad si prefieres
if (device != null)
{
// Si el dispositivo es un mando de PlayStation (DualSense)
if (device.name.Contains("DualSense"))
{
// Lee el Vector2 completo del stick izquierdo
Input_Steer = action_steer.action.ReadValue<Vector2>().x;
}
else Input_Steer = action_steer.action.ReadValue<float>();
}
else if (device == null || !device.name.Contains("DualSense")) Input_Steer = action_steer.action.ReadValue<float>();
//--------------------------------------------------------------------------------------
Input_Accel = ProcessAxis(action_accel.action.ReadValue<float>(), accelConfig); // Procesamos el acelerador
Input_Brake = ProcessAxis(action_brake.action.ReadValue<float>(), brakeConfig); // Procesamos el freno
Input_Clutch = ProcessAxis(action_clutch.action.ReadValue<float>(), clutchConfig); // Procesamos el clutch
Input_Handbrake = ProcessAxis(action_handbrake.action.ReadValue<float>(), handbrakeConfig); // Procesamos el freno de mano
Input_SteerStrong = action_steerStrong.action.ReadValue<float>();
Input_GearUp = action_gearUp.action.WasPressedThisFrame();
Input_GearDown = action_gearDown.action.WasPressedThisFrame();
Input_H_Gear_1 = action_H_Gear_1.action.WasPressedThisFrame();
Input_H_Gear_2 = action_H_Gear_2.action.WasPressedThisFrame();
Input_H_Gear_3 = action_H_Gear_3.action.WasPressedThisFrame();
Input_H_Gear_4 = action_H_Gear_4.action.WasPressedThisFrame();
Input_H_Gear_5 = action_H_Gear_5.action.WasPressedThisFrame();
Input_H_Gear_6 = action_H_Gear_6.action.WasPressedThisFrame();
Input_H_Gear_R = action_H_Gear_R.action.WasPressedThisFrame();
Input_changeCam = action_changeCam.action.WasPressedThisFrame();
Input_CarReset = action_CarReset.action.WasPressedThisFrame();
Input_Pause = action_Pause.action.WasPressedThisFrame();
Input_LightsOn = action_LightsOn.action.WasPressedThisFrame();
Input_StartEngine = action_StartEngine.action.WasPressedThisFrame();
Input_DebugInfo = action_DebugInfo.action.WasPressedThisFrame();
//Debug.Log("Input_H_Gear_R " + Input_H_Gear_R);
}
float ProcessAxis(float valueRaw, AxisConfig config)
{
float cleanValue = valueRaw;
if (Mathf.Abs(valueRaw) < config.deadzone)
{
cleanValue = 0f;
}
if (config.normalize) // Normaliza el valor si está activado, con soporte de inversión
{
cleanValue = NormalizeAxis(valueRaw, -1f, 1f, config.invert);
}
else if (config.invert)
{
cleanValue = -valueRaw;
}
return cleanValue;
}
float NormalizeAxis(float rawInput, float minValue = -1f, float maxValue = 1f, bool invert = false)
{
float normalizedValue = (rawInput - minValue) / (maxValue - minValue); // Normaliza el valor del rawInput al rango [0,1]
if (invert)// Si se requiere invertir, transformamos el rango [0,1] a [-1, 0] o viceversa
{
return normalizedValue * -1;// Si invertimos, el valor de [0, 1] se convierte en [-1, 0]
}
else
{
return normalizedValue;// Si no invertimos, el valor de [-1, 1] pasa a [0, 1]
}
}
}
You need to use the Player Input script of the system for it to work
Then, on your scripts use it like this:
for bools
if (NewInputSystem_Manager.Instance.Input_H_Gear_1) car.HGearManager(1);
for floats
RAWSteerInput = NewInputSystem_Manager.Instance.Input_Steer ;
With an structure like this you can navigate the new input system without having to change your mind with the event approach, which honestly sucks, and the extended use of strings in such approach is a deathtrap whaiting for you at the worst moment.
The only issues I found so far, are the issue with the horizontal left analog in PS4-PS5 controllers, reads as vector 2 instead of float, may or may not be a bug, makes my code looks like shiet.
The major one may be that even is you switch schemes, it does not mute the other inputs from other schemes, it does allegedly prioritize the input hardware asigned to such scheme, in my experience, a noisy PS5 controlelr many times tries to get on top when using steering wheel. I find this a major limitation, nearly a bug. I can´t believe that 4-5 years later documentation is so poor on this scheme switching “feature”.
Other htan that I’m quite happy, has solved my input issues. But the path untill I got to this simple solution has been harsh.