OpenBVE 日本語リファレンス

チュートリアル:OpenBVEで交通信号を作ってみよう

OpenBVEでアニメーションを製作する方法についてはリファレンスのほうで触れましたが、それでは一体どのように製作すれば良いのでしょうか?
ここでは、一定間隔で表示を変える交通信号機を例に、アニメーションの基本的な方法について解説していきます。

下準備:テクスチャ・モデルデータの用意

資料写真とテクスチャ素材の撮影

私の場合には、信号機そのものを撮った写真というものは手元にありませんでした。
従って、そこの写真を撮ることから始めます。
信号機 信号機 信号機 信号機
※写真は全てフリー素材とします。ご自由にお使いください。

資料集めと寸法決め

寸法 写真を撮ったら、今度は資料集めとモデリングに入ります。
信号機の明確な寸法などは資料がすぐには見つかりませんが、信号機のレンズの直径をGoogleで検索すると、 一般的には300mmの直径のものが多いようです。
撮影したものも300mm直径のもののようですので、その写真を元に、レンズと本体の大きさの比率を考えて本体の寸法を推測します。
今回は、信号機本体の大きさが横1230mm、高さ380mmとすることにしました。
それに合わせて、他のパーツなども製作していくことにします。

モデリング

モデリングの様子 信号機のモデリングを行い、テクスチャの配置を行います。
openBVEではxファイルを扱えるため、使用できるのであれば市販のモデリングツールを使用してオブジェクトを製作します。
ここではメタセコイアとxファイル出力プラグインを使用することにしました。
openBVEでは圧縮されたxファイルは読み込めないので、出力の際には無圧縮テキスト形式で出力してください。
詳しくは当該ソフトの説明書を参照されることをオススメします。
なお、動作は部品単位で行うため、出力する際には動かしたい部品別に出力する必要があります。ここでは、本体、支柱、看板を別々に出力しました。

ここのチュートリアルで扱うフリー素材のモデルデータをダウンロードできます。
オブジェクトは素材としてご自由にお使いください。
■素材モデルデータのダウンロード(zip形式)

animatedファイルを作る

信号機テクスチャ さて、モデルデータが準備できたら、今度はanimatedファイルの製作です。
アニメーションオブジェクトの製作で述べたように、animatedファイルとは アニメーションオブジェクトの動作情報を定義するファイルです。
今回ここでやるべき動作は主に、時間に合わせて信号機の色を変えることになります。
信号機の色を変えるには色々な方法がありますが、ここでは最も簡単に、 あらかじめ3通りの点灯方法を画像データに並べておき、テクスチャをシフトさせることによってアニメーションさせることとします。

本体部分の骨組みを作成

ここからは、trafficsig.animatedファイルを作成し、その中身を記述していきます。
まずはオブジェクトを定義します。セミコロンから始まる行はコメントです。
;trafficsig.animated ;本体オブジェクト
[object]
States=signal.x
ここまでの記述を行ってopenbveでtrafficsig.animatedファイルを読み込むと、信号本体だけが浮いているオブジェクトが描画されます。

時間によるアニメーションの変化

さて、ここからいよいよアニメーションさせる段に入ります。
ここで、openBVEのアニメーションオブジェクト特有の、時間に応じたアニメーションを行うことになります。
時間に応じたアニメーションは式でその動きを定義しますが、初心者には大変分かりにくいものです。
ここではそのアニメーション方法を分かりやすく記述していきます。

テクスチャをシフトさせる構文

TextureShiftYFunction = 式 面に張られたテクスチャを移動させる(UVアニメーションさせる)構文は、TextureShift(XorY)Function構文になります。
移動は、50%移動するなら0.5、100%(結局元通りに見えます))移動するなら1を指定することになります。
今回の信号機の画像は縦向きにシフトするため、YFunctionを使用します。
では、試しにTextureShiftYFunctionを数値で入れてみましょう。
;trafficsig.animated ;本体オブジェクト
[object]
States=signal.x
TextureShiftYFunction = 0.1
テクスチャが下方向に若干ずれたことが分かりましたでしょうか?
このときのズレ量は、テクスチャのサイズ768pxの10%、つまり76.8pxずれていることになります。
このテクスチャは256pxで1つの表示を再現しているため(青、黄、赤合計で768px)、実際に信号を変える場合には33%ずらす必要性がありますね。

式のイメージ

では、いよいよ1秒刻みで33%ずつずらす数式を作りましょう。ここでポイントになるのは、time変数の使い方とMOD関数の使い方です。
time変数は00:00:00からの経過秒数をミリ秒単位で返してくれます。
mod関数は、割り算の余りを返してくれます。

ここでは、3秒を一つの単位と考え、1秒目:青、2秒目:黄、3秒目:赤といった具合で表示することを考えます。
そのためには、現在の秒数を3で割った余りが0のとき、1のとき、2のときと場合わけが必要です。
場合分けにはIF関数を使います。

式のイメージとしては、
現在秒数を3で割った余りが1→青、それ以外のとき、1であれば黄、そうでない場合赤

といった形になります。

式に必要な値の出し方

まず、現在秒数を3で割った値の出し方です。
これは、MOD関数を使用すると、mod[time,3]と表現できます(openBVEでは大文字小文字の区別はないようですので、MODでもmodでもOKです)。 青の表示は、ズレ量で言うと0%、0です。
黄の表示は、ズレ量で言うと33%、0.33です。
赤の表示は、ズレ量で言うと66%、0.66です。
条件分岐のIF関数は、IF[条件,真の場合(条件を満たす場合)の値,偽の場合(条件を満たさない場合)の値]を返します。

実際の式

最終的に、実際の式は次のようになります。
IF[mod[time,3] < 1, 0.33, IF[ mod[time,3] < 2, 0.66, 0.99 ]]
  │     │  │    │      │  │  └成り立たない場合(1秒目未満でも2秒目未満でもないとき=3秒目未満のとき)
  │     │  │    │      │  └成り立つ場合、黄
  │     │  │    │      └右辺のほうが左辺より大きい(ここでは、現在秒数を3で割った値が2未満(1秒目~2秒目のとき)
  │     │  │    └成り立たない場合(1秒目~3秒目)、次の比較を行う
  │     │  └成り立つ場合、青を表示
  │     │
  │      └右辺のほうが左辺より大きい(ここでは、現在秒数を3で割った値が1未満(0秒目~1秒目のとき)
  └3で割った余りの時刻が
time変数で得られる値はミリ秒単位で得るため、 「秒数を3で割った余りが0のときに青にしよう」と、mod[time,3]==0としてしまうと、経過秒数が0.01秒のときでも0.1秒でもない0秒ちょうどのときしか条件が成立しません
したがって、ここでは、秒数を3で割った余りが1未満(0から0.999...の間)のときに青を表示するようにしています。

また、IF関数は真と偽しか値にもてないため、条件分岐は常に2つに絞られてしまいます。
そのため、3つ以上の選択肢が必要な、今回の信号機のような場合には、IF文を入れ子(ifのなかにif)する処理が必要となります。
非常に複雑ですが、頑張って覚えてください。

#個人的な感想ですが、openBVEのこのif文の構造は何とかして欲しいです。せめて複数行に分けることが出来ないと、条件分岐の本数が少し多くなっただけで悲惨なことになります。

完成図

信号オブジェクト
;trafficsig.animated ;本体オブジェクト
[object]
States=signal.x
TextureShiftYFunction = IF[mod[time,3]<1, 0.33, IF[mod[time,3]<2,0.66,0.99]]
これで、1秒ごとに信号が切り替わるオブジェクトを作ることができました。
ここでは1秒ごとに切り替えを行っていますが、これを30秒ごとなどにするとだいぶ信号らしくなりますね。
素材ファイルを改造して、黄色が点滅する信号機などを作るのも良いかもしれません。

応用例

[object]
States=747-landing.x
RotateYFunction= -135/57.29
Position=-450,47,-150
TranslateXDirection = 1,0,1
TranslateXFunction= (mod[time,20])*45
TranslateYFunction= if[mod[time,20] <= 9,(mod[time,20])*(-4),if[mod[time,20] <=14,((mod[time,20]-9)*(-2))-36,if[mod[time,20]<=15,((mod[time,20]-14)*(-1))-46,-47]]]
RotateXFunction = (if[mod[time,20] > 15, 7-(mod[time,20]-15),if[mod[time,20] > 11,((mod[time,20]-11)*1) + 3,3]]) / 57.29
着陸シーンを見る
(動画:WMV形式)
OpenBVEでのアニメーションを応用すると、実はこんなものまで作れてしまいます。
航空機モデルは再配布条件の都合上再配布できませんが、アニメーション用のデータを掲載しておきます。
現状のOpenBVEでちょっと複雑なアニメーションを行うと、すぐこのように非常に複雑な値を入力する必要があります。 もはや意味不明ですね。
個人的には、路線上の座標から座標、若しくはレールにそってオブジェクトを移動するような構文が欲しい限りです。
しかしながら、簡単なアニメーションには十分威力を発揮する代物ですので、以前のBVEから言えば比べ物にならない進歩ができましたね。
このサイトについて サポート サイトマップ