====================================================================
道探しの枠（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）。
