週刊ラジコンモデル#1 Xboxコントローラの入力

こんにちは、開発担当の杉原です。

 

会議にてテコ入れ指示があったので、今週からは「週刊ラジコンモデル」という企画ものをやってみようと思います。

ちょうど10月にはいったところですので、10月いっぱい使って全4回でお送りする予定です。

 

企画名は言うまでもないかもしれませんが、本屋というよりかはテレビCMなんかでよく目にする、毎号ついてくるパーツを集めると完成品になるあれのインスパイアです。

ですので、8月の自由研究のように、グダグダにならないよう、4回分の記事を読めば目的のものが作れるようにしていきたいと思います。頑張ります。

 さて、まずは作りたいものを簡単に説明します。

百聞は一見に如かず、ということで動画をご覧ください。

(GIFアニメーションはいろいろ制約あって辛かったので、ブログ用にアカウント作りました)

冒頭3秒は何もしてない状態が続いていますが、そこから視点が変わって、人の後ろ側にカメラが回ります。

そして、PCに接続されたコントローラによる操作で人や視点が動きます。

さらに、コントローラが2台接続され、View Windowが2つ存在すると、モデル上にいる二人がそれぞれ個別に動きます。

 

と、ここまで書いてこのあたりのコントローラと人の連動が上記動画ではわかりづらいなぁと感じたので、操作の様子を撮影していました。

画面に対してコントローラの配置が逆になってますが、なんとなくは伝わるかなと。

あと、触ってなくても左画面の人が動いていますが、どうやらスティックをニュートラルにしているはずが、入力値がニュートラルになっていないようです(コントローラの故障?)。

 

このモデルは以前社内で「XboxコントローラでVisualを動かせないか」という話になったときに試しに作ったものを、暇だったのでさらに改造を加えて普段やってるゲームみたいな操作感にしてみたものです。

ただ未解決の課題として、動画の通り人は棒立ちのまま移動してしまって見栄えがよくないので、今回は人ではなく乗り物で表現してみようかなと思います。

というわけで、おなじみのフォークリフトでも動かしてみようかと思います。

もし試してみられる方がいましたら、この後の手順でフォークリフトのスクリプトは真っ新にしてしまうので、いい感じの3Dモデルをインポートしてみても面白いかもしれません。

 

てわけで、今ぽろっと漏らした通り、スクリプトを真っ新にしてしまいます。

プロパティウィンドウからScriptプロパティを探して、Noneを選択します。

そして新たにスクリプトを追加してやれば、まっさらなスクリプトで始めることができます。

 

まずはコントローラからの入力を受け付けてみたいと思います。

OnInitializeイベントの処理を追加して、次のような処理を実装します。

function Forklift1_OnInitialize( sender : Demo3D.Visuals.BoxVisual )
{
    // コントローラの取得
    var controllers = Demo3D.Input.Controller.GetControllers();
    if (controllers.Count < 1) return;
    var controller = controllers[0];
        
    // 入力チェックループ
    while(true) {
        wait(0.1);
                
        if (controller.Poll()) {
            print("X:" + controller.X + " Y:" + controller.Y);
        }
    }
}
[Auto] IEnumerable OnInitialize(Visual sender) {
    // コントローラの取得
    List controllers = Controller.GetControllers();
    if (controllers.Count < 1) yield break;
    Controller controller = controllers[PlayerIndex.Value];

    // 入力チェックループ
    while(true) {
    yield return Wait.ForSeconds(refreshTime);
        if (controller.Poll()) {
            print("X:" + controller.X + " Y:" + controller.Y);
        }
    }
}

モデルを実行すると、0.1秒ごとにコントローラの状態を取得して、左スティックのX軸(横方向)とY軸(縦方向)の値をメッセージログに出力し続けます。

(このとき、実行開始時点でコントローラがつながっていないと何も起きませんので注意してください)

 

仕組みについて説明していきます。

まずDemo3D.Input名前空間にあるControllerクラスの静的メソッドGetControllers()を実行して、PCに接続されているコントローラをすべて取得します。

このとき、コントローラの接続が無ければ、得られるリストは空っぽなので、要素数をチェックして1に満たなければ処理を終了させます。そうでなければ、リストの先頭の要素を取得します(リストにはおそらくPCに接続した順でコントローラの参照が格納されていると思います)。

 

そして無限ループを作成し、その中で0.1秒の待ちを行います。なお、なんとなくで実装しちゃいましたが、この0.1秒はモデル内の時間であることには注意したほうが良いかもしれません。

 

コントローラのPollメソッドを呼び出すと、コントローラの入力状態が取得され、各プロパティの値が更新されます。

左スティックのX軸はXプロパティ、Y軸はYプロパティによって値を取得できるので、その値をそのまま出力しています。

 

ちなみにこの部分の実装や、X軸、Y軸以外の状態を取得するためのプロパティはマニュアルにあるHandle Game Controller And Steering Wheelの項目にも記述されていますので、そちらも参考にしていただければと思います。


 

次回の週刊ラジコンモデルでは、今回得た入力情報をもとに「モデルを動かす」部分を実装したいと思います。

更新は10/11(木)、第2号も0円です。お楽しみに。