ETC


1、AttackDist

2、F式(鴨音中段)

3、開幕前の行動

4、デバッグモード


はじめに

キャラ製作部分で関わってくるAIの問題について
書こうと思っています。
そのため、今回はAI製作をしている人に向けてではなく、
キャラを作成している人を対象として書かせていただきました。


1、AttackDist

[小話]

AI同士の戦いでよく中遠距離からの本体の攻撃(飛び道具ではなく)
をガード出来ない現象を見たことが無いでしょうか?
近距離ではガードが固いのに、距離が離れるとガードが出来ない場合は
ほとんどこれから書くことが原因だったりします。

これは、「Attack.Dist」が影響しているのですが、
AIを作る側ではどうしようもない問題で(
ガードのトリガーに「InGuardDist」を使わないわけにはいかないので)
キャラを作る側で設定しないといけない問題なのです。

[方法]

キャラの[Size]項目に「Attack.Dist」という項目があります。
これは、こちらが攻撃したときに相手がガード行動を取れる距離を表します。
(「Attack.Dist」=「InGuardDist」となります)
そのため、「Attack.Dist」の値を超える距離から本体による攻撃を当てると、ガードできないという現象が起こります。
しかし、この値はプレイヤー操作時だと関係無いらしく、攻撃が当たる直前にレバーが後ろに入っていれば、
ガード行動が何故か取れるようになっています。
そのため、気づきにくく設定をしない場合が多いのですが、
実は
「InGuardDist」範囲内でしかガード出来ないAI(CPUも含む)にとっては
完全なガード不能攻撃になってしまうのです。

[例]

[State -1]
Type = AttackDist
Trigger1 = 1
Value = 200
           ;ガード可能距離
Persistent = 1

製作が面倒になるのですが、範囲が広い攻撃を持つキャラは、
その技毎に「AttackDist」を設定してあげるしか方法は無いようです。
キャラの[Size]項目の「Attack.Dist」はデフォルトでは160になっていますので、
それを超える攻撃のみに設定していけば、ガード不能攻撃は無くなります。

また、これを応用して
「AttackDist」の値を0にすることで、
逆に相手にガード行動を取らせないようにすることも出来ます。

ガード不能の投げなんかはこうしておくと、相手のAIはガードが
出来なくなるので、それ以外の選択肢を強制的にするようになり、
結果的に相手の無駄な行動が減ります。


2、F式(鴨音中段)

[小話]

動きの自由度が高いコンボゲーが流行してから、発覚した格闘ゲームのバグ、F式(鴨音中段)。
どういうバグかというと、
立ちガードで攻撃をガードした後の硬直中は、
しゃがみガードに切り替えても判定が立ちガードのまま
になるというものです。
もちろん、判定のみが立ちガードなのであって、しゃがみガードのモーションをキャラは取っています。
これを利用した実戦向けな崩しやコンボが最近のコンボゲーだと色々あるので、
コンボゲーのキャラのAIを作られている方は、F式が出来なくて泣く泣く諦めた人も居るのではないでしょうか?

[方法]

まずは、Airファイルに「Anim153」を新たに作成します。
「Anim153」の
表示するスプライトは「Anim151」と同じもの、判定は「Anim150」と同じ判定で作ります。
そして、commonファイルの「StateNo152」と「StateNo153」に記述を加えます。

[例]

「StateNo152」の「ChangeAnim」を下の記述に変更、

[State -1]
Type = ChangeAnim
Trigger1 = Anim != 150
Trigger1 = Anim != 151
Value = 151
IgnoreHitPause = 1

[State -1]
Type = ChangeAnim
Trigger1 = Anim = 150
Trigger1 = Anim != 153
Value = 153
IgnoreHitPause = 1

「StateNo153」の「StateDef 153」の記述から、「Anim=151」の記述を削除します。
そして、
下の「ChangeAnim」の記述を追加します。

[State -1]
Type = ChangeAnim
Trigger1 = Time = 0
Trigger1 = PrevStateNo = 152
Trigger1 = Anim = 151
Trigger2 = Anim = 153
Trigger2 = Time = GetHitVar(SlideTime) || HitOver
Value = 151
IgnoreHitPause = 1

[State -1]
Type = ChangeAnim
TriggerAll = Time = 0
Trigger1 = Anim = 150 || Anim = 153
Value = 153
IgnoreHitPause = 1

F式はこれで完成です。
F式を使った連携というのは、コンボゲーが流行っている今日では、これからも増えていくと思われるので、
以外と馬鹿に出来ない要素になってきています。
作成自体はとても簡単なので、是非導入してみて下さい!


3、開幕前の行動

[小話]

一部の格闘ゲームでは、開幕前に自分の有利な場所取りが可能なゲームが存在します。
遠距離や近距離キャラだとこの要素は、特に重要だったりするのですが、
mugenの仕様でこれらの行動はかなり制限されてしまっています。
ただ、地上での移動位ならmugenでもバグ無しで作る事も実は可能だったりします。

[方法]

まずは、-2Stateに下の記述を追加します。

[例]

[State -2]
Type = VarSet
TriggerAll = RoundState = 0
      ;ラウンドのはじめ(暗転中)
TriggerAll = StateNo != 5900
      ;ラウンドのはじめの最初のステート以外
Trigger1 = Var(1) = 0
V = 1
Value = 1

[State -2]
Type = VarSet
Trigger1 = Var(1) = 1
Trigger1 = RoundState = 2
       ;お互いのイントロ終了
V = 1
Value = 2

[State -2]
Type = VarSet
TriggerAll = Var(1) = 2
TriggerAll = RoundState = 2
Trigger1 = Ctrl
              ;ラウンドコール後(開幕)
Trigger2 = MoveType != I
V = 1
Value = 0

上の記述は、開幕前の状態をVarで確認させています。
理由は、
「RoundState = 2」になった瞬間にPosがmugen本体の処理でリセットされてしまう事
mugenに最初から用意されているTriggerでは、「RoundState = 2」の状態で
且つ、ラウンドコール前の状態というのを認識する事が不可能
だからです。

前者は、「RoundState = 2」になると、ステージで設定されているPosに強制移動されてしまうため、
その前から移動すると変に見える(ワープする)という点と「RoundState = 1」はイントロスキップをすると、
直接「RoundState = 0」から「RoundState = 2」に飛ぶ為にTriggerとして使いづらいというのがあります。

後者は、「RoundState = 2」で且つ、Ctrl=1になる前の状態を確実にTriggerで認識する方法が無い為、
Varに状態を記憶させています。
ちなみに、この場合
「Var(1) = [1,2]」の状態が、開幕前の行動が可能な状態となります。

それと、開幕前の行動は格闘ゲームでも特殊なものなので、
作る場合は開幕前の行動をユーザー側で使用可能にしたり、不可にしたり出来るように
コンフィグを作る事を推奨します。

次に、ラウンドコール後にmugen本体で強制的に「StateNo = 0」にされる事
考えた記述を「StateDef 0」に追加します。
今回は一例として、開幕前に歩き行動(この例では、「StateNo = 10020」)が出来るようにしてみます。
歩行に関しては、mugenのデフォルトに既に用意されていますが、これを使ってしまうと、
本来、「Ctrl = 0」になっている状態の時に「Ctrl = 1」になってしまうので、専用のStateも用意する必要があります。

[例]

[State -1]
Type = VarSet
TriggerAll = Ctrl
TriggerAll = Var(1) != 0
Trigger1 = Time = 0
V = 1
Value = 0
                ;Varリセット

[State -1]
Type = ChangeState
TriggerAll = Ctrl
TriggerAll = Var(1) = 0
        ;開幕後
TriggerAll = RoundState = 2
Trigger1 = PrevStateNo = 10020
 ;強制的にリセットされる前の行動が開幕前の専用歩き行動だった場合
Value = 20
               ;開幕後歩き行動へ

[State -1]
Type = Turn
              ;!=Ctrlなので、自動で振り向かないため、別途振り向きの命令が必要になる
TriggerAll =! Ctrl
TriggerAll = Var(1) = [1,2]
     ;開幕前
TriggerAll = RoundState = 2
TriggerAll = P2Dist X < 0
Trigger1 = Anim = 5

[State -1]
Type = PlayerPush
          ;相手とぶつからないように
Trigger1 = Var(1) = [1,2]
Value = 0

[State -1]
Type = ChangeState
TriggerAll =! Ctrl
TriggerAll = Var(1) = [1,2]
TriggerAll = RoundState = 2
Trigger1 = Command = "holdfwd" || Command = "holdback"
Value = 10020
            ;開幕前の専用歩き行動へ

「StateDef 0」に上の記述を追加します。
上から順に説明していくと、一番上は開幕前の状態を記憶しているVarのリセットです。
次は、歩行中に「StateNo = 0」に強制リセットされると、動きが不自然になるので、
そのまま開幕後のデフォルトに用意されている歩行ステートに飛ばしています。
「Turn」は、「Ctrl = 0」だと自動で振り向かないため用意しています。
「PlayerPush」は押し合いを拒否したい時、必ずしも必要な記述ではないです。
一番下は、専用の歩き行動へ飛ばしています。

専用の歩き行動ですが、実は難しいことは無く、デフォルトの「StateNo = 20」をコピペして、
「Turn」と「PlayerPush」、「StateNo = 0」に戻る「ChangeState」を用意するだけで完成です。

また、開幕前の時間は、「Fight.Def」の「Ctrl.Time」に依存します。
開幕前の行動が可能なキャラ同士の場合は、この時間を多めに取る事で、
お互い充分な間合い取りが可能になります。

若干面倒な記述な事と開幕前の行動があるキャラと無いキャラでアンフェアになるため、
避けられている傾向にあったシステムだと思いますが、
コンフィグで開幕前の行動の使用可否を決められれば問題無いですし、
この紹介で仕組みさえ分かってしまえば、割とすんなり組めるようになると思いますので、
試してみるのも面白いと思います。


4、デバッグモード

[小話]

キャラ作成にかかせないデバッグモードについてです。
デバッグモードについては、mugen付属のdocsに全て書かれていますが、
英文になっているため、日本語訳しています。
ついでに、自分が使っている用途や「DisplayToClipboard」の説明を加えています。

[方法]

まず、mugen.cfgを開いて、[Debug]の項目の
DebugとAllowDebugModeの値を1にしてください。

判定の見方

mugenを起動して対戦中にキーボードでCtrl+C(Ctrlキーを押しながらCを押す)と入力してみてください。
そうすると、キャラの周りに四角い枠が出ると思います。
キャラの周りに出ている青い枠が喰らい判定、赤が攻撃判定、緑が無敵判定を表します。
もう一度コマンドを入力すると、枠の中の部分も色がついてより判定がみやすくなります。
さらに、もう一度コマンドを入力すると枠が消えます。
また、キャラの下に出ている白い線は押し出し判定(Width)で、線の近くに出ている英文はキャラのDisplayNameです。

キャラの状態、データの見方

対戦中に表示されている左下の英文がキャラの状態やデータを表しています。
英文の2段目に灰色で表示されている部分がどのデータを表示しているかを表します。
次にキーボードでCtrl+Dと入力してみてください。
このコマンドを入力することで、データの表示が他のものに切り替わります。
順番的には、コマンドを入力する毎に1P→2P→1PHelper→2PHelper→データ非表示と切り替わっていきますが、
2段目の文を読めば、どのデータか書いてあるので問題ないと思います。

次にデバッグデータの見方です。

・FRAMES=TriggerのGameTimeの事、対戦中の経過時間
・FPS=ゲームの速度、60FPSが普通で処理が重いとFPS値が減る、mugen側で意図的にFPSを変える事も可能
・2段目の灰色表示=上にも書きましたが、キャラの名前(
DisplayName)、名前の後の()の部分の中の数字はTriggerのIDです
・ACITONID=TriggerのAnimの事
・SPR=現在表示されている画像でSFFに登録されている画像の番号の数値
・ELEMNO=b/aと表示されていて、aはそのAnimの最大AnimElemNo、bは現在のAnimElemNoを表す
・3段目のTIME=b/aと表示されていて、aはそのAnimの最大時間、bはそのAnimの現在のTime、GameTimeではないので注意!
Airに-1が使われている場合は最大値が-1になる事と最大値の後もAnimが続く場合はbの値は最初の1に戻る
(または、Loopstartの記述部分の値に戻る)事にも注意!
・STATE NO=TriggerのStateNoの事
・CTRL=コントロール可能かどうか、0は不可、1は可能
・TYPE=TriggerのStateTypeの事、1はS(立ち)、2はC(しゃがみ)、3はA(空中)、4はL(ダウン、Tripやられも含む)
・MOVETYPE=TriggerのMoveTypeの事、0はI(非攻撃、非やられ状態)、1はA(攻撃状態)、2はH(やられ状態)
・4段目のTIME=StateTimeの事、こちらは最初のTimeの値を0から数えている事に注意!、またAIRに-1やLoopstartの記述があっても、
そのステートにいる間はずっとTimeが増え続けます
※1段目に書かれているVRETとSPEED、SKIP特に気にする必要も無いので書きません
※また、デバッグの文字が黄色くなる事がありますが、これは相手にStateをとられている(投げ等)状態を表します

デバッグモードの見方が分かったら、次はmugenのホットキーを覚えると製作がさらに楽になります。

ホットキーの効果

・F1=2P側のライフを0に
・CTRL+F1=1P側のライフを0に
・F2=両側のライフを1に
・CTRL+F2=1P側のライフを1に
・SHIFT+F2=2P側のライフを1に
・F3=両側のパワーをMAXに
・F4=ラウンドリセット
・SHIFT+F4=データのリロード(mugen起動中にcnsを更新して、そのまま更新データを読み込ませる事も可能で重要なホットキーの一つ)
・F5=タイムオーバー
・F12=スクリーンショット
・CTRL+C=判定枠の表示の切り替え
・CTRL+D=デバッグデータ表示の切り替え
・CTRL+I=両側のプレイヤーを強制ニュートラルステート(StateNo=0)に(はまり状態の回避に使える)
・CTRL+L=アドオンのライフ、パワーバー等を消去(キャラ固有のパワーバーは消せません)、用途はキャラ作成時に見やすくすることとスクショ用w
・CTRL+S=ゲームスピードアップ(デバッグのFPSとSPEEDで確認可能)、マシンパワーが無いとあまり意味が無かったり…
・CTRL+V=V-sync機能の停止、ぶっちゃけ使いませんw
・CTRL+数字=数字には1〜4の数値が入ります、指定した数値のキャラをAIモードに(1なら1P、2なら2P)
・CTRL+ALT+数字=AIモードOFFに(mugenデフォルトのCPUではないAIはOFFにすることは不可能)
・SPACE=両側のライフとパワーをMAXに、時間もリセット
・PAUSE=ポーズ画面の表示、トレーニングモードならサンドバッグの状態の指定とかも出来ます
・SCROLLLOCK=PAUSE中にSCROLLLOCKを押すたびに1Fだけ時間を進める、製作中キャラの動きの確認等で使う一番大事なホットキー
PAUSEを押す前に特定のコマンドを押しておけば(例えば、"F"を押しておいて前進させる)、1F毎に動きを確認できる
PAUSE前にコマンド入力しておかないと受け付けない点に注意!、また、この方法を使うとTriggerの「Command」は
成立に1Fかかるという事も確認できます(AIが0Fで動いてくるのも確認可能)
・ESC=mugenの終了や画面を戻すのに使用

「DisplayToClipboard」はデバッグモードの左下に書かれている英文の4段目より下に追加でデータ項目を表示できます。
例えば、相手と自分の距離や相手の状態、特定のVarの値の変動の確認等です。

DisplayToClipboardの書き方

[例]

[State -2]
Type = DisplayToClipboard
Trigger1 = 1
Text = "ATK:%f \n"
Params = fvar(0)
IgnoreHitPause = 1
SuperMoveTime = 9999
PauseMoveTime = 9999

[State -2]
Type = AppendToClipboard
Trigger1 = 1
Text = "Pos X:%f, Pos Y:%f"
Params = P2BodyDist X, P2BodyDist Y
IgnoreHitPause = 1
SuperMoveTime = 9999
PauseMoveTime = 9999

例は自分のMBキャラの記述の一部コピペです。
「DisplayToClipboard」は主に-2か-3辺りの常時監視ステートに書くのが基本です。
参照するデータが常に読み込まれていないと意味が無いですからね。
それから、
AI講座にも書きましたがcnsは記述を上から読んでいくので、書く場所も
考えないと、データの表示が1F遅れたりします。

また、
デバッグモードはHelperのデータも参照可能なので、特定のHelperの確認にも
「DisplayToClipboard」を使うことが出来ます。
「AppendToClipboard」は意味の通りで、二つ目の「DisplayToClipboard」だと思えば問題ないです。
また、このステートコントローラーも「IgnoreHitPause」や「PauseMoveTime」を使うことが出来ます。

まず、「TEXT」の部分について、
「:」の前のATKやPos Xはデバッグを見やすくするための項目作りだと思ってください。
実際、fvar(0)にはMBキャラの攻撃補正値が入っていたりします。
なので、「:」の前の文字に意味は無く適当な英文を書いても問題ありませんw

項目を書かなくても問題ない場合は、「%d」だけを書いて省略することも可能です。
「%f」は小数点を含む値の表示を、「%d」は小数点の値を含まない値を表示します。
使い分けは、表示させたいデータの値によります。
それから、「%f」「%d」の後に次のデータを書きたい場合は、「,」で区切ります。
「\n」は改行の事です、横に長くなりすぎると見づらくなるので適当なところで改行しましょう。
最後に、TEXTは記述を「"」でくくるようになっていますので、書き忘れないように注意!

次に「PARAMS」について
これは表示させたいデータについて書きます。
Varの値の参照だけでなく、Triggerの命令もほぼ全て使用可能なので結構幅広く使えます。
他にも、「Var(1)+Var(2)」みたいな計算式も使えたりします。
それから、これも次のデータを書きたい場合は、「,」で区切ります。