📜 ⬆️ ⬇️

Vibration of the XboxOne gamepad for Unity3d

Unity3d has universal controller support via the Input class. After pre-setting the axes and buttons, you can achieve a tolerable work of any controller. Unfortunately, there will be no support for vibration for the Xbox 360 and Xbox One gamepads. You can correct this situation by using, for example, the XInputDotNet plugin, but as it turned out, this plugin is not ready for use in Windows Store applications. Therefore, a small XInput wrapper was made which works in this version.

Creating plugins for Unity3d is quite a simple process. To do this, you need to create a Class Library project in Visual Studio 2013, and do not forget to switch to .NET Framework 3.5 use mode.


Next, the resulting assembly must be transferred to the Assets directory, and all the classes that you have implemented will be available from Unity. It is also convenient to place the Solution of your plugin directly in the directory in which the Unity project is located, and specify Output in the Assets directory:


In order for the same plugin to work in the Windows Store application mode, in the same Solution for our plugin we create the Store Apps / Class Library project:
')


The code of the plug-in can be used the same, in our case you don’t even have to do some conditional compilation conditions, the source files for both assemblies will be the same and you can simply link them:

The build option for the Windows Store should be located in the Assets / Plugins / Metro directory:


Needless to say, the file name of the plug-in for Windows Store should match the option for Desktop:


If everything is done correctly, then Unity, when creating a version of the application for the Windows Store, “picks up” the replacement and the final build of the application in Visual Studio 2013 will take place correctly.

The plugin itself is simple, and in fact is a wrapper over XInput functions:

[DllImport("xinput1_4.dll")] public static extern int XInputGetState ( int dwUserIndex, ref XInputState pState ); [DllImport("xinput1_4.dll")] public static extern int XInputSetState ( int dwUserIndex, ref XInputVibration pVibration ); 

All necessary structures are prepared in accompanying classes.

Using the plugin to work with the gamepad


As already mentioned, it is now sufficient to place the assembly of the plug-in in the appropriate directories / Assets and / Assets / Metro , after which the functions will be available when developing the Unity application:

Usually, work with gamepads is carried out in query mode (polling) before drawing each frame. In Unity, each object has a void Update () method in which it will be possible to interrogate the state of buttons and axes and, depending on them, make changes to the behavior of game objects.
As an example, you can look at the finished Unity project, which works both in desktop mode and can create an application for the Windows Store. This is a helicopter that flies among the mountains. Rather, of course, it does not fly, but “floats” since the full realization of helicopter physics is beyond the scope of this article.

At the same time, it reacts to input from the gamepad from all axes, DPAD and by pressing the right trigger “moves” accelerating forward and unwinding the main and tail screws:

 void Update () { XInputWrapper.XInputState st=new XInputWrapper.XInputState(); XInputWrapper.XInput.XInputGetState(0, ref st); if (Mathf.Abs(st.Gamepad.sThumbLY) > XInputWrapper.XInputConstants.XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { float rotX_norm = (float)((float)st.Gamepad.sThumbLY / 32767.0f); transform.RotateAround(transform.position, transform.right, rotX_norm * 20.0f*-1.0f * Time.deltaTime); } } 


Box Collider and RigidBody are associated with the helicopter object. This makes it possible to receive notifications about collisions with other objects, and the vibration is actually implemented here. As the helicopter hits the mountain, the gamepad vibrates a third of a second:

  void OnTriggerEnter(Collider other) { if (!vibrating) { XInputWrapper.XInputVibration vibr = new XInputWrapper.XInputVibration(); vibr.LeftMotorSpeed = 65535 / 3; vibr.RightMotorSpeed = 65535 / 3; XInputWrapper.XInput.XInputSetState(0, ref vibr); vibrationStartTime = Time.time; vibrating = true; } } 


You can download the finished project for Unity and the source codes of the XInput wrapper at http://aka.ms/unitygmsmpl; if you only need a wrapper, you can download the archive only with assemblies at http://aka.ms/xinputwrapper . By the way, they can be used not only in Unity projects, but also for desktop applications and Windows store applications, including those written in HTML5 / Javascript.

useful links


Source: https://habr.com/ru/post/243021/


All Articles