週刊ラジコンモデル#4 マルチプレイ

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

 

自宅のPS3が壊れてディスク読み込みができなくなり、ブルーレイ再生のためだけにPS4Proを買ったのですが、後日なんとなしにPS3分解したら復活し、PS4が不要になってしまいました(原因はディスクドライブへの異物混入。子供の仕業ですね)。

買った意味がないどころか、それから1か月も経たずにPS4Proが値下げしまして、泣きっ面に蜂です。

悔しいので何かゲームを買おうと考えているんですけども、何かないですかね?

友達がいない(いないとは言っていない)ので、対戦ゲームはNGです!

 

と言いつつも、今回はマルチプレイについてご紹介。

あ、一応今回が「週刊ラジコンモデル」の最終号になります。

正直言ってしまうと、わざわざ最終回に説明するような内容でもなく、前々回のコントローラ入力と、前回のカメラ取得の処理を応用するだけでなんとかなるお話ではあります。

というのも、配列から要素を取り出すときのインデックス値をプレーヤーごとに変えればいいだけだからです。

 

てわけで、まずは「どのプレーヤーが操作する車両なのか」を判別するためのプロパティを追加します。

 

せっかくなので今回はちょっと違った方法で。

普段、プロパティの追加は画面のプロパティウィンドウから追加することが多いかと思いますが、今回はスクリプトからプロパティを追加してみます。

function Forklift1_OnReset( sender : Demo3D.Visuals.BoxVisual )
{
    if (!defined(sender.PlayerIndex)) {
        sender.AddSimpleProperty("PlayerIndex", 0, "");
    }
}
[Auto] SimpleProperty<int> PlayerIndex;

 

JScriptとC#ではそれぞれ違った方法を採用しています。

 

まずはJScript側から。この方法はC#でもできますが、C#の場合は後述の方法のほうが楽だと思います。

OnResetイベントなんかで追加したいプロパティPlayerIndexが定義されているかを確認し、定義されていない場合はプロパティを追加する方法です。

 

次にC#のコード。

こちらはイベントメソッド内ではなく、その外側でメンバ変数として定義しています。

ポイントは先頭にAuto属性をつけていること。これによって、変数名と同じ名前のプロパティに対してバインドすることが可能となり、また同じ名前のプロパティが無いときはプロパティを自動で作成してくれます。

 

こうした手段でプロパティを追加することで、すでにモデル上にスクリプトを参照するVisualが複数個あったときに1つ1つプロパティ追加作業を地道にやっていく手間がなくなります。

 

さて、これでプロパティPlayerIndexが追加され、プレーヤを識別する準備ができました。

プレーヤーの識別は、後続処理の都合上プレイヤー1が「0」、プレイヤー2が「1」というふうに識別値を設定するものとします。

 

次に、このPlayerIndexによって使用するコントローラを切り替えるようにしてみます。

// コントローラの取得
var controllers = Demo3D.Input.Controller.GetControllers();
if (controllers.Count <= sender.PlayerIndex) return;
var controller = controllers[sender.PlayerIndex];
// コントローラの取得
List controllers = Controller.GetControllers();
if (controllers.Count <= PlayerIndex.Value) yield break;
Controller controller = controllers[PlayerIndex.Value];

GetControllersメソッドで取得する値は配列なので、そこから値を取り出すときのインデックス値をPlayerIndexに変えるだけですね。

ただ、指定するインデックス値が配列の要素数より大きいとエラーとなるので、配列の要素数とPlayerIndexの比較を忘れずに行ってください。

 

次はカメラの取得。

// カメラの取得
var view = app.Display.GetView(sender.PlayerIndex);
if (view == null) return;
var camera = view.Camera;
    // カメラの取得
IView view = app.Display.GetView(PlayerIndex.Value);
if (view == null) yield break;
Camera camera = view.Camera;

こちらも似たような感じですね。

コントローラと違う点としては、配列へアクセスするのではなく、GetViewメソッドの引数としてインデックス値を取得する点です。

この場合、指定したインデックス値が範囲外だった場合はnull値が返されるため、nullチェックを忘れずに行ってください。

 

これでマルチプレイの準備ができました。

フォークリフトをコピーして2台にし、コントローラも2台接続して、Demo3DのViewWindowも2つにします。

なおViewWindowの増やし方ですが、リボンのHomeタブにある[Windows]の中に[View Window]というものがありますので、これをクリックすればもう1つView Windowが作成されます。

これでマルチプレイを確認できたはずです。

 

Demo3Dによるラジコンモデル作成、いかがでしたでしょうか。

4週にわたって紹介しておいてなんですが、これはDemo3Dの本来の用途からは外れていると思います。

私にはこれをどう生かしていくかなんてのは考えが及ばず、忘年会の出し物程度でしか思っていないのですが、この記事をここまで読んでくださった方の中には、これを生かした何かをひらめかれる方がいるかもしれません。

ですので、これからも時折こうしたヘンテコ記事を公開していって、お客様がDemo3Dを活用するためのひらめきの種になっていけたらなと思っていますので、よろしくお願いします。


 

次週からは【How to Demo3D Scripting】を再開しようと考えていますが、今のところ更新内容は未定となっています。すみません。

更新予定日は11/1(木)です。お楽しみに。