XboxOne Gamepad Vibration for Unity3d

    Unity3d has universal controller support through the Input class. After pre-setting the axes and buttons, you can achieve the tolerable operation of any controller. Unfortunately, there will be no vibration support for the Xbox 360 and Xbox One gamepads. You can fix this situation 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 wrapper XInput was made which works in this version.

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


    Next, the resulting assembly must be transferred to the Assets directory, and all the classes that you implemented will become available from Unity. It’s 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, we create the Store Apps / Class project for our plugin in the same solution Library: You



    can use the same plugin code, in our case you don’t even have to make any 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 name of the plug-in file for the Windows Store should coincide with the version for Desktop:


    If everything is done correctly, then Unity will “pick up” the replacement when creating the version of the application for the Windows Store and the final assembly of the application in Visual Studio 2013 will work correctly.

    The plugin itself is simple, and essentially a wrapper over the 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 attendant classes.

    Using a gamepad plugin


    As already mentioned, now it’s enough to place the plug-in assemblies in the corresponding directories / Assets and / Assets / Metro , after which the functions will be available when developing the Unity application:

    Usually, gamepads are operated in polling mode before rendering each frame. In Unity, each object has a void Update () method in which it will be possible to query 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 helicopterwhich flies among the mountains. Rather, it certainly does not fly, but “floats” since the full implementation of helicopter physics is beyond the scope of this article.

    At the same time, it responds to input from the gamepad from all axes, DPAD and, by pressing the right trigger, "accelerates" accelerating forward and untwisting 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);
            }
    }
    


    The object of the helicopter is associated with Box Collider and RigidBody. This makes it possible to receive notifications of collisions with other objects, and in fact vibration is realized here. As soon as the helicopter collides with the mountain, the gamepad begins to vibrate for 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 code of the XInput wrapper at http://aka.ms/unitygmsmpl; if you need only wrapper, you can only download the archive 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



    Also popular now: