自由研究#4 ランダム性を持たせる

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

 

ついに8月も終わりです。(※記事を公開するの忘れてたので、実はもう9月なのですが。。。)

私は夏休みの宿題を夏休みが終わってからやっていた悪い子供でした。

それは今も変わらずでして。

 

何が言いたいかというと、今回で終わらせたいんだけど、たぶん終わらないなぁって。

なかなか時間が取れなかったというのも大きいですが、やはり見切り発車がダメでしたね。

というわけで、今は下図のような感じで動くわけなんですけども、ご覧の通り寸分の狂いもなく正確な狙いとなっているわけです。

ピッチングマシンとして使う場合、これはすごく致命的なのではないでしょうか。

そこでランダム性を持たせたいと思います。

 

まず問題なのは、ワーク(=ボール)が常に定位置に生成されるということです。

これが多少ぶれるように設定します。

設定はLoadCreatorの設定から、Initial Placementで設定します(下図の黄色い部分)。

試しに20%で設定します。

その横のシークバーがCenterの位置にあるので、中心位置から左右に20%ほどぶれることになります。

 

実行してみると、下図のようになりました。

少しぶれるようになりました。(20%じゃわかりづらいですかね?)

 

これで多少のぶれはできたものの、あくまで上図でいう左右方向に少し距離が変わったくらいで、打ち出されるボールのスピードや、おそらく描く放物線なんかはほぼ同じはずです。

ですので、今度は高さ方向を変えていきたいと思います。

 

まずは高さ方向をどう変えるかということになります。現実的に考えれば、Pusherで押し出す角度を変えれば変わるはずなので、それを試してみたいと思います。

 

まずは水平方向

これを上方向に20度傾けてみると。。。。

打ち出される角度が変わりましたね。

じゃあこの角度をランダムに変更できればいいわけです。

 

残念ながらPusherにはランダムに角度を変えるような仕組みはありません。

そこで、どこかにPusherの角度をランダムに変える処理を組み込む必要があります。

じゃあどこに実装するかというと、コンベアの先端に設置されたセンサーです。

 

このセンサー、もともとスクリプトを持っており、センサーにワークが当たったときに処理が行われ、その中でPusherを動かしています。

ですので、Pusherの角度をランダムに変えるにはとても都合がいいということです。

 

ランダムな値の作り方は、過去にこのブログで書きましたね。

 

HDS#07 乱数の生成(デモンストレーション向け)

HDS#08 乱数の生成(シミュレーション向け)

 

ざっと試した感じ、30%になるとうまく飛ばないので、0=20%にしてみましょう。

function PusherSensor_OnBlocked( sender : Demo3D.Visuals.PhotoEye, load : Demo3D.Visuals.Visual )
{
    var pusher : Demo3D.Visuals.PusherVisual = sender.Pusher;
    if (pusher == null) return;
    if (!sender.PusherRules.Accept(load)) return;

    // 角度をランダムに変更
    var rnd = new System.Random();
    var value = rnd.Next(20);
    pusher.RotationXDegrees = value;
        
    wait(sender.PusherDelay);
    pusher.Activate();
    wait(sender.PusherDuration);
    pusher.Deactivate();
}
// 今回はJSのみ

(久しぶりにこれ使いましたね。。。。)

 

さて実行! してみたのですが、角度が変わらなかったです。

 

どうもPusherが動くときかどこかでもとの位置に戻されてしまうようなんですね。

これは困った。

じゃあ代案をと、コンベアの角度を変えてみたら、Pusherだけ角度が変わらない。

物理のKinematicをtrueにしてみると、角度は変わったけど元の位置に戻らない。

 

これはなぜかというと、どうやらモデル実行時の初期処理の中で物理動作を作成しているようで、その中でPusherがどのように動くかが定義され、後から関連のプロパティを変更しても、動き方はもう決まっているために、変更後のプロパティが反映されずにいるためです。

 

じゃあどうするかというと、プロパティを変えたところで物理動作の再作成をしてやればいいわけです。

再作成にはCreatePhysicsメソッドを使用します。

 

function PusherSensor_OnBlocked( sender : Demo3D.Visuals.PhotoEye, load : Demo3D.Visuals.Visual )
{
    var pusher : Demo3D.Visuals.PusherVisual = sender.Pusher;
    if (pusher == null) return;
    if (!sender.PusherRules.Accept(load)) return;

    // 角度をランダムに変更
    var rnd = new System.Random();
    var value = rnd.Next(20);
    pusher.RotationXDegrees = value;

    // 物理動作を再作成する
    pusher.CreatePhysics();
        
    wait(sender.PusherDelay);
    pusher.Activate();
    wait(sender.PusherDuration);
    pusher.Deactivate();
}
// 今回はJSのみ

これで実行すると、以下のようになりました。

いかがでしょうか。

ボールが飛ぶ場所に結構なばらつきが出ているのがわかるかと思います。

 

あとは同じ要領でForceやVelocityなんかをランダムで決めてからCreatePhysicsしてやれば、球速もランダムになります。

 

 

 

自由研究シーズンにやろうと思って強行したのが災いして、なかなかグダグダになってしまったこの企画。

まだまだ出来上がりではないので、夏休みシーズンは終わりましたが、もうちょっと続けてみようと思います。

(ちょうど、1回お休みしてしまったのもありますし)


 

ということで次回、「寸法を考慮する」をお送りする予定です。

更新は9/6(木)です。お楽しみに。