2006/1/10

方向幕が変更できない?  VRMスクリプト禅問答
【怎麼生】
コレを見て自分でもやってみようと方向幕の変更に挑戦したのですが、スクリプトを書いても方向幕が変わりません。これはVRMのバグですか?

【説破】 4.0.3.2
おそらく、あなたは編成エディタからリソースを組み込み、以下に例示するようなスクリプトを書かれたのであろうと推察します。
[編成スクリプト]
SelectTrainResource 1

[車輛スクリプト]
SetSignTexture {リソース番号}
実は、この書き方は、少なくとも現行のVRMではマズいのです。


まず、正しい・・・厳密に言うと「意図どおりに動作する」サンプルスクリプトをご覧頂きましょう。
[編成スクリプト]
SelectTrainResource 1
CallCar MtdInitialize

[車輛スクリプト]
BeginFunc MtdInitialize
SetSignTexture {リソース番号}
EndFunc
前掲のマズいスクリプトとの違いは、車輛スクリプト側のSetSignTexture命令、すなわち車輛に方向幕を決定するリソース番号を割り当てる命令がBeginFunc〜EndFuncで囲まれてメソッド化されている点、そして編成スクリプトからCallCar命令でこれが実行されている点です。この結果、両者の動作に微妙な差が生じます。
編成エディタから組み込んだ車輛リソースを利用するには、SelectTrainResource命令でリソースの参照先をレイアウト(パラメータ0)から編成(同1)に設定する必要がありますが、これはSetSignTexture命令によるリソースの割り当てに先行している必要があります。そして、マズい書き方をした場合、必ずしも編成スクリプトが車輛スクリプトに先行して実行されるとは限らないのです。後で示したサンプルのような書き方であれば、SelectTrainResource命令の次にCallCar命令が実行され、その結果として車輛スクリプト内のSetSignTexture命令が実行される、という順序を保証することが可能になります。

これを一般論化すると、VRMスクリプトにおいて、メソッドの外側に記述される命令、つまりビュワー起動時に自動的に実行される一連の命令については、

・同じオブジェクトの中であれば書いた順番に実行される。
・異なるオブジェクトの間ではどちらが先に実行されるかは時の運である。

ということになります。車輛は編成に含まれる要素ではあるのですが、VRMビュワーの実装としては、独立したオブジェクトとして扱われている(ように見える)ため、必ずしも編成スクリプトが車輛スクリプトに先行して実行されるとは言えないワケです。
なお、レイアウトスクリプト(レイアウターメニューの「スクリプト編集」から書き込むもの)については、すべてのオブジェクトに先行してメソッド外の命令が実行されることが保証されています。レイアウト全体から参照すべきグローバル変数をここに書くための措置と思われます。

この事例から次のような教訓を得ることができます。すなわち、実行順序が動作に影響する一連の処理を複数のオブジェクトに分散して記述する場合、メソッドの外側に単純に並べてしまうと、あるときは意図通りに動作し、あるときは意図通りに動作しない、ということが起こる、ということです。
たとえば、ポイントPOINT1・POINT2があったとします。POINT1はビュワー起動時にSetPointBranch 1で反位になり、POINT2はメソッドの外側に「POINT1からポイントの状態を取得して自分もそれに倣う」とします。このとき、POINT1/2のどちらの処理が先行するかはわからないので、結果的にPOINT2は正/反位のどちらでもありえる(ビュワーを起動する毎に結果が異なる)ことになります。

これを回避するには、

(1) 関連する複数のオブジェクトのうち、一番最初におこなうべき処理を有するオブジェクトに「順序制御」の役割をあたえる。
(2) (1)以外のオブジェクトのビュワー起動時処理は、メソッドの外側に出さず、外部からcall可能なメソッドとして用意する。
(3) (1)のスクリプトは、メソッドの外側でまず自分自身の初期化をおこない、続いて(2)のメソッドを適切な順序でcallする。

のような対策が必要になります。

この現象については早い時期から気付いていたのですが、今回moko氏の献身的なご協力をいただき、公開に到りました。moko氏に多謝。
0

2006/1/10  11:32

投稿者:moko
>>厳密には「脆弱性」ではないので

すみません。意味を履き違えてたようですm(_ _)m

コメントを書く

この記事にはコメントを投稿できません




teacup.ブログ “AutoPage”
AutoPage最新お知らせ