使用 C# .NET 从操纵杆获取输入

发布于 2024-09-27 13:13:42 字数 74 浏览 8 评论 0原文

我在谷歌上搜索了这个,但我想到的唯一的东西已经过时并且不起作用。

有人知道如何使用 C# .NET 获取操纵杆数据吗?

I searched around on Google for this, but the only things I came up with were outdated and did not work.

Does anyone have any information on how to get joystick data using C# .NET?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

空城仅有旧梦在 2024-10-04 13:13:42

由于这是我在研究 C# 中的操纵杆/游戏手柄输入时在 google 上获得的最高点击率,因此我认为我应该发布一个回复供其他人查看。

我发现最简单的方法是使用 SharpDX 和 DirectInput。您可以通过 NuGet (SharpDX.DirectInput) 安装它

之后,只需调用几个方法即可:

来自 SharpDX 的示例代码

static void Main()
{
    // Initialize DirectInput
    var directInput = new DirectInput();

    // Find a Joystick Guid
    var joystickGuid = Guid.Empty;

    foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad, 
                DeviceEnumerationFlags.AllDevices))
        joystickGuid = deviceInstance.InstanceGuid;

    // If Gamepad not found, look for a Joystick
    if (joystickGuid == Guid.Empty)
        foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick, 
                DeviceEnumerationFlags.AllDevices))
            joystickGuid = deviceInstance.InstanceGuid;

    // If Joystick not found, throws an error
    if (joystickGuid == Guid.Empty)
    {
        Console.WriteLine("No joystick/Gamepad found.");
        Console.ReadKey();
        Environment.Exit(1);
    }

    // Instantiate the joystick
    var joystick = new Joystick(directInput, joystickGuid);

    Console.WriteLine("Found Joystick/Gamepad with GUID: {0}", joystickGuid);

    // Query all suported ForceFeedback effects
    var allEffects = joystick.GetEffects();
    foreach (var effectInfo in allEffects)
        Console.WriteLine("Effect available {0}", effectInfo.Name);

    // Set BufferSize in order to use buffered data.
    joystick.Properties.BufferSize = 128;

    // Acquire the joystick
    joystick.Acquire();

    // Poll events from joystick
    while (true)
    {
        joystick.Poll();
        var datas = joystick.GetBufferedData();
        foreach (var state in datas)
            Console.WriteLine(state);
    }
}

我希望这会有所帮助。

我什至让它与 DualShock3 和 MotioninJoy 驱动程序一起使用。

Since this was the top hit I got on google while researching joystick / gamepad input in C#, I thought I should post a response for others to see.

The easiest way I found was to use SharpDX and DirectInput. You can install it via NuGet (SharpDX.DirectInput)

After that, it's simply a matter of calling a few methods:

Sample code from SharpDX

static void Main()
{
    // Initialize DirectInput
    var directInput = new DirectInput();

    // Find a Joystick Guid
    var joystickGuid = Guid.Empty;

    foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad, 
                DeviceEnumerationFlags.AllDevices))
        joystickGuid = deviceInstance.InstanceGuid;

    // If Gamepad not found, look for a Joystick
    if (joystickGuid == Guid.Empty)
        foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick, 
                DeviceEnumerationFlags.AllDevices))
            joystickGuid = deviceInstance.InstanceGuid;

    // If Joystick not found, throws an error
    if (joystickGuid == Guid.Empty)
    {
        Console.WriteLine("No joystick/Gamepad found.");
        Console.ReadKey();
        Environment.Exit(1);
    }

    // Instantiate the joystick
    var joystick = new Joystick(directInput, joystickGuid);

    Console.WriteLine("Found Joystick/Gamepad with GUID: {0}", joystickGuid);

    // Query all suported ForceFeedback effects
    var allEffects = joystick.GetEffects();
    foreach (var effectInfo in allEffects)
        Console.WriteLine("Effect available {0}", effectInfo.Name);

    // Set BufferSize in order to use buffered data.
    joystick.Properties.BufferSize = 128;

    // Acquire the joystick
    joystick.Acquire();

    // Poll events from joystick
    while (true)
    {
        joystick.Poll();
        var datas = joystick.GetBufferedData();
        foreach (var state in datas)
            Console.WriteLine(state);
    }
}

I hope this helps.

I even got this to work with a DualShock3 and the MotioninJoy drivers.

平定天下 2024-10-04 13:13:42

一:使用SlimDX

二:它看起来像这样(其中 GamepadDevice 是我自己的包装器,代码被精简为仅相关部分)。

查找操纵杆/手柄 GUID:

    public virtual IList<GamepadDevice> Available()
    {
        IList<GamepadDevice> result = new List<GamepadDevice>();
        DirectInput dinput = new DirectInput();
        foreach (DeviceInstance di in dinput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
        {
            GamepadDevice dev = new GamepadDevice();
            dev.Guid = di.InstanceGuid;
            dev.Name = di.InstanceName;
            result.Add(dev);
        }
        return result;
    }

用户从列表中选择后,获取游戏手柄:

   private void acquire(System.Windows.Forms.Form parent)
    {
        DirectInput dinput = new DirectInput();

        pad = new Joystick(dinput, this.Device.Guid);
        foreach (DeviceObjectInstance doi in pad.GetObjects(ObjectDeviceType.Axis))
        {
            pad.GetObjectPropertiesById((int)doi.ObjectType).SetRange(-5000, 5000);
        }

        pad.Properties.AxisMode = DeviceAxisMode.Absolute;
        pad.SetCooperativeLevel(parent, (CooperativeLevel.Nonexclusive | CooperativeLevel.Background));
        pad.Acquire();
    }

轮询手柄如下所示:

        JoystickState state = new JoystickState();

        if (pad.Poll().IsFailure)
        {
            result.Disconnect = true;
            return result;
        }

        if (pad.GetCurrentState(ref state).IsFailure)
        {
            result.Disconnect = true;
            return result;
        }

        result.X = state.X / 5000.0f;
        result.Y = state.Y / 5000.0f;
        int ispressed = 0;
        bool[] buttons = state.GetButtons();

One: use SlimDX.

Two: it looks something like this (where GamepadDevice is my own wrapper, and the code is slimmed down to just the relevant parts).

Find the joystick / pad GUIDs:

    public virtual IList<GamepadDevice> Available()
    {
        IList<GamepadDevice> result = new List<GamepadDevice>();
        DirectInput dinput = new DirectInput();
        foreach (DeviceInstance di in dinput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
        {
            GamepadDevice dev = new GamepadDevice();
            dev.Guid = di.InstanceGuid;
            dev.Name = di.InstanceName;
            result.Add(dev);
        }
        return result;
    }

Once the user has selected from the list, acquire the gamepad:

   private void acquire(System.Windows.Forms.Form parent)
    {
        DirectInput dinput = new DirectInput();

        pad = new Joystick(dinput, this.Device.Guid);
        foreach (DeviceObjectInstance doi in pad.GetObjects(ObjectDeviceType.Axis))
        {
            pad.GetObjectPropertiesById((int)doi.ObjectType).SetRange(-5000, 5000);
        }

        pad.Properties.AxisMode = DeviceAxisMode.Absolute;
        pad.SetCooperativeLevel(parent, (CooperativeLevel.Nonexclusive | CooperativeLevel.Background));
        pad.Acquire();
    }

Polling the pad looks like this:

        JoystickState state = new JoystickState();

        if (pad.Poll().IsFailure)
        {
            result.Disconnect = true;
            return result;
        }

        if (pad.GetCurrentState(ref state).IsFailure)
        {
            result.Disconnect = true;
            return result;
        }

        result.X = state.X / 5000.0f;
        result.Y = state.Y / 5000.0f;
        int ispressed = 0;
        bool[] buttons = state.GetButtons();
合约呢 2024-10-04 13:13:42

坏消息是 Microsoft 似乎停止支持 DirectX 的 NET 库,转而专注于 XNA。我不在 GameDev 工作,所以我不需要使用 XNA,但如果你开发电脑游戏,你可以尝试一下。好消息是还有其他方法。其中之一是 SlimDX 新框架,可帮助您从 C# 使用 DirectX。另一种方法是直接将“Microsoft.DirectX.dll”和“Microsoft.DirectX.DirectInput.dll”的引用添加到您的项目中。您可以找到它们“..\Windows\Microsoft.NET\DirectX for Managed Code\”。如果您打算使用最后一种方法,这里有一个链接codeproject,您可以在其中可以阅读如何使用操纵杆。

编辑:
如果您的应用程序基于 NET 版本较新的 2.0,则该应用程序可能会挂起。要解决此问题,请更改配置文件并添加以下内容:

<startup useLegacyV2RuntimeActivationPolicy="true"> 

The bad news is that Microsoft seems to stop supporting their NET libraries for DirectX and focus on XNA instead. I don't work in GameDev so I don't need to use XNA but you may try it if you developing computer games. The good news is that there are other approaches. One is SlimDX the new framework to help you to wok with DirectX from C#. The other way is to directly add references of "Microsoft.DirectX.dll" and "Microsoft.DirectX.DirectInput.dll" to your project. you can find them "..\Windows\Microsoft.NET\DirectX for Managed Code\". if you you are going to use last approach here is a link to codeproject where you can read how to work with a joystick.

EDIT:
If your application is based on NET version newer then 2.0 the application may hang on. To fix this problem change config file and add this:

<startup useLegacyV2RuntimeActivationPolicy="true"> 
简美 2024-10-04 13:13:42

Google 引导我来到这里,虽然不是这个问题的要求,但 OpenTK 是一个不错的选择Windows 和 Linux(在单声道下)支持。

来自 OpenTK 文档,此代码适用于 Raspberry Pi + Raspbian + Mono 3.12.0:

for (int i = 0; i < 4; i++)
{
    var state = Joystick.GetState(i);
    if (state.IsConnected)
    {
        float x = state.GetAxis(JoystickAxis.Axis0);
        float y = state.GetAxis(JoystickAxis.Axis1);

        // Print the current state of the joystick
        Console.WriteLine(state);
    }
}

Google led me here and while not a requirement of this question, OpenTK is a good option for Windows and Linux (under mono) support.

From the OpenTK docs, this code works on Raspberry Pi + Raspbian + Mono 3.12.0:

for (int i = 0; i < 4; i++)
{
    var state = Joystick.GetState(i);
    if (state.IsConnected)
    {
        float x = state.GetAxis(JoystickAxis.Axis0);
        float y = state.GetAxis(JoystickAxis.Axis1);

        // Print the current state of the joystick
        Console.WriteLine(state);
    }
}
箜明 2024-10-04 13:13:42

这个问题很老了,但直到今天它似乎仍然很活跃,所以我还是要发帖。

如果您只需要从 XInput 获取输入,请查看 XInputium。这是一个专门用于 XInput 控制器的 .NET 库。它非常简单,并且有许多代码示例可供您查看。

This question is old, but it seems to be active even to this day, so I'm posting anyway.

If you need to get input from XInput only, take a look at XInputium. This is a .NET library that is specialized in XInput controllers. It is pretty straightforward, and has many code samples you can look at.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文