2015年09月18日

状態検証の追加方法

0232で実装した状態検証プラグインの作り方について少々説明しておこうかと思います。

以下、付属の CSスクリプトプラグインを用いた作成方法を紹介します(通常のプラグイン作成の場合は自前で初期化を行う必要がある程度で後は同様です)

■作成手順
1. CS(C#)スクリプトを開き、メニュー[ファイル]-[新規作成-状態検証]を選択(→編集タブが一般形式へ移行/コードが自動的に変更)
2. 検証コードを追記
3. ビルド確認(F6)を行いエラーがなければ、[ファイル]-[プラグインDLL生成]でDLLファイルへ変換し保存
4. PMXエディタを再起動し、追加した状態検証が正常に動作するかチェック

■検証コード
CheckPmx() 処理に渡される PMXデータを適宜調査し、検証結果を PECheckResult データとして返すことで状態検証へ結果が表示されます。

●PECheckResult
Text : 状態検証に表示される結果文字列(string)
Filter : ○/△/×にそれぞれ相当するフィルタ数値(int) ○=0/△=1/×=2

●IEnumerable<PECheckResult>
検証結果は列挙子に包んで返します。よって一つのプラグイン処理で一度に複数の検証を行うことができます。実際のコードでは PECheckResultの配列やリストなどを用いる他、yield return を使って一つずつ結果を返すことも可能です。


■コード例
※参考用なので実用性はありません。

●モデル名が "初音ミク" であるかチェック
public class CheckerClass : IPECheckerPlugin
{
public IEnumerable<PECheckResult> CheckPmx(PEPlugin.Pmx.IPXPmx pmx)
{
if(pmx.ModelInfo.ModelName == "初音ミク") {
yield return new PECheckResult() { Text = @"○ モデル名は ""初音ミク"" です.", Filter = 0 };
}
else {
yield return new PECheckResult() { Text = @"× モデル名が ""初音ミク"" ではありません.", Filter = 2 };
}
}
}


●全ての親ボーンがあるかどうか/全ての親ボーンが先頭であるかどうかを同時にチェック
public class CheckerClass : IPECheckerPlugin
{
public IEnumerable<PECheckResult> CheckPmx(PEPlugin.Pmx.IPXPmx pmx)
{
int bx = -1; // 対象ボーンのIndex
for (int i = 0; i < pmx.Bone.Count; i++) {
if (pmx.Bone[i].Name == "全ての親") {
bx = i;
break;
}
}

var r = new PECheckResult[] {
new PECheckResult(){ Text = "○ 全ての親ボーンが含まれます.", Filter = 0 },
new PECheckResult(){ Text = "○ 先頭ボーンは全ての親ボーンになっています.", Filter = 0 }
};

if (bx < 0) {
r[0].Text = "× 全ての親ボーンが含まれません."; r[0].Filter = 2;
}
if (bx != 0) {
r[1].Text = "× 先頭ボーンが全ての親ボーンではありません."; r[1].Filter = 2;
}

return r;
}
}


●Jointが剛体間に位置しているか簡易チェック
public class CheckerClass : IPECheckerPlugin
{
public IEnumerable<PECheckResult> CheckPmx(PEPlugin.Pmx.IPXPmx pmx)
{
// null指定で検証無効
if (pmx.Joint.Count == 0) { return null; }

var list = new List<int>();
for (int i = 0; i < pmx.Joint.Count; i++) {
var j = pmx.Joint[i];
if (j.BodyA == null || j.BodyB == null) { continue; }

// 剛体位置(xyz)を小〜大で範囲分け
V3 max = V3.Max(j.BodyA.Position, j.BodyB.Position);
V3 min = V3.Min(j.BodyA.Position, j.BodyB.Position);

// Joint位置が両剛体の外側にある場合(X/Yのみ判定)
if (j.Position.X < min.X || max.X < j.Position.X || j.Position.Y < min.Y || max.Y < j.Position.Y) {
// Indexをリストへ追加
list.Add(i);
}
}

// 先頭で通常のreturnを使っているのでyield returnは使えません
var r = new PECheckResult();
if (list.Count == 0) {
r.Text = "○ 全てのJoint位置は関連剛体間に配置されています."; r.Filter = 0;
}
else {
r.Text = "△ 次のJoint位置は関連剛体間に配置されていません(X/Y範囲のみ/Index表示) -> " + string.Join(",", list); r.Filter = 1;
}
return new PECheckResult[] { r };
}
}

※Joint位置は必ずしも剛体A-Bの間にある必要はありませんので、↑の検証自体には大きな意味はありません。


■まとめ
というような感じでエディタのソース内にも状態検証コードがずらずらと並んでいたりします。

単純な検証でも実際のコード作成は色々面倒なことが多いので、誰でも簡単に思った通りのものが作れるわけではありませんが(複雑な検証であれば尚更)、このように必要に応じて拡張自体は一応行うことができるようになっていますよ、というお話でした。

以上

【関連する記事】
posted by - at 22:19| PMX | 更新情報をチェックする

2015年08月30日

0232

■更新内容

・状態検証簡易フィルタリング
・任意の状態検証項目の追加(プラグイン実装)

以上


不具合修正がてらのちょっとした機能追加です。

状態検証を ○/△/× で表示分けできるようにしておきました。

合わせて任意の検証項目を追加できるよう機能修正(フィルタがあれば見落としも減るので項目を増やせるようにしても大丈夫かな?と)

といっても検証方法は全てプラグインコードで書く必要があるので「誰でも気軽に」というわけにはいきませんけどね。

※一応、CSスクリプトプラグインでも作成すること自体は可能です(通常プラグインとは異なる仕様なので実行はできません/DLL変換後要再起動)

あと状態検証プラグインは昨今の Cプラグイン仕様ではありませんので、細かくデバッグなどを行いたい場合は、Cプラグインにて検証部分を作成→状態検証プラグインへ移植、といった手順で作成してください(インポート/エクスポートと同様)


以上

posted by - at 21:12| PMX | 更新情報をチェックする

2015年08月24日

15夏Eマップ

今回はブログへの記載はスルーしようかとも考えましたが(前エントリ参照)、一応それなり?の結果でクリアできたので簡単に書いておきたいと思います。

0082.jpg

0083.jpg

全甲クリア及び全艦ゲット(画像は江風以外)、フルコンプリート達成です。


それにしても今回のイベントマップにおいては、

・札多すぎ
・ドロップ艦多すぎ
・ドロップ率絞りすぎ
・丙リセマラ推奨とか正気を疑う
・E7弱体効果が解り難すぎ
・弱体効果の有無をゲーム内から発見できない(外部告知のみ)
・弱体効果リセットがどこからも確認できない(外部告知のみ)
・毎日深夜0時に弱体効果を強制リセット(史実をモチーフにするならXY最終撃破から??時間とかでよいのでは?)
・連合マップのゲージ長すぎ(甲ならともかく丙でも時間と資材かかりすぎ)
・おにぎり多すぎ

などなど、およそバランス調整や演出といったものを十分に考慮したとは思えない酷さでした(特に新艦の掘り関係はどうしようもない...)

まあこのあたりはそこかしらで既に語られていることなので、ここでは適当にしておきますが。


■攻略記録

0084.jpg

0085.jpg
到達数=ボスマス戦闘回数

●編成など

E1 | 菊月(66)/伊勢型(98)/球磨or長良(86)/駆逐(66)/駆逐(66)/駆逐(66)

E2 |
1: 龍驤(82)/伊勢(98)/日向(98)/衣笠(82)/高雄(83)/愛宕(83)
2: 球磨or長良(86)/駆逐(66)/駆逐(66)/木曽(97)/北上(69)/大井(69)

E3 [丙掘り] |
1: 龍驤(82→96)/伊勢(98→99)/日向(98→99)/摩耶(86→93)/加賀(86→94)
2: 阿武隈(87→96)/雪風(96→98)/秋月(93→96)/高雄(83→91)/愛宕(83→91)/木曽(97→98)

E3 [攻略] |
1: 加賀(94)/武蔵(132)/大和(132)/赤城(98)/千歳(98)/千代田(98)
2: 阿武隈(96)/秋月(93)/ビスマルク(98)/鳥海(86)/雪風(98)北上(98)

E4 [丙掘り] | 龍驤(86)/吹雪(90)/初霜(88)/霧島or金剛(97)/比叡or榛名(97)/鳥海(86)

E4 [攻略] |
削り: 龍驤(86)/吹雪(93)/初霜(91)/金剛(98)/榛名(98)/加賀(99) ※北ルート
撃破: 金剛(98)/榛名(98)/比叡(98)/霧島(98)/龍驤(86)/祥鳳(86) ※夜戦ルート

E5 | 龍鳳(84)/扶桑型(98)/最上or三隈(90)/Z1(74)/Z3(74)/大井(98)

E6 [丙掘り] |
1: 瑞穂(育成枠)/扶桑型(98)/龍驤(87)/隼鷹(88)/飛鷹(86)/摩耶(93)
2: 阿武隈(96)/島風(96)/秋月(96)/綾波(94)/Prinz(86)/鳥海(90)

E6 [攻略] |
1: 摩耶(93)/長門(84)/陸奥(84)/大鳳(136)/加賀(95)/赤城(98)
2: 阿武隈(96)/ビスマルク(98)/秋月(96)/鳥海(90)/Prinz(86)/雪風(98)

E7 [XY] |
1: あきつ丸(91)/長門(84)/陸奥(84)/大鳳(136)/隼鷹(88)/飛鷹(86)
2: 阿武隈(96)/島風(96)/潮(87)/ビスマルク(98)/Prinz(86)/鳥海(90) ※三式弾

E7 [攻略] |
1:
摩耶(94) : 90高角(★10)/司令部/25集中機銃/FuMO
武蔵(132) : 試41主/41主/水観/一式徹甲弾(★2)
大和(132) : 同上
隼鷹(88) : 流星(601)/烈風(601)/烈風改/二式艦偵
飛鷹(87) : 流星改/烈風(601)/烈風/烈風
龍驤(88) : 烈風/流星(601)/烈風/彩雲

2:
阿武隈(96) : 4連酸素魚雷(★6)/4連酸素魚雷(★6)/甲標的
鳥海(90) : SKC主/SKC主/夜偵/照明弾
雪風(98) : 5連魚雷/5連魚雷/照明弾
綾波(95) : 5連魚雷/5連魚雷/見張員
Prinz(86) : 53cm魚雷/5連魚雷/5連魚雷/見張員
ビスマルク(98) : 38改主(★2)/38改主(★2)/夜偵/大型探照灯

※削り時は大和型→長門型、綾波→秋月(96) : 10主+高射/10主+高射/13改電探

XY撃破は各5回(Xは+1〜2回)
道中支援(全キラ) : 正規空母x2(彗星一二甲x2+32電探x2)/利根型x2
ボス支援(旗艦のみキラ) : 正規空母x2(彗星一二甲x2+32電探x2)/戦艦x2(主x2+32電探x2)

・ゲージ破壊時の行動パターン
1. 昼戦時に棲姫一隻撃沈、残りボスと棲姫一隻のみ(第二部隊は全員健在)
2. 夜戦最初に阿武隈カットイン→残りの棲姫をワンパン(300オーバーダメージ)
3. 敵ボス攻撃により綾波大破
4. 鳥海連撃→雪風カットインで順調に減らし(残120程度)
5. Prinzカットインで150オーバーダメージによりボス撃破→S勝利

たいへん理想的な勝ちパターンでした。

※今回も最終マップは恒例の全艦撃破(S)勝利(ボス艦はラストショット)。経験上うちの艦隊がスナイプで勝つことはできませんので(苦笑)


■感想

全マップ通して、出撃艦は疲労回復のみでキラ付けはなし(間宮伊良子使用ゼロ)、今回導入された補強増設も未使用でダメコン/女神も不要という、ゆるゆるプレイでやってました。

まあいつもとは異なり今回はかなり情報が出揃ってからの攻略でしたので、余裕があるのも当然と言えば当然ですけどね。

今回は特に先行して進んだ方々に(冷酷無慈悲に)厳しい調整だったようなので、屍?になりながらも有益な情報を提供し続けて頂いていることに感謝しつつ(皮肉ではなく)、〆にしたいと思います。

以上、15夏Eマップの攻略記録でした。

posted by - at 22:05| その他 | 更新情報をチェックする