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

「ガード関連の仕様について」の編集履歴(バックアップ)一覧に戻る

ガード関連の仕様について - (2010/04/21 (水) 10:49:22) のソース

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

----
#contents
----

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

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

----
*&bold(){Guard.Distについて}
HitDef内の設定であるGuard.Dist。そのHitDefの攻撃を出している時に相手がガードモーションを
とりうる最大距離を示す。

キャラクターが攻撃を出していても、そのHitDefのGuard.Dist値以上に距離が離れていると敵は
ガードモーションをとらない(とれない)。これはあくまでガードモーションに移行しないだけで
ガードは問題なくできる。省略した場合はcnsで指定する[Size]のattack.distが代入される。

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

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

この方法ではHitDefを発生させる瞬間にしか設定はできないが、AttackDistというステートコントローラーなら
任意のタイミングで変更が可能。

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

人操作のガードは、敵側がmovetype=AだったりProjectileを発射している時に自分がCtrl=1で、
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になってしまう。

&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がガードできないアイントリガーである。)

このAttack.Distはキャラの大きさに依存される。デフォルトでは160だが、D4仕様のキャラの場合0.5倍されて実際は80に
なってしまう。リーチの長いキャラやD4キャラの場合は大きめに設定しておこう。

**飛び道具以外(キャラクター本体の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を単独で用いる場合
Hitdefが有効になり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ファイル上での飛び道具の軸位置を後方にずらす。具体的には発生の根本付近の少し後ろあたり。
Hitdef内の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を同時に用いており、どちらの方法でも対応できるようになっている)
''キャラクターの軸を中心に当たり判定が発生するHitdefで定義された攻撃について''
ProjectileやHelperなら軸位置で対応できるが、キャラクターの軸位置を動かすことはできないので
足元に本体とは逆方向を向いたmovetype=AのHelperを設置し、
キャラクターの後方でもInguarddistが成立するようにしてやればよい。
ちなみに全画面攻撃も、Hitdefで定義されていればこの部類に入る。
//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の挙動を理解しているからこそ起こってしまったもので、
出雲氏には全く非がないことを言明しておく。
こうした背景があるので、動画内で軽々しくcnsの不備を疑うようなコメントをしてはならない。
もししっかりと調べた上で原因が特定できたら、キャラクターの製作者にメールなどで連絡してあげよう。
#endregion

----
*暗転中に攻撃判定が発生する技とガード
一般的な格闘ゲームにおいて暗転中に攻撃判定が発生する技に関しては
暗転中相手は動けないので暗転前からガードモーションをとっていないとガードできない。
MUGENに関してもこれは同じなのだが、MUGENの場合たとえガードポーズを取っていてもガードができないことがある。
これは暗転中に攻撃判定が出ている場合、防御側キャラクターは120番ステートか130~132番ステートにいないとガードができず、
ガード硬直にあたる150番台のステートにいる場合ガードステートへの移動ができないため、
その結果guardflagが設定されている攻撃でも強制的にガード不能になるという仕様からくるもの。
もともとガード不能な技や投げ技であれば関係ないが、ガード可能な暗転後0F発生の技を作るときには気をつけよう。

----
*ガード硬直半減バグ
DOSMUGENには&bold(){ガード硬直が設定したものの半分になる}というバグがある。
一見WINMUGENなどを使っていれば関係ない話に聞こえるが、当時製作されたキャラやDOS版からコンバートしたキャラの中には
このバグを回避するために&bold(){ガード硬直を本来の2倍の値に設定したキャラ}が多数存在する。(sander71113氏製作のキャラなど)
古いキャラを使っていて固めが異様に強かったりした際には一度チェックしてみよう。