ひでぼ~blog

C#ときどきゲーム

ViGEm.NETを使って仮想ゲームコントローラを作る

ViGEm.NETというライブラリを使ってC#で簡単な仮想ゲームコントローラを作ってみます。 ViGEmはVirtual Gamepad Emulator Frameworkの略だそうです。読み方は謎です。C#用のライブラリが公開されているので使っていきます。

github.com

実行環境

準備

Visual Studioで作成したプロジェクトにNuGetでNefarius.ViGEm.Clientをインストールします。ターゲットフレームワークが.NET Framework4.5.2でないと動かないので注意です。 f:id:hideb3:20211231111651p:plain

また、以下からViGEmBusのインストーラをDLしてインストールしておきます。 github.com

コントローラの作成

ViGEmではXbox360のコントローラとPS4のコントローラ(DualShock4)が作成できます。今回はXbox360のコントローラを作成して接続してみます。

var client = new ViGEmClient();
var controller = client.CreateXbox360Controller();
controller.Connect();

実行するとUSBデバイスを接続する音が鳴り、デバイス一覧を確認するとXbox360Controllerが接続されているのを確認できます。 f:id:hideb3:20211231094235p:plain

ボタンとスティックの操作

コントローラのボタンを押したり、スティックを動かしたりしてみます。

var client = new ViGEmClient();
var controller = client.CreateXbox360Controller();
controller.Connect();

controller.SetAxisValue(Xbox360Axis.LeftThumbX, short.MaxValue);
controller.SetButtonState(Xbox360Button.X, true);

Console.ReadLine();

実行後にデバイスの設定を確認してみると、左スティックが右一杯に入っていることとボタン3が押されているのを確認できます。 f:id:hideb3:20211231095906p:plain

一連の操作を自動化する

コナミコマンドを入力してみます。ボタンの入力時間(duration)をセットできるように拡張メソッド(ControllerExtension)を追加しています。

internal class Program
{
    static void Main(string[] args)
    {
        var client = new ViGEmClient();
        var controller = client.CreateXbox360Controller();
        controller.Connect();

        while (true)
        {
            RunKonmaiCommand(controller);
        }

        controller.Disconnect();
    }

    static void RunKonmaiCommand(IXbox360Controller controller)
    {
        var duration = 500;//ms

        controller.SetAxisValue(Xbox360Axis.LeftThumbY, short.MaxValue, duration);
        controller.SetAxisValue(Xbox360Axis.LeftThumbY, short.MaxValue, duration);
        controller.SetAxisValue(Xbox360Axis.LeftThumbY, short.MinValue, duration);
        controller.SetAxisValue(Xbox360Axis.LeftThumbY, short.MinValue, duration);

        controller.SetAxisValue(Xbox360Axis.LeftThumbX, short.MinValue, duration);
        controller.SetAxisValue(Xbox360Axis.LeftThumbX, short.MaxValue, duration);
        controller.SetAxisValue(Xbox360Axis.LeftThumbX, short.MinValue, duration);
        controller.SetAxisValue(Xbox360Axis.LeftThumbX, short.MaxValue, duration);

        controller.SetButtonState(Xbox360Button.B, true, duration);
        controller.SetButtonState(Xbox360Button.A, true, duration);
    }
}

public static class ControllerExtension
{
    public static void SetAxisValue(this IXbox360Controller controller, Xbox360Axis axis, short value, int duration)
    {
        controller.SetAxisValue(axis, value);
        Thread.Sleep(duration);
        controller.SetAxisValue(axis, 0);
    }

    public static void SetButtonState(this IXbox360Controller controller, Xbox360Button button, bool pressed, int duration)
    {
        controller.SetButtonState(button, pressed);
        Thread.Sleep(duration);
        controller.SetButtonState(button, false);
    }
}

参考

forums.vigem.org