Behaviorシリーズの続きです。
前回見た拍手のbehavior graphを、今回はxmlで見ることにします。
SSはほとんど前回と一緒です('_')・・・テヌキジャナイヨ
僕もまだ知らないことだらけですぬ。
前回はこちら
skmod.hatenablog.com
- behaviorファイルとxmlの関係
- xml変換したbehaviorファイルの見方
- IdleApplaudへの状態遷移
- State Machine
- StateMachineInfo
- ClipGenerator
behaviorファイルとxmlの関係
behaviorファイルは、実の所ただのxmlファイルです。勿論.hkxのままでは開けないですが、コンバータがあります。
32bit用。NEMESISでも使われてます。
www.nexusmods.com
Skyrim Behavior ToolやHKX Extractorが32bit版しか対応してない為、behaviorファイルは32bit版で扱うのが基本スタイルだと思います。
64bit版はどうするのか?というと。特定の条件を合わせて作った32bit版NEMESISパッチは、64bit版でも使用可能です。なので32bit版で改変すれば問題無いです(簡単な改変で正常動作したのは確認済)。
詳細はNEMESISの記事をおいおい作る予定なので、その時にでも。
github.com
NEMESISは32bit/64bit共にこれを基準にパッチを取り込み、ローカル環境毎のbehaviorファイルを生成します。つまり同様にこれ基準で差分抽出したパッチは、32bit/64bit共通になる訳です。
タイムスタンプに差分があるかもですが、HKX Extractor同梱のbehaviorファイル(.hkx)と同じだと思います。
xml変換したbehaviorファイルの見方
まずはNotePad++で、いくつかxmlファイルを見ていきます。細かいパラメータはSkyrim Behavior Toolと比較すると判ると思うので、おおまかな見方だけ書いておきます。
nodeを構成する要素
0_master.hkxからの抜粋。
1行目の<hkobject>
と27行目の</hkobject>
間の要素が、1つのnodeです。
同じく1行目の#0258は、このnodeのuniqueな名前を表します。Skyrim Behavior Tool(以下SBT)でnode名が重複しても問題無いのは、このおかげです。したがって、こっちは重複禁止です。そのまま右を見ると、nodeの種類名とsignatureがあります。このsignatureはnodeのclass毎に同一っぽく見えます(別のbehaviorファイル間でも共通)。
4行目がnode名前です。SBTで表示されるのはこれ。この後は、しばらくnode設定の要素が続きます。
22行目は、接続された子nodeの数です。この場合は#0257のBlenderGeneratorと、#0255のStateMachineの2つ。それぞれを見ると、また同じような内容になってます。こうしてxmlファイルからnodeを追うことができます。
node内でのanimation event指定方法
mt_behavior.hkxからの抜粋。931個のanimation eventが登録されてます。animation variableやcharacter propertyも同様に存在します。ここでちょっとしたルールがありまして。これらを使う各node内では、ここで登録した名称では記述されません。
931個の「登録リスト」の先頭を0番、最後を930番として、この番号で記述します(indexされる感じですが、xmlで"index"というと別の意味があるかもなので避けておきます。xmlしろーと( ; ゚Д゚))。
つまり上のSSの例だと、”eventId”の”5"は、animation event "IdleFurnitureExit"ということです。
skeleton.hkxでのboneの並び順に合わせて、各boneのweigtが羅列されてます。
IdleApplaudへの状態遷移
ではそろそろ、前回の拍手アニメーションの遷移を追いかけます。IdleApplaudのbehavior graphです。
前回のSSと、対応するxmlソースを比較します。各項目の説明は、前回と同じなので省略。
State Machine
親nodeであるStateMachine"NonOffsetIdlesBehavior”。詳細忘れてたら前回の記事参照で。
今回は本体である"StateMachine"と、設定項目である”StateMachineTransitionInfoArray”に項目分けます。
StateMachine
まずStateMachine本体です。子nodeと遷移条件が見えます。
nodeの固有名は”#2194"。表示名は"NonOffsetIdlesBehavior"。83個の子nodeが接続されてますが、SBTで表示される子nodeのID番号はここでは見当たりません。子nodeから読んで表示してそう。
<hkobject name="#2194" class="hkbStateMachine" signature="0x816c1dcb"> <hkparam name="variableBindingSet">null</hkparam> <hkparam name="userData">0</hkparam> <hkparam name="name">NonOffsetIdlesBehavior</hkparam> <hkparam name="eventToSendWhenStateOrTransitionChanges"> <hkobject> <hkparam name="id">-1</hkparam> <hkparam name="payload">null</hkparam> </hkobject> </hkparam> <hkparam name="startStateChooser">null</hkparam> <hkparam name="startStateId">97</hkparam> <hkparam name="returnToPreviousStateEventId">-1</hkparam> <hkparam name="randomTransitionEventId">-1</hkparam> <hkparam name="transitionToNextHigherStateEventId">-1</hkparam> <hkparam name="transitionToNextLowerStateEventId">-1</hkparam> <hkparam name="syncVariableIndex">-1</hkparam> <hkparam name="wrapAroundStateId">false</hkparam> <hkparam name="maxSimultaneousTransitions">32</hkparam> <hkparam name="startStateMode">START_STATE_MODE_DEFAULT</hkparam> <hkparam name="selfTransitionMode">SELF_TRANSITION_MODE_NO_TRANSITION</hkparam> <hkparam name="states" numelements="83"> #2193 #2190 #2175 #2169 #2151 #2116 #2113 #2110 #2104 #2093 #2091 #2089 #2087 #2084 #2081 #2077 #2063 #2060 #2057 #2054 #2051 #2046 #2041 #2036 #2033 #2030 #2027 #2024 #2019 #2017 #2005 #1995 #1988 #1979 #1973 #1967 #1960 #1951 #1948 #1945 #1942 #1936 #1930 #1926 #1923 #1920 #1917 #1912 #1905 #1902 #1899 #1896 #1893 #1888 #1884 #1879 #1856 #1851 #1848 #1846 #1843 #1840 #1837 #1833 #1828 #1823 #1818 #1813 #1810 #1807 #1804 #1801 #1798 #1795 #1792 #1789 #1785 #1781 #1778 #1775 #1772 #1769 #1766 </hkparam> <hkparam name="wildcardTransitions">#1763</hkparam> </hkobject>
前回同様に追いかける"NPC_Applaud2.hkx"は、勿論この83個の中に入ってます。node名で検索すると"#2036"であることが分かります(ちゃんとありますね!)。
遷移条件の記述は別のnodeに分離されていて、末尾の方にある"#1763"のnodeに纏まってます。
それと前回触れませんでしたが、"startStateId"というのがありまして。遷移条件が何も設定されてないので、もしこのStateMachineに来たものの何もanimation eventが無かった際は、そこに飛ぶのかも。スタック予防策?
StateMachineTransitionInfoArray
遷移条件設定。SBTからだとStateMachineの設定項目ぽく見えますが、xmlで見る限りこれはこれで別nodeのようです。
"NPC_Applaud2.hkx"への遷移条件となるanimation event "IdleApplaud2"は、SBTのリスト519番目。これは最初にxmlで見たanimation eventの羅列と同じ順序なのですが、こちらは1番からナンバリングされてるので注意。xmlでは518になります。
"flagGlobalWildCard"と"flagLocalWildCard"は、チェック状態だとどこからでもこの遷移にワープしてこれる、的な物みたいです。idleアニメーションにはおそらく必須だと思います。ポーズMODのNEMESIS専用化実験してた時にうまくいかず、このチェック入れたら動いたでござる。FNISのidleアニメーションでもチェック入ってたので、もっと早く見ておくべきだった( ; ゚Д゚)。
StateMachineに書かれてた"#1763"です。83個分の遷移条件を纏めたnodeのようで、長いので抜粋。
"eventId"が518、"toStateId"が63。animation event "IdleApplaud2"がトリガされたらnode "NPC_Applaud2.hkx"に遷移しろ、ってことですね。SBTで見た通り。
<hkobject name="#1763" class="hkbStateMachineTransitionInfoArray" signature="0xe397b11e"> <hkparam name="transitions" numelements="28"> <hkobject> <hkparam name="triggerInterval"> <hkobject> <hkparam name="enterEventId">-1</hkparam> <hkparam name="exitEventId">-1</hkparam> <hkparam name="enterTime">0.000000</hkparam> <hkparam name="exitTime">0.000000</hkparam> </hkobject> </hkparam> <hkparam name="initiateInterval"> <hkobject> <hkparam name="enterEventId">-1</hkparam> <hkparam name="exitEventId">-1</hkparam> <hkparam name="enterTime">0.000000</hkparam> <hkparam name="exitTime">0.000000</hkparam> </hkobject> </hkparam> <hkparam name="transition">#0093</hkparam> <hkparam name="condition">null</hkparam> <hkparam name="eventId">518</hkparam> <hkparam name="toStateId">63</hkparam> <hkparam name="fromNestedStateId">0</hkparam> <hkparam name="toNestedStateId">0</hkparam> <hkparam name="priority">0</hkparam> <hkparam name="flags">FLAG_IS_LOCAL_WILDCARD|FLAG_IS_GLOBAL_WILDCARD|FLAG_DISABLE_CONDITION</hkparam> </hkobject>
下の方に"#0093"なるnodeが見えます。これも前回触れませんでしたが、BlendingTransitionEffectという物で、多分遷移に伴うアニメーションの変化前と変化後を、違和感無くブレンドする設定だと思います(多分・・・何かしらこういう設定が無いと、アニメーションが切り替わる度にコマ送りぽくなる気がするし)。SBTだとうまく触れないらしい?
StateMachineInfo
遷移先のstateです。ID63、"NPC_Applaud2.hkx"。
固有名は"#2036"。子nodeに”#2035"が接続されてます。この後はもうclip再生に入るだけだからか、情報量少な目ですかね。
<hkobject name="#2036" class="hkbStateMachineStateInfo" signature="0xed7f9d0"> <hkparam name="variableBindingSet">null</hkparam> <hkparam name="listeners" numelements="0"></hkparam> <hkparam name="enterNotifyEvents">null</hkparam> <hkparam name="exitNotifyEvents">null</hkparam> <hkparam name="transitions">null</hkparam> <hkparam name="generator">#2035</hkparam> <hkparam name="name">NPC_Applaud2.hkx</hkparam> <hkparam name="stateId">63</hkparam> <hkparam name="probability">1.000000</hkparam> <hkparam name="enable">true</hkparam> </hkobject>
ClipGenerator
こちらも本体と設定で実は別nodeなので、今回は項目分けます。
ClipGenerator
いよいよゴールの"NPC_Applaud2.hkx"です。直前のstate(StateMachineInfo)と同名ですが、#で始まる方が異なってれば問題無し。
こちらの固有名は"#2035"。ちゃんとuniqueになってますね。
"animationName"でアニメーションファイルの記述が見えます。
<hkobject name="#2035" class="hkbClipGenerator" signature="0x333b85b9"> <hkparam name="variableBindingSet">null</hkparam> <hkparam name="userData">0</hkparam> <hkparam name="name">NPC_Applaud2.hkx</hkparam> <hkparam name="animationName">Animations\NPC_Applaud2.hkx</hkparam> <hkparam name="triggers">#2034</hkparam> <hkparam name="cropStartAmountLocalTime">0.000000</hkparam> <hkparam name="cropEndAmountLocalTime">0.000000</hkparam> <hkparam name="startTime">0.000000</hkparam> <hkparam name="playbackSpeed">1.000000</hkparam> <hkparam name="enforcedDuration">0.000000</hkparam> <hkparam name="userControlledTimeFraction">0.000000</hkparam> <hkparam name="animationBindingIndex">-1</hkparam> <hkparam name="mode">MODE_LOOPING</hkparam> <hkparam name="flags">0</hkparam> </hkobject>
このclip再生からトリガするanimation eventの設定は、"#2034"にありそうです。
ClipTriggerArray
animation eventのトリガ設定。
#2034です。SBTで見た通りな感じ。animation event "IdleStop"はリスト30個目(つまり29)なので合ってます。
<hkobject name="#2034" class="hkbClipTriggerArray" signature="0x59c23a0f"> <hkparam name="triggers" numelements="1"> <hkobject> <hkparam name="localTime">-0.500000</hkparam> <hkparam name="event"> <hkobject> <hkparam name="id">29</hkparam> <hkparam name="payload">null</hkparam> </hkobject> </hkparam> <hkparam name="relativeToEndOfClip">true</hkparam> <hkparam name="acyclic">false</hkparam> <hkparam name="isAnnotation">false</hkparam> </hkobject> </hkparam> </hkobject>
かくして完走、拍手の再生です!
長くなりましたが、とりあえずこれでbehaviorを読み解く編はいったん終了とします。
おつかれさまでした!