==================================================================== 道探しの枠(pathfindingIterationsPerFrame)が残る穴を直した 2026-10-26 07:25 ==================================================================== 結論 ・エイイチの疑いは **当たっている可能性が高い**です。 戻し方に **穴が3つ**あり、どれでも 5000 がエディタを閉じるまで残りえます。 いちばん効くのは「**切り替えを『切』にしても、Unity の中の値は戻らない**」です。 ・ただし **18回が 5000 で回ったと断定はできません**。 cs:7 の run_info.json には枠の値が入っていないからです(記録が無かった)。 これが今回の直し (2) で記録されるようになります。 ・直して check-in しました(**cs:8**)。保留 0。組み立ては通っています(55 本・エラー 0)。 ・⑦0台・種0〜2 を 100 と 5000 で回すメニューを足しました(押す順番は 4 章)。 ==================================================================== 1. (1) RestoreDetCheck は戻しているか → 戻すが、穴が3つある ==================================================================== 直す前のコード(cs:7) void ApplyDetCheck() // StartJob から呼ぶ { _savedPathIterations = NavMesh.pathfindingIterationsPerFrame; // 今の値を覚える if (plan.detCheckPathIterations > 0) NavMesh.pathfindingIterationsPerFrame = plan.detCheckPathIterations; … } void RestoreDetCheck() // OnDisable からだけ呼ぶ { if (_savedPathIterations >= 0) { NavMesh.pathfindingIterationsPerFrame = _savedPathIterations; _savedPathIterations = -1; } … } 形としては戻しています。けれど次の3つの穴があります。 穴A ★ いちばん効く:**「切」にしても戻らない** 「ぜんぶ切る」を押すと detCheckPathIterations が 0 になります。 すると ApplyDetCheck は **今の値を覚えるだけで、何も入れません**。 つまり、その時点で Unity の中が 5000 だったら 5000 のまま回り、 RestoreDetCheck は覚えた 5000 をそのまま書き戻します。 → 「切」は「上書きをやめる」だけで、「100 に戻す」ではありませんでした。 いちど 5000 が残ると、エディタを閉じるまでずっと 5000 です。 穴B 戻すのが OnDisable だけ FinishJob や AllDone では戻していません。Play を抜けるときの OnDisable だけです。 19:41〜43 のように **Play の最中にスクリプトが読み込み直された**ときは、 _savedPathIterations([SerializeField] でない private)が初期値 −1 に戻るため、 `if (_savedPathIterations >= 0)` が偽になり **戻しが丸ごと飛びます**。 穴C 1回の Play で2条件以上回すと、2度目が壊れた値を覚える StartJob は、並べた条件がある間くり返し呼ばれます(ExperimentRunner:881)。 RestoreDetCheck は Play の終わりに1回だけです。 → 1条件め:100 を覚えて 5000 を入れる 2条件め:**5000 を覚えて** 5000 を入れる Play の終わり:**5000 を書き戻す** 段階Bと Site Run は1回の Play で1条件なので、この穴は踏みません。 段階2・段階3の Run All は踏みます。 断定できない理由 cs:7 の18回の run_info.json を見ましたが、 path_iterations_per_frame … **記録なし**(当時は書いていない) det_check … 空(切り替えはぜんぶ切) det_check が空なのは「上書きしていない」ことしか示さず、 穴A のとおり **そのとき Unity の中が何だったかは分かりません**。 なので「18回は 5000 で回った」とは言えず、**4 章の確かめで決める**しかありません。 ==================================================================== 2. (2) 直した中身(cs:8) ==================================================================== 考え方:**knob を1つにして、回すたびに必ず入れる。戻す処理をやめる。** 戻す処理がある限り「戻し損ね」が起きるので、その形そのものを無くしました。 ExperimentPlan.cs + pathIterationsPerFrame = 100(新しい項目。Unity の既定と同じ) − detCheckPathIterations を廃止(knob を2つにしない=隠れた設定を作らない) ExperimentRunner.cs ・回し始め(StartJob → ApplyDetCheck)で **必ず** 入れる: int want = plan.pathIterationsPerFrame > 0 ? plan.pathIterationsPerFrame : 100; NavMesh.pathfindingIterationsPerFrame = want; _pathIterationsUsed = NavMesh.pathfindingIterationsPerFrame; // 読み直す if (_pathIterationsUsed != want) → Debug.LogWarning 0 以下なら 100 を使います。**入れたつもりではなく、読み直した値**を記録します。 ・RestoreDetCheck から枠の戻しを外した(_savedPathIterations も消した) ・回し始めのログに「道探しの枠: N 回/コマ」を必ず出す TripLogger.cs + run_info.json に "path_iterations_per_frame": N(実際に入った値) Editor/ServiceSimStageB.cs ・「切り分けの設定」の表示を、枠は切り替えではなく「いまの値」として常に出す形に ・「ぜんぶ切る」は **枠も 100 に戻す**(穴A をメニュー側でも閉じる) + メニュー「道探しの枠を 100 にする(既定)」「道探しの枠を 5000 にする」 + メニュー「道探しの枠の確かめ(⑦0台・種0〜2)」(名札 path_check) ・測る回を止める条件から枠を外した(枠はもう隠れないので) 店の回し方・ロボットと人の動き・台帳の列は変えていません。 確かめ(Unity 抜き・19 件ぜんぶ OK) 初期値 100 / detCheckPathIterations が Runner と StageB から消えた / 0 以下なら 100 / 回し始めに必ず入れる / 入れたあと読み直す / 入らなかったら警告 / RestoreDetCheck は枠を触らない / _savedPathIterations そのものが無い / run_info に出る / 回し始めのログに出る / メニュー3つ / 名札 path_check / 条件3を3回・種0〜2 組み立て:55 本・エラー 0 ==================================================================== 3. なぜ⑦だけ・ロボット0台でも出たのか(筋は通ります) ==================================================================== 枠が大きいと、人(スタッフ・客)の道が早く引き上がります。 依頼 v11 の調べで分かったとおり、道が引けていない間は StaffAgent:189 着いたかの判定を打ち切る → 会計・片付けの始まりが遅れる GuestAgent:175 同じ PersonRobotYield:774 よけるかの判断を打ち切る ので、枠が大きい=人の反応が早い=**待ちが短く出る**向きです。 ・⑦(fam_p5)の通路は 0.95 m、③(fam_p1)は 1.2 m。 狭いほど人の道の引き直しが増えるので、⑦に強く出るのは筋が通ります。 ・ロボット0台でも出るのは、効くのが **人の道**だからです。ロボットは関係ありません。 ・「卓を空けた 1〜4 → 0」も、片付けの始まりが早まれば減る向きです。 ただしこれは筋の話で、証拠は 4 章の確かめで取ります。 ==================================================================== 4. (3) 押す順番(Unity を一度閉じて開き直してから) ==================================================================== 0. Unity を **閉じて開き直す**(これで Unity の中の枠が既定 100 に戻ります) 1. ServiceSim → Stage B → 切り分けの設定 → 道探しの枠を 100 にする(既定) 2. ServiceSim → Stage B → 道探しの枠の確かめ(⑦0台・種0〜2) 3. ServiceSim → Stage B → 切り分けの設定 → 道探しの枠を 5000 にする 4. ServiceSim → Stage B → 道探しの枠の確かめ(⑦0台・種0〜2) 5. ServiceSim → Stage B → 切り分けの設定 → 道探しの枠を 100 にする(既定) ← 終わったら必ず 100 に戻してください(次の回のため) 出力は 6 フォルダ。名札が path_check なので18回とは混ざりません。 20261026_path_check_cs8_fam_p5_r0_s0 / _s1 / _s2 (1〜2 が枠 100) 20261026_path_check_cs8_fam_p5_r0_s0_2 / _s1_2 / _s2_2 (3〜4 が枠 5000) ★ どちらの枠で回したかは、各回の run_info.json の path_iterations_per_frame で必ず分かります(取り違えません)。 Console の回し始めの行にも「道探しの枠: 100 回/コマ」と出ます。 見るところ(私が並べます) 入店待ち・席は空いているのに待った・卓を空けた・客が帰ってから卓が使えるまで → 100 と 5000 で差が出れば、18回(⑦)のずれの原因はこれと決まります。 そのうえで、18回を枠 100 で回し直すかを決めましょう。 → 差が出なければ、⑦のずれは別の原因です。cs:144 と cs:7 の間で ⑦に効く変更(v10 の逃がし弁の数え方・v10b・v11 の移設)を1つずつ見ます。 1回 12 分前後 × 6 回で 70〜80 分の見込みです。 ==================================================================== 5. 気をつけること ==================================================================== ・ExperimentPlan.asset には pathIterationsPerFrame の行がまだありません。 Unity を開き直すと C# の初期値 100 で書き出され、保留に1件出ます。 **その行(100)はそのまま check-in して構いません**(既定を .asset に残す形)。 私がやってもよいので、開き直したあと声をかけてください。 ・枠を 5000 にしたまま段階Bを回さないでください。 「ぜんぶ切る」でも 100 に戻るようにしましたが、 回し始めのログと run_info で必ず確かめられます。 ・18回(cs:7)の判定結果は、枠がどちらだったか分からないまま残ります。 基準データにするかは、4 章の結果を見てから決めるのが安全だと思います。 check-in:**cs:8**(直したファイル4本)。保留 0。 依頼 v13 の 依頼2(店の時計と倍率の画面)は、まだ手付かずです(次は cs:9)。