このダイアログ ボックスの設定により、認識機能コントローラを使用する場合に、ある状態から別の状態への遷移に対する影響の与え方を制御できます。詳細は、認識機能コントローラをセットアップして使用するにはを参照してください。
トランジションの最も重要な要素は、MAXScript の条件式スクリプトです。これは、フレームごとに 1 度実行されるコントローラと関係付けられたスクリプトで、シーンのあらゆる状況をテストでき、テストが成功(true または 1)するか失敗(false または 0)するかによって、トランジションが生じたり、生じなかったりします。
スクリプトは、割り当て済みの代理オブジェクトに対してフレームごとに 1 度実行されます。オブジェクトおよび影響はアニメート可能で、それに対し代理オブジェクトは正確に対応します。
トランジションで使用されるすべてのスクリプトでは、以下の構造が使用されます。
fn [FunctionName] del t = ( [MAXScript code] if [MAXScript conditional] then 1 else 0 )
開始の部分には「fn」(関数)があり、[トランジション](Transition)ダイアログ ボックスにも表示されます。「fn」の後に関数名が続き、それから入力パラメータ「del t」、最後に「= (」が続きます。この後に MAXScript コードが存在する場合もあります。
終了の部分には必要な MAXScript の条件式があり、その後「then 1 else 0」が続きます。このスクリプトの意味は、この条件式の結果が true の場合は 1 を返す(つまり、トランジションが生じる)、また条件式の結果が false の場合は 0 を返す(トランジションは生じない)ということです。1 と 0 の順序を反対にすることもできますが(then 0 else 1)、その場合は条件式が true の場合にトランジションが生じず、条件式が false の場合にトランジションが生じます。最後に、関数は括弧「)」で終わる必要があります。
認識機能コントローラで使用されるスクリプトの例を以下に示し、簡単に説明します。スクリプトは、シーンに合わせて修正して使用します。
このサンプル スクリプトでは、パーティクル システム Spray01 により放出されたパーティクルの数をテストし、その数が 100 の場合は正の数を返します。
fn TestParticles del t = ( if (particleCount $Spray01) == 100 then 1 else 0 )
このサンプル スクリプトでは、Sphere03 という名前のオブジェクトの位置をテストし、その位置が(X>=150、Y>=0、Z>=70)の場合は正の数を返します。
fn PositionCheck del t = ( if ($sphere03.pos.x >= 150 and $sphere03.pos.y >=0 and $sphere03.pos.z >=70) then 1 else 0 )
このサンプル スクリプトでは、霧(フォグ)の効果の[密度](Density)パラメータをテストし、パラメータが 50 の場合は正の数を返します。
fn TestAtmos del t = ( atmos_fog = getAtmospheric 1 print atmos_fog.density -- to:debug if (atmos_fog.density == 50) then 1 else 0 )
2 行目に注目してください。霧の環境効果が「atmos_fog」という名前の変数に割り当てられています。名前の割り当ては、環境効果の場合にのみ必要です。ほとんどの標準的なオブジェクトでは、その前の 2 つの例のように、単にドルマーク($)をオブジェクト名の前に付けて使用します。getAtmospheric コマンドに続く「1」は、[レンダリング効果](Rendering Effects)ダイアログ ボックス [効果](Effects)リストでの環境効果の位置を示します。
この割り当てを実行した後、次のコマンドを[MAXScript リスナー](MAXScript Listener)ウィンドウに入力すると、環境効果プロパティのリストを取得できます。
ShowProperties atmos_fog
また、サンプル スクリプトの 3 行目は、認識機能コントローラには必要ありません。デバッグの目的で[リスナー](Listener)ウィンドウにテストの結果を出力するだけです。
このサンプル スクリプトでは、MAXScript の[距離](Distance)機能を使用して代理オブジェクトとシーン オブジェクトの距離を取得し、結果が 30 未満の場合に正の数を返します。
fn TestDist del t = ( get_dist=distance $sphere01.pos $delegate02.simpos print (get_dist) if get_dist < 30 then 1 else 0 )
前の例のように、変数が使用されています。この例では、スクリプトを簡単にするためのものです。2 行目で、sphere と代理オブジェクトの距離を取得するために[距離](Distance)機能が使用され、結果は変数「get_dist」に割り当てられます。特定の代理オブジェクトではなく、認識機能コントローラを使用するすべての代理オブジェクトをテストする場合は、「$delegate02.simpos」の代わりに「del.simpos」を使用します。
スクリプトの 3 行目によって、計算された距離がデバッグの目的で[リスナー](Listener)ウィンドウに出力されます。このラインはシミュレーションには必要ないため、削除してもかまいません。最後に、値が定数 30 と比較され、それ未満の場合は、スクリプトにより 1 が返され、トランジションが生じます。
このスクリプトを利用して、複数の探査動作または状態を使用する認識機能コントローラを作成し、代理オブジェクトを任意の数のオブジェクトの間にあるパスに沿って移動させることができます。代理オブジェクトの位置が、特定のオブジェクトと指定された距離以内になった場合、ただちにトランジションが生じ、代理オブジェクトは次の探査状態を使用します。つまり、次のオブジェクトに向かって移動します。トランジションは各フレームでテストされるため、ダイナミックなアニメーションになるようターゲット オブジェクトを任意の方法で移動できます。
このサンプル スクリプトでは、シリンダーに適用するベンド モディファイヤの[角度](Angle)パラメータがテストされ、パラメータが 70 から -70 (両端を含む)の場合は true を返します。
fn TestBend del t = ( if ($cylinder01.bend.angle <= 70 and $cylinder01.bend.angle >= -70) then 1 else 0 )
2 行目の If 構文でテキストに括弧が使用されているのは、2 つの条件をテストするためです。つまり、角度が 70 以下かどうかという条件と、-70 以上かどうかという条件です。2 つのテストの間に「and」があるため、スクリプトは両者が true の場合にのみ true を返します。
トランジション スクリプトで、ある代理オブジェクトに対して現在影響している動作の判別が必要な場合があります。群集には、判別を行う MAXScript に基づく方法が備わっています。特定の代理オブジェクトがその動作でターゲットとして指定されているかどうか確認することもできます。たとえば、カクテル パーティのシーンで、ハリーがサリーを捜そうとすると、ベティはハリーから遠ざかるとします。しかし、ハリーがサリーから遠ざかっている場合には、ベティがハリーを捜すようになります。
次の例のスクリプトでは、前述の例の説明よりもさらに複雑なシナリオが使用されています。次に概要を示します。
4 つのグリッドで定義された「room」に、壁反発動作を使用して 6 体の代理オブジェクトが入っています。シミュレーション中、代理オブジェクト 1、2、3、および 5 は、単にランダムにさまよいます。ただし、代理オブジェクト 4 は、認識機能コントローラ(cc1)によりさまよいを開始し、さらに代理オブジェクトの 3 つの任意のペアのうちの 1 つが、お互い 50 単位以内に近づいた場合は 3 種類の回避動作のいずれか 1 つに切り換わります。各回避動作のターゲットは、3 つの異なる代理オブジェクトのグループで、そのうち 2 つに代理オブジェクト 2 が入っています。代理オブジェクト 6 には第 2 の認識機能コントローラ(cc2)が割り当てられており、代理オブジェクト 4 が代理オブジェクト 2 を避けている場合は、以下のスクリプトにより回避動作に切り換わります。スクリプトの核は、関数 transfunc4 にある次のラインです。
(isDelAvoid = isDelegateAvoiding the_current_behavior.name "$Delegate04" "$Delegate02"
ファイルをロードし、F11 を押すと[リスナー](Listener)ウィンドウが開き、計算されます。[リスナー](Listener)ウィンドウには、代理オブジェクト 4 が代理オブジェクト 2 を避けるとメッセージが表示されます。
上のラインの代理オブジェクトの名前を置換したり、transfunc4 のリストにある回避動作の名前を置換したり、必要な場合は行の追加や削除を行って、このスクリプトをシミュレーションに合わせて使用すると、ある代理オブジェクトが別の代理オブジェクトを避けているかどうか確認できます。
スクリプトの例に示されている第 2 の重要な点は、認識機能コントローラのトランジション スクリプトに、複数の関数を含むことができることです。群集では、まず[トランジション](Transition)ダイアログ ボックス [遷移の状態](Transition Condition)フィールドで指定された関数が実行され、その関数によりスクリプトにある追加の関数が 1 つ以上呼び出されます。この例の場合、transfunc4 によって最初の関数 isDelegateAvoiding が呼び出され、3 つのパラメータが渡されます。
最後に、スクリプトには getBehaviorType という特別な関数が含まれており、入力された動作と既存の動作のリストとを比較します。一致すると、既存の動作を返します。ここでは、transfunc4 が Delegate04 に現在影響を与えている動作のリストに対して実行され、各動作に getBehaviorType をテストします。回避動作が有効な場合は、Degelgate02 がその回避動作の障害になるかどうか確認します。この関数の使用は、特にシーンに同じタイプのさまざまな動作がある場合や、頻繁に動作の設定を編集する場合には、特定の動作に対するテストよりも効率的かつ柔軟です。以下の transfunc4 のラインの初めの部分からコメント(二重引用符)を削除すると、返される動作を表示できます。
-- format "Return Behavior: %\n" return_behavior fn isDelegateAvoiding theCurrentBehavior theCogDelegate theAvoidingDelegate = ( the_return = 0 counter = 1 for the_assignments in $Crowd01.assignments do ( if the_return == 1 then exit if the_assignments.delegate != undefined then ( if theCogDelegate == "$"+the_assignments.delegate.name then ( if the_assignments.cogcontrol != undefined then ( for the_cogcontrol_state in the_assignments.cogcontrol.states do ( if the_return == 1 then exit for the_cogcontrol_state_behavior in the_cogcontrol_state.behaviors do ( if the_return == 1 then exit if the_cogcontrol_state_behavior.name == theCurrentBehavior then ( for the_obstacle in the_cogcontrol_state_behavior.obstacles do ( if the_return == 1 then exit if "$"+the_obstacle.name == theAvoidingDelegate then ( --format "Set it true here !\n" the_return = 1 ) ) ) ) ) ) ) ) counter = counter + 1 ) the_return ) fn getBehaviorType val = ( if not iskindof val MAXRefTarg do return undefined theBehaviors = #( Speed_Vary_Behavior ,Orientation_Behavior ,Scripted_Behavior , Wander_Behavior ,Surface_Arrive_Behavior ,Path_Follow_Behavior , Seek_Behavior ,Avoid_Behavior ,Wall_Seek_Behavior , Space_Warp_Behavior,Wall_Repel_Behavior,Surface_Follow_Behavior , Repel_Behavior ) val_classID = val.classid for behav in theBehaviors do ( local behav_classid = behav.classid if val_classID[1] == behav_classid[1] and val_classID[2] == behav_classid[2] do ( return behav ) ) undefined ) fn transFunc4 del t = ( another_the_return = 0 counter = 1 for the_current_behavior in $Delegate04.behaviors do ( if another_the_return == 1 then exit return_behavior = getBehaviorType the_current_behavior --format "Return Behavior: %\n" return_behavior if return_behavior == Avoid_Behavior then ( isDelAvoid = isDelegateAvoiding the_current_behavior.name "$Delegate04" "$Delegate02" if isDelAvoid == 1 then ( format "$Delegate04 found to be Avoiding $Delegate02\n" format " Starting Transition in frame %:\n" t another_the_return = 1 ) ) counter = counter + 1 ) another_the_return )
複数のトランジション テストが true の場合、発生するトランジションは[優先順位](Priority)設定に基づいて決定されます。これは、最小の[優先順位](Priority)設定により実行されます。たとえば、[優先順位](Priority)設定が 0 のトランジションの優先順位は、設定 1 のトランジションよりも高くなります。
低い値にすればトランジションは急激になり、高い値にすれば緩やかに遷移します。
低い値にすればトランジションは急激になり、高い値にすれば緩やかに遷移します。
トランジションが発生する時と方法を指定する MAXScript 関数の名前です。
この名前もスクリプトのメイン関数の最初に現われ、「fn」の後に配置する必要があります。スクリプトには、メイン関数が呼び出す関数および互いに呼び出し合う関数が含まれます。
トランジションのMAXScript スクリプトを編集、保存、およびロードするエディタ ウィンドウが表示されます。