Other Fixed it. Reminder: Passing ZERO to PlayerIndex returns Player One's Game Pad.
XInput stopped working on Unity 5.3.x
Yes, another XInput-related question. lmao.
Anyway, I have no idea what to do with the DLLs "XInputDotNetPure" and "XInputInterface". They simply refuse to activate/connect pads to my game now. (other XInput apps work on my laptop, Even Device Manager says it's good and connected. Used to work just fine, and now I can't get any response/connection out of the damn thing. I connect, reconnect the pad to the USB 3.0 slot, updated to the absolute latest driver from Microsoft. Nothing works. The pad model I have is Logitech F310 wired controller, XInput mode compatible.
In the past, I had put them in Assets/Plugins/x86_64, then just Assets/Plugins/ and it worked just fine. Now with this Plugin inspector I'm confused. I have NO idea whatsoever how to set them up to work. Unity knows the plugins are in the project because I reference XInputDotNetPure.dll in my source code and get zero errors.
I have both plugins from the unitypackage in Assets, no subfolder. I copied XInputInterface.dll into my project root as per the instructions. But I can't get my connected pads to do a darn thing. It refuses to connect to the game. Unity even displays a message in its console saying "Joystick Connected (my controller)" But the actual game I'm developing tries to use XInputDotNetPure and will not initialize the pad at all. I get no actual errors or warnings. But, interestingly, when I build and play, I get an error message telling me the build can't find the plugin. This is confusing the heck out of me, since it seems to do this on a per-project basis, and will work sometimes and sometimes not. I had updated to Unity 5.3.3 and even tried to downgrade to 5.3.1 which had worked before. Seriously, nothing's working and I'm starting to get pissed.
I'm on Windows 8.1
Game pad code "XInput_Controller.cs"
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using XInputDotNetPure;
// Rumble (vibration) event
class xiRumble
{
public float xi_RumbleTimer; // Rumble timer
public float xi_FadeTime; // Fade-out time (in seconds)
public Vector2 xi_Power; // Intensity of rumble
// Decrease timer
public void Update()
{
this.xi_RumbleTimer -= Time.deltaTime;
}
}
// Main pads.
public class XInput_Controller
{
// Indices.
private PlayerIndex xi_PadID; // Pad ID / Index.
// Game Pad's states.
private GamePadState xi_Current; // Current Pad state.
private GamePadState xi_Previous; // Previous Pad state.
// Rumble.
private List<xiRumble> rumbleEvents; // Stores rumble events
public XInput_Controller(int id)
{
if (id == 1 || id == 2 || id == 3 || id == 4)
{
xi_PadID = (PlayerIndex)id; // Same value as a PlayerIndex.
xi_Current = GamePad.GetState(xi_PadID);
}
else
{
Debug.Log(id.ToString() + " isn't a valid Game Pad index!");
}
rumbleEvents = new List<xiRumble>();
}
// Accessing private vars for If statements.
public bool GetConnection()
{
return xi_Current.IsConnected;
}
public int GetPadID()
{
return (int)xi_PadID;
}
public GamePadState GetCurrentState()
{
return xi_Current;
}
public GamePadState GetPreviousState()
{
return xi_Previous;
}
public void UpdatePad()
{
xi_Previous = xi_Current;
xi_Current = GamePad.GetState(xi_PadID);
HandleRumble();
}
/*
* BUTTON TAPS
* Used for single-frame button taps, such as for menus.
*/
// Tap the A Button.
public bool TapA()
{
if (xi_Current.IsConnected && xi_Current.Buttons.A == ButtonState.Pressed && xi_Previous.Buttons.A == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the B Button.
public bool TapB()
{
if (xi_Current.IsConnected && xi_Current.Buttons.B == ButtonState.Pressed && xi_Previous.Buttons.B == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the X Button.
public bool TapX()
{
if (xi_Current.IsConnected && xi_Current.Buttons.X == ButtonState.Pressed && xi_Previous.Buttons.X == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the Y Button.
public bool TapY()
{
if (xi_Current.IsConnected && xi_Current.Buttons.Y == ButtonState.Pressed && xi_Previous.Buttons.Y == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the Start Button.
public bool TapStart()
{
if (xi_Current.IsConnected && xi_Current.Buttons.Start == ButtonState.Pressed && xi_Previous.Buttons.Start == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the Back Button.
public bool TapBack()
{
if (xi_Current.IsConnected && xi_Current.Buttons.Back == ButtonState.Pressed && xi_Previous.Buttons.Back == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the X Button.
public bool TapLB()
{
if (xi_Current.IsConnected && xi_Current.Buttons.LeftShoulder == ButtonState.Pressed && xi_Previous.Buttons.LeftShoulder == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the X Button.
public bool TapRB()
{
if (xi_Current.IsConnected && xi_Current.Buttons.RightShoulder == ButtonState.Pressed && xi_Previous.Buttons.RightShoulder == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the Left D Pad Button.
public bool TapDPad_Left()
{
if (xi_Current.IsConnected && xi_Current.DPad.Left == ButtonState.Pressed && xi_Previous.DPad.Left == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the Right D Pad Button.
public bool TapDPad_Right()
{
if (xi_Current.IsConnected && xi_Current.DPad.Right == ButtonState.Pressed && xi_Previous.DPad.Right == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the Up D Pad Button.
public bool TapDPad_Up()
{
if (xi_Current.IsConnected && xi_Current.DPad.Up == ButtonState.Pressed && xi_Previous.DPad.Up == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap the Down D Pad Button.
public bool TapDPad_Down()
{
if (xi_Current.IsConnected && xi_Current.DPad.Down == ButtonState.Pressed && xi_Previous.DPad.Down == ButtonState.Released)
{
return true;
}
else
{
return false;
}
}
// Tap Left on Left Stick.
public bool TapLeft_Left()
{
if (xi_Current.IsConnected && xi_Current.ThumbSticks.Left.X <= -0.1f && xi_Previous.ThumbSticks.Left.X == 0.0f)
{
return true;
}
else
{
return false;
}
}
// Tap Right on Left Stick.
public bool TapLeft_Right()
{
if (xi_Current.IsConnected && xi_Current.ThumbSticks.Left.X >= 0.1f && xi_Previous.ThumbSticks.Left.X == 0.0f)
{
return true;
}
else
{
return false;
}
}
// Tap Up on Left Stick.
public bool TapLeft_Up()
{
if (xi_Current.IsConnected && xi_Current.ThumbSticks.Left.Y >= 0.1f && xi_Previous.ThumbSticks.Left.Y == 0.0f)
{
return true;
}
else
{
return false;
}
}
// Tap Down on Left Stick.
public bool TapLeft_Down()
{
if (xi_Current.IsConnected && xi_Current.ThumbSticks.Left.Y <= -0.1f && xi_Previous.ThumbSticks.Left.Y == 0.0f)
{
return true;
}
else
{
return false;
}
}
// Tap Left on Right Stick.
public bool TapRight_Left()
{
if (xi_Current.IsConnected && xi_Current.ThumbSticks.Right.X <= -0.1f && xi_Previous.ThumbSticks.Right.X == 0.0f)
{
return true;
}
else
{
return false;
}
}
// Tap Right on Right Stick.
public bool TapRight_Right()
{
if (xi_Current.IsConnected && xi_Current.ThumbSticks.Right.X >= 0.1f && xi_Previous.ThumbSticks.Right.X == 0.0f)
{
return true;
}
else
{
return false;
}
}
// Tap Up on Right Stick.
public bool TapRight_Up()
{
if (xi_Current.IsConnected && xi_Current.ThumbSticks.Left.Y >= 0.1f && xi_Previous.ThumbSticks.Left.Y == 0.0f)
{
return true;
}
else
{
return false;
}
}
// Tap Down on Right Stick.
public bool TapRight_Down()
{
if (xi_Current.IsConnected && xi_Current.ThumbSticks.Left.Y <= -0.1f && xi_Previous.ThumbSticks.Left.Y == 0.0f)
{
return true;
}
else
{
return false;
}
}
// Tap Any button. (Usually for title and Challenger Approaching screens. Excludes taps of sticks and shoulders)
public bool TapAny()
{
if (xi_Current.IsConnected && TapA() || TapB() || TapX() || TapY() || TapStart() || TapBack())
{
return true;
}
else
{
return false;
}
}
/*
* BUTTON PRESSES
* Used for when the buttons are pressed down for multi-frame, like for gameplay.
*/
// Press the A Button.
public bool PressA()
{
if (xi_Current.IsConnected && xi_Current.Buttons.A == ButtonState.Pressed)
{
return true;
}
else
{
return false;
}
}
// Press the B Button.
public bool PressB()
{
if (xi_Current.IsConnected && xi_Current.Buttons.B == ButtonState.Pressed)
{
return true;
}
else
{
return false;
}
}
// Press the X Button.
public bool PressX()
{
if (xi_Current.IsConnected && xi_Current.Buttons.X == ButtonState.Pressed)
{
return true;
}
else
{
return false;
}
}
// Press the Y Button.
public bool PressY()
{
if (xi_Current.IsConnected && xi_Current.Buttons.Y == ButtonState.Pressed)
{
return true;
}
else
{
return false;
}
}
// Press the Left Shoulder Trigger Button.
public float PressLT()
{
return xi_Current.Triggers.Left;
}
// Press the Right Shoulder Trigger Button.
public float PressRT()
{
return xi_Current.Triggers.Right;
}
// Press the Left Shoulder Trigger Button left or right.
public float PressLeftStick_X()
{
return xi_Current.ThumbSticks.Left.X;
}
// Press the Left Shoulder Trigger Button Up or Down
public float PressLeftStick_Y()
{
return xi_Current.ThumbSticks.Left.Y;
}
// Press the Right Shoulder Trigger Button left or right.
public float PressRightStick_X()
{
return xi_Current.ThumbSticks.Right.X;
}
// Press the Right Shoulder Trigger Button left or right.
public float PressRightStick_Y()
{
return xi_Current.ThumbSticks.Right.Y;
}
/* RUMBLE CODE.
* User for force feedback such as when landing heavy hits.
*/
// Add rumble to the pad.
public void AddRumble(float timer, Vector2 power, float fadeTime)
{
xiRumble rumble = new xiRumble();
rumble.xi_RumbleTimer = timer;
rumble.xi_Power = power;
rumble.xi_FadeTime = fadeTime;
rumbleEvents.Add(rumble);
}
// This is for executing the rumbles.
void HandleRumble()
{
// Ignore if there are no events
if (rumbleEvents.Count > 0)
{
Vector2 currentPower = new Vector2(0, 0);
for (int i = 0; i < rumbleEvents.Count; ++i)
{
// Update current event
rumbleEvents[i].Update();
if (rumbleEvents[i].xi_RumbleTimer > 0)
{
// Calculate current power
float timeLeft = Mathf.Clamp(rumbleEvents[i].xi_RumbleTimer / rumbleEvents[i].xi_FadeTime, 0f, 1f);
currentPower = new Vector2(Mathf.Max(rumbleEvents[i].xi_Power.x * timeLeft, currentPower.x),
Mathf.Max(rumbleEvents[i].xi_Power.y * timeLeft, currentPower.y));
// Apply vibration to gamepad motors
GamePad.SetVibration(xi_PadID, currentPower.x, currentPower.y);
}
else
{
// Remove expired event
rumbleEvents.Remove(rumbleEvents[i]);
}
}
}
}
}
This code was taken and adapted for my game from the tutorial in the top comment block.
Here's how they're initialized in a Singleton I wrote specifically for global game variables.
// -Snippet from Awake function in a singleton called GlobalVars.cs.
gb_ConnectedPads = new List<XInput_Controller>(); // Create 4 controller slots.
for (int ctrls = 0; ctrls <= 3; ++ctrls)
{
gb_ConnectedPads.Add(new XInput_Controller(ctrls + 1));
Debug.Log("Pad no. " + (ctrls + 1).ToString() + " 's connection status: " + gb_ConnectedPads[ctrls].GetConnection().ToString());
}
The Debug command is to try and figure out what the hey is going on with this.
Thanks all.
Answer by TabuuForteAkugun · Feb 28, 2016 at 03:17 AM
I got it working again. Turns out, I was passing incorrect values to XInput_Controller's constructor. I forgot that ZERO actually represents Player One's controller!! So since I was passing 1, 2, 3 and 4, Player One was completely ignored, not by Unity, but by that one flaw in the constructor that mucked everything up.
0 = PlayerIndex ONE.
Remember this, folks!