ガード関連の仕様について

「ガード関連の仕様について」の編集履歴(バックアップ)一覧に戻る
ガード関連の仕様について」を以下のとおり復元します。
MUGENのガード関連の仕様について。

----
#contents
----

*&bold(){ガード方向}
MUGENでは相手キャラの位置に関係無く、『キャラクターが(内部的に)向いている方向の逆』で固定されている。
つまり見た目とガード方向が常に一致するため、一般的な格ゲーでいう[[めくり]]と完全に同じ状況というのはありえない。

が、いくら見た目通りだとは言っても人間の反射神経では限界があるわけで、
ガード方向が切り替わる瞬間を狙った飛び越えつつの攻撃というのは
やはりMUGENにおいてもプレイヤーにとってある程度の脅威ではあり続けている。
微妙な位置だなと感じた時は相手キャラの軸位置よりも自キャラが振り向くかどうかに注意を置くと吉。

----
*&bold(){Guard.Distについて}
HitDefおよびProjectile内の設定であるGuard.Dist。
HitDefはキャラクター本体や飛び道具、Projectileであれば飛び道具の位置を基準とした相手がガードモーションをとりうる最大距離を示す。

キャラクターが攻撃を出していても、そのHitDefのGuard.Dist値以上に距離が離れていると敵は
ガードモーションをとらない(とれない)。
これはあくまでガードモーションに移行しないだけで、キー入力によるガードは問題なくできる。
だが、AIはinguarddistトリガーでガードを行うため実質的にガード不能技になる。
遠距離から連発するだけでハメ殺せてしまう。対処法は下記の製作者向け記事を参照のこと。
省略した場合はcnsで指定する[Size]のattack.distが代入される。

別に全てのHitDefに設定する必要のあるものではないが、細かな調整をしたい時には
知っておくと便利である。たとえば瞬獄殺のようにガード不能な突進技ではGuard.Dist=0に
しておくと、相手はバックジャンプやダッシュをしなくても歩いて後ろに下がれる。

ちなみに一般的な格ゲーの投げ技はほとんどの場合ガードモーションが取れないようになっている。

なおこの方法ではHitDefを発生させる瞬間にしか設定はできず、
現在は当たり判定の発生と同時にHitDefを実行するのが一般的になっているため、
攻撃の予備動作中は通常通りの距離でガードすることになりGuard.distだけでは無意味なことも多い。
特に理由がなければ該当ステートに入った時点でAttackdistを実行し、
HitDefの実行前に変更しておいた方がいいだろう。

----
*&bold(){人操作とAIのときとのガードの違いについて}
CMDやCNSファイルに記述するステートコントローラーで、CPU操作時の特徴を検出してフラグを立て、
入力が無くとも自動的に行動するようにしたもの。つまるところAIというのはそれだけである。
敵との間合いや敵のStateType・MoveType監視し自動的に状況に即した技を出すという程度のことなら
もともとCMD・CNSで管理する領域なので全く問題は無い。
しかし本来『ガード』という行動はCMD・CNSの記述で管理されているものではない&color(red){*1}ため、
AIに的確にガードをさせようとしてもそれには限界がある。

人操作のガードは、フレームの開始時点で自分のctrlが有効かつ敵側がmovetype=AだったりProjectileを発射している時に
Command="Holdback"=1だと''内部的な''ガード状態に入る。
さらにこの時、自分が敵側のGuard.Dist圏内にいるとChangeStateが起こり、外見的にもガードモーションに入る。
なおWin版ではGuard.Distの値をInGuardDistというトリガーで参照できるので、
Win版のAIではDOS版の時のAIよりもだいぶ人間操作時に近い自然さでガードステートに移行させることができる。

CMD・CNSの記述で強引に作ったAIのガードはこれと全く違い、上で述べたInGuardDistなどをトリガーに用いて
ChangeStateで強引に120番台にステートを飛ばす&color(red){*2}ことで作られている。
しかし、InGuardDist=1を使う都合上、''Guard.Distの値以上の遠距離''から''届く攻撃''を出された時反応のしようが無い。
こればかりはキャラがたまたまCommand="Holdback"の状態で、つまり''MUGEN本来のAIの部分''でガードしてくれることを祈るしかないのである。
ちなみにもしもInGuardDistを使用しないと、DOS版の時のようなGuard.Distと無関係に敵のStatetypeや
NumProjのみを監視してガードステートに飛ばすAIになってしまう。

なおトレーニングモードにもオートガードの設定が存在するが、これは
''Inguarddistが反応したらCommand="Holdback"を実行する''というものであり、
どちらかと言えば人操作のガードに近い。
そのため一般的なAIでもガードできることを確認したければ、
stupa氏が作成した[[いっしょにとれーにんぐ]]のガードモードをAutoにして確認する必要がある。

&color(red){*1}:ガード行動のステートは他の行動と違い勝手に好きなステートNoに振り分けるなどのことは出来ない。
120~150番台の最初から決定されている特定のステートNoしかガードは出来ないし、
このステートNo郡をガードではなくさせることも出来ない。
&color(red){*2}:120~150番台のガード用のステートNoに入ると、CtrlやCommand="Holdback"に関係なく内部的にもガードの状態に入る。

----
*InGuardDist=1になるタイミングと距離について(製作者向け)
攻撃側のキャラクターがmovetype=Aになると、Attackdistを個別に設定しない限り、
攻撃のHitdefに関わらず、キャラクターの軸の前方に''cns内のSizeの項目で設定した''Attack.Distの値に応じた
InGuardDist=1が成立する範囲が発生し、このトリガーを利用してAIがガードモーションを取ることが可能になる。
なおmovetypeをA以外にすると、本体依存のInGuradDist=1が成立する範囲は存在しなくなる。
(この仕様を利用したのが、Mouser氏作成BLACK氏アレンジの[[K']]に搭載されている、AIがガードできないアイントリガーである。)


**飛び道具以外(キャラクター本体のHitdefで定義されたもの、attrは問わない)の場合
Hitdefで個別にGuard.Distが定義されていない場合はもちろん、Hitdefが実行されるまでのフレームでは、
InGuradDist=1が成立する距離は(Size内の定数、ステートコントローラを問わず)AttackDistの値がそのまま適用される。
逆に言えば、Hitdef内に明記したGuard.Distの値は、''Hitdefが実行されてからしか適用されない''。
したがって、発生の遅い投げ技の場合、技の射程範囲内でガードモーションを取り続け、
Guard.Dist=0が有効になったフレームで掴まれる、ということもありうる。
(一応技を受ける側がHitdefattr=SCA,NT,STなどをトリガーにして
1フレーム目から投げに対して無敵になるステートに移ればなんとか間に合うが、
ほとんどのAIではrandomなどを使ってChangestateが確実に作動することを防止しているため、
人操作では見てからジャンプ余裕の投げ技でも、AIではあっさり投げられてしまう。
なおAIがこの手の技に無敵技で切り返す際には、Hitdefattrではなくたいていmovetype=Aをトリガーにしている。)
意図的にガードモーションを取らせたい場合はこのままでいいが、
それでは困るという場合は、''ステートコントローラの''AttackDistを併用するか、
airファイルのCLSN1をわざと設定せず(あるいは攻撃判定を画面外遠方に設定するか)にHitdefだけを先行して実行すればよい。
前者の方法で設定したAttackDistはHitdefでguard.distを定義するまで有効で、
gurad.distを明記しないとそのステートを抜けるまでずっと有効になる。
一方後者の方法は、任意のタイミングで相手AIに技の属性まで認識させることができる。
(例えば投げモーションに入った瞬間にHitdefを実行すれば、見てからジャンプ余裕でした、という行動をAIに再現させられる。
もっともこのあたりが未調整であることを前提にして、見てからどころか超反応でジャンプやバクステを繰り出すAIも少なくないのだが。)
なおAttackDistもGuard.Distも起点はキャラクター本体の軸位置になるため、
当たり判定が大きく前方に張り出すキャラクターだけではなく、元々左右に長いキャラクターもしっかりと値を設定しておく必要がある。
//誤解を招く表現があったので修正//

**飛び道具(キャラクターのHitdef以外で定義されたもの)の場合
・Projectileを単独で用いる場合
Projectileコントローラが実行されProjectileが発生するまでは、飛び道具以外の攻撃と同様の範囲でInGuradDist=1が成立する。
しかしProjectileが発生した次のフレーム以降では、''キャラクター本体から生じるInGuradDist=1の範囲は消失''し、
今度は''Projectileの軸の前方''のcns内のSizeの項目で設定したProj.Attack.Distの値に準じた範囲でInGuradDist=1が成立する。
airファイルで設定された軸位置からProj.Attack.Distよりも前に当たり判定がある飛び道具は、
向かって前方部分ではInGuradDist=1が成立せず、AIはこのトリガーを用いてガードできなくなる。
特にビーム状の横方向に長い飛び道具でこの問題が起こりやすい。
一般的なキャラクターではcns内のAttack.Distは160、Proj.Attack.Distは90に設定されており、
Attack.Dist依存ではInGuradDist=1は成立するが、Proj.Attack.Dist依存ではInGuradDist=1が成立しないこともある。
その結果、''飛び道具の発生まではガードしているのに、飛び道具が発生した瞬間ガードを解いてダメージを受ける''という、
一見不可解な現象が起きる。MUGENユーザーならば何度となく目にしたことがある光景だろう。
対処法を簡単に説明する。
まず飛び道具が発生するまでに相手にガードモーションを取って欲しい距離を、
ステートコントローラのAttackDistで設定する。
画面端から画面端まで一瞬で届くビームのような飛び道具の場合、AttackDistのトリガーはtime=0などとするのが無難。
次にairファイル上での飛び道具の軸位置を後方にずらす。具体的には発生の根本付近の少し後ろあたり。
Projectileコントローラ内のOffsetの値(つまり、飛び道具を発生させる座標)は、airファイルの軸位置が決まった後で設定する必要がある。
また逆に、飛び道具の軸位置よりも後ろに当たり判定がある場合にも、AIがガードを解いてしまうことがある。
本体から離れたところに当たり判定が発生する場合は、いかにも飛び道具が刺さっているように見えるが、
実際にはただ単に軸位置の設定のせいでガー不になっているだけということもある。
具体的にどうすりゃいいの、という人は、出雲氏の[[ジェダ・ドーマ]]のセーガの軸位置を参考にするといいだろう。
意外に思われるかもしれないが、これでも氏のジェダほどの横幅でぎりぎりだったりする。
なお飛び道具に幅があって軸位置が画面外に出てしまう場合、ProjEdgeBoundやProjStageBoundの設定が必要になることもある。
ちなみに、Projectileを管理しているとキャラクター本体のmovetypeがAになっていても
InguarddistがProjectileにしか反応しなくなる。
そのため飛び道具発射後の硬直が短かったり、画面内外を問わず長く残る飛び道具を持つキャラクターはガー不攻撃を繰り出すことになってしまいやすい。
(例えば、Projectileで定義された弱ソニックブームを前転で抜けてきたAIに通常技を振ると、AIはガードできない)
Projectileを管理していてもHelperならInguarddistを反応させられるので、
Hitdefで定義された攻撃を含むステートに入った時点で
本体の足元にmovetype=AのHelperを設置してIngurddistを作動させ、
!numprojをトリガーにしてdestroyselfで消えてもらえばこの事態は避けられる。
いっそのこと飛び道具をProjectileではなくHelper形式に切り替えるという手もあるが、
これはこれで相手側がnumprojトリガーなどを使えないという問題(詳細は後述)を含むので推奨しない。
//Projectile管理時の仕様について追記
・Helperを単独で用いる場合
飛び道具に複雑な挙動をさせたい場合、HelperにHitdefを設定して飛び道具とすることでかなり自由度が増えるが、
見た目には同じ飛び道具でも内部での振る舞いはProjectileとは大きく異なる。
まずProjectileとは異なり、キャラクター本体のmovetypeがAならば、
Helperを発生させても本体依存のInGuradDist=1の範囲は消失しない。
そのため飛び道具を飛び越えるなどしてスカした後でも、攻撃を受ける側がガードしっぱなしになることがある。
Helperの位置を特定するトリガーがあれば飛び道具を後方にやりすごしたことをAIが確認できるのだが、
あいにくそのようなトリガーは存在しない。
(手段が全くないわけではないのだが、それなりの準備を必要とする。
興味がある人は[[簡易AIテンプレ等]]のページにリンクされている厨忍氏のAI作成に関するQ&A集を読んでみよう。)
このように、攻撃を受ける側が認識するのは難しいが、
攻撃する側がHelperを発生させたフレームでステートコントローラを使ってAttakdist=0とすれば、
Projectileと同様に本体依存のInguardDist=1の範囲を消すことが簡単にできる。こだわりがある人は、設定しておいて損はないだろう。
また、デフォルトでInGuradDist=1となる範囲もProjectileと異なる。
ProjectileではProj.Attack.Distの値が参照されるが、HelperはHitdef内の設定attr = S,SPなどとして飛び道具属性にしても、
cnsのAttack.Distの値が参照される。いずれにせよステートコントローラでAttackDistを長めに設定しておけば
飛び道具の発生後もその範囲でInGuradDist=1は成立し続けるので、あまり問題にはならない。
Helperは特殊な挙動を設定できる分、Projectileとは違った原理でガー不になることがある。
その最たる例が画面上を左右に往復するタイプの飛び道具で、
前述したようにInGuradDist=1になるのは飛び道具の前方だけに限られるので、
飛び道具が敵の背後から飛んでくるタイミングでは、見た目だけではなく内部的にも飛び道具の向きを変えてやる必要がある。
方法は単純で、見た目の向きが変わったところで、Helper側でステートコントローラのTurnを使ってやればよい。
(Vel Xの値はプレイヤーでもHelperでも向いている方向を正とするので、
いったん減速させたのち反転させ、再度加速させればブーメランのような挙動になる。)
なおIngurddistと直接関係はないのだが、Helper形式の飛び道具はNumProjトリガーに反応しないことも頭に入れておきたい。
当たり前のような話ではあるが、攻撃を受ける側のAIにしてみれば、
Projectileならば発生直後からNumProjで認識できるのに対し、HelperはInGuradDist=1が成立するまで
特殊な方法を取らなければその存在が全く掴めないのである。
Numhelperトリガーを使えばいいと思われるかもしれないが、いまやゲージやエフェクトに多量のHelperが使われ、
しかもHelperのmovetypeを認識するトリガーが存在しない(一応認識する手段はある。前述した厨忍氏のQ&A参照。)ので、
現実的にはNumhelperトリガーは単独では防御、警戒には使えない。
特に速度の速い飛び道具を使う場合は、そのことを念頭に置いた上でGuard.distを設定したい。
//(とはいえProjectileはProjectileで防御側が位置を特定する手段が発見されていないので、一概にProjectileがいいとは言えない。
//なお参考までに、悪咲3号氏製のキャラクターはProjectileとHelperを同時に用いており、どちらの方法でも対応できるようになっている)
//helperを利用した飛び道具は位置以外にもprojectileとの相殺などに問題があるためコメントアウト
・キャラクターの軸を中心に当たり判定が発生するHitdefで定義された攻撃について
ProjectileやHelperなら軸位置で対応できるが、キャラクターの軸位置を動かすことはできないので
足元に本体とは逆方向を向いたmovetype=AのHelperを設置し、
キャラクターの後方でもInguarddistが成立するようにしてやればよい。
ちなみに全画面攻撃もHitdefで定義されていればこの部類に入るが、
Helperを設置すると同時に本体およびHelperのattackdistを延長しておかないと、
相手との距離が離れたときにガー不になってしまう。
//ProjectileやHelperであれば軸位置で対処できるので、本体のHitdefに限定

かなり長々と書いてきたのでうんざりした人も少なからずいると思われるが、
実際にAIがきちんとガードできるかどうかを確かめるには、stupa氏が作成した[[いっしょにとれーにんぐ]]のガードモードをAutoにした上で、
//AIのガードとトレモのオートガードは仕様が異なるのでこちらに。
少しずつ互いの位置をずらしながら技を振ってみるだけでいい。
意図した通りにガードしてくれなければ、cnsかairか、どこかに問題があるはずである。
//AIのガード関係について追記。誤りや不適切な表現などがあれば修正していただけると助かります。
//regionから独立させておきました。
//Helper発生後の処理と、飛び道具の軸位置が画面外に出てしまうときの対処について追記。

#region
動画で「ガードしろw」、「なぜつっこんだw」というコメントをしばしば見かけるが、
ガードしなかったAIではなく攻撃している側のcnsの方に原因がある場合も少なくない。
ただし、原因の特定は動画だけではまず不可能で、双方のAI、cns、airを照らし合わせながら、
デバッグを起動して最低限フレーム単位、場合によっては同一フレーム内での複数回のchangestateまで確認する必要がある。
また、ガードはMUGENの内部処理にも関わってくるため、下手をすると[[神キャラ]]製作者レベルの知識を要求されることも。
それぐらいならまだ対処の手段もあるが、MUGENの仕様上どうしようもないこともある。
Y軸方向の当たり判定、guardflag、持続、当たり判定の形状の変化などをAIは参照できない。
//また、厨忍氏が解説しているヘルパーリダイレクトを利用した飛び道具の位置検出を
//出雲氏のジェダのセーガのように軸位置を当たり判定からずらしたHelper型の飛び道具に対して行うと、
//AIがそのずれた位置を検出してしまい、不自然な挙動を取る可能性がある。
//Projectileで実現できる飛び道具ならば、エフェクトと位置情報をmovetype=Aでattackdist=0にしたHelper、
//攻撃をguard.distを飛び道具に合わせて設定したProjectileで処理することで解決できるのだが、
//セーガはHelperでしか実現できない挙動を取るのでどうすることもできない。
//なお、これは出雲氏がInguraddistの挙動を理解しているからこそ起こってしまったもので、
//出雲氏には全く非がないことを言明しておく。
//攻撃判定を持たせた飛び道具の軸位置を戻しても、その飛び道具とは別にmovetypeをAにしたhelperを出しておけばガードでは問題ないのでコメントアウト
こうした背景があるので、動画内で軽々しくcnsの不備を疑うようなコメントをしてはならない。
もししっかりと調べた上で原因が特定できたら、キャラクターの製作者にメールなどで連絡してあげよう。
#endregion

----
*暗転中に攻撃判定が発生する技とガード
一般的な格闘ゲームにおいて暗転中に攻撃判定が発生する技に関しては
暗転中相手は動けないので暗転前からガードモーションをとっていないとガードできない。
一方MUGENでは、単にsuperpauseやpauseを実行するだけでは暗転してからキーを入力してもガードが間に合う。
//MUGENに関してもこれは同じなのだが、MUGENの場合たとえガードポーズを取っていてもガードができないことがある。
//これは暗転中に攻撃判定が出ている場合、防御側キャラクターは120番ステートか130~132番ステートにいないとガードができず、
//ガード硬直にあたる150番台のステートにいる場合ガードステートへの移動ができないため、
//その結果guardflagが設定されている攻撃でも強制的にガード不能になるという仕様からくるもの。
これは暗転中も「ctrlが有効か、ガードステートにいて、かつcommand="holdback"が成立している」という
ガード成立条件が機能していることが原因。
そのため暗転後ガード不能な技を作るためには暗転時に相手がガードステートにいるかどうかを参照して、
ガードしていればガード可能なhitdefを実行、そうでなければガードできないhitdefを実行する必要がある。
もちろんassertspecialのflagに空きがあればunguardableを実行してもいい。
なおhitdefによる指定を行う場合、暗転が解除された時点でhitdefをガード可能なものに上書きしておかないと、
暗転解除後も攻撃がガード不能になってしまうことに注意。
また、暗転時にガード姿勢にいることをトリガーにする以上、
inguraddistが成立した状態で、1回以上相手側にステート処理順序が回っていなければならない。
早い話が1P2Pを問わずattackdistの足りない攻撃や、2P側から0F暗転技をぶっぱなすとどこをどうやってもガード不能になってしまう。
このため、MUGENで暗転前ガード可能かつ暗転後ガード不能の0F暗転技を完璧に実装するのは事実上不可能になっている。
なお、AIは暗転中に攻撃判定が発生する技は基本的にガードできない。
通常commandが実行されていなくても単にガードステートにいるだけでガードは可能で
AIはこの仕様を利用してガードしているのだが、
暗転中はcommand="holdback"が成立していないとガードができない。
そのため、一見するとガードモーションを取っているように見えても、
AIは暗転中に攻撃判定が出る攻撃は無防備に受けてしまう(ただしhitoverrideを作動させていた場合は作動する)。
いずれのケースでもガー不技(投げ技も含む)であれば問題ないのだが、そうでない技を作るときは注意しよう。

----
*DOS版MUGENのガード硬直半減仕様
DOS版MUGENはcommonの仕様がWIN版MUGENや1.0以降のMUGENとは異なるため、
ガード硬直がhittimeで設定したフレームの半分(実際には半分+小数点部分切り上げ)になる。
一見WIN版などを使っていれば関係ない話に聞こえるが、当時製作されたキャラやDOS版からコンバートしたキャラの中には
このバグを回避するために&bold(){ガード硬直を本来の2倍の値に設定したキャラ}が多数存在する。(sander71113氏製作のキャラなど)
古いキャラを使っていて固めが異様に強かったりした際には一度チェックしてみよう。
また逆に、DOS版からコンバートされたキャラで、ガード用のステートがキャラクターのcns内に記載されている場合、
本来のガード硬直の半分のフレームでガード硬直が解除されることがある。
この場合、他のキャラクターでは連続ガードになるはずの連携に割り込むなどの現象が発生する。
こちらの問題の修正方法は以下の通り。
cnsファイルをテキストエディタやメモ帖で開き、statedef 151で検索する。
キャラクターのcnsファイルが複数あるなら、全てのcnsファイルから探す。
statedef 151が見つかったら、その少し下にある
[State 151, 4]
type = ChangeState
trigger1 = Time >= GetHitVar(hittime)
value = 130
ctrl = 1
この記述を
[State 151, 4]
type = ChangeState
trigger1 = Hitover
value = 130
ctrl = 1
と書き換える。(Time >= GetHitVar(hittime)をHitoverと書き換えればよい)
また、statedef 153で検索して、同じようにTime >= GetHitVar(hittime)をHitoverと書き換える。
cnsの書き換えの前には、必ずバックアップを取っておくこと。

復元してよろしいですか?