[WL-816i2] 던전 재입장 시 전투가 시작되지 않던 것 수정 (#816)
- 원인(실측): 전투 시작 신호는 RealCamera 의 카메라 연출이 끝날 때 나온다 — PCActor.StartCam → Set_Target(pc, CamRot_Portal) → CamStatus=0 + list_tfCamactionTarget.Add(pc) → LateUpdate 가 목록을 다 비우면 Start_Game() → ActorInfo.All_Stop(false) + DungeonInfo.Start_Dungeon. 그런데 원본에 그 목록을 비우는 곳이 없어 맵을 바꾸면 **죽은 Transform** 이 남고, 재입장 때 `camTarget.position`(RealCamera.cs:199)이 MissingReferenceException 을 던져 LateUpdate 가 매 프레임 끊긴다 → Start_Game() 이 영영 안 불려 전투가 멈춘 채로 남는다. (816i 가 Get_PortalPos 콜백을 되살리기 전에는 이 경로 자체가 안 돌아 드러나지 않았다.) → 죽은 항목만 걷어내고, 비면 지금 대상을 한 개 채운다(원본 0줄 · SO 로 끔). - 같은 씬을 쓰는 던전(1·3 = WL_Dungeon01, 2·4 = WL_Dungeon02)에서 씬 이름으로만 찾느라 **언제나 앞 줄**의 스테이지가 돌던 것 수정 — 입장 요청(Pending)을 우선한다. 실측: 던전 3 입장 시 stageIndex 12·보상 192(전에는 10·96). - 던전 전용 카메라 거리(dungeonCamDistance)를 SO 에 분리(섬 값은 그대로). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
30c73321e9
commit
6cb9f40944
|
|
@ -82,12 +82,14 @@ MonoBehaviour:
|
|||
camPitch: 45
|
||||
camYaw: 0
|
||||
camDistance: 22
|
||||
dungeonCamDistance: 18
|
||||
camFov: 60
|
||||
camLookHeight: 0
|
||||
camLockYaw: 1
|
||||
camLeadMultiplier: 1
|
||||
fixDegenerateCameras: 1
|
||||
cameraGuardInterval: 0.5
|
||||
fixCamActionTargets: 1
|
||||
dungeons:
|
||||
- enabled_: 1
|
||||
id: 1
|
||||
|
|
|
|||
|
|
@ -111,7 +111,13 @@ namespace WL.Island
|
|||
return;
|
||||
}
|
||||
|
||||
var dg = cfg.FindBySceneName(scene.name);
|
||||
// 🔴 WL-816i2 — 들어가겠다고 **요청한** 던전이 우선이다.
|
||||
// 표에서 씬 이름으로만 찾으면(FindBySceneName) 같은 씬을 쓰는 던전 1·3(WL_Dungeon01),
|
||||
// 2·4(WL_Dungeon02) 중 **언제나 앞 줄**이 잡혀, 던전 3 에 들어가도 던전 1 의 스테이지
|
||||
// (몹 3마리 · 보상 배수 1)가 돌았다. 그래서 「다른 던전에 들어가도 전투가 이상하다」가 된다.
|
||||
var dg = WLDungeonSceneSetup.Pending;
|
||||
if (dg == null || dg.enabled_ == 0 || !scene.name.Equals(dg.sceneName))
|
||||
dg = cfg.FindBySceneName(scene.name);
|
||||
if (dg != null)
|
||||
{
|
||||
DungeonLoads++;
|
||||
|
|
@ -388,6 +394,11 @@ namespace WL.Island
|
|||
if (cfg == null || cfg.enabled_ == 0) return;
|
||||
WLDungeonGate.TickAll(cfg);
|
||||
|
||||
// 🔴 WL-816i2 — 재입장 시 전투가 시작되지 않던 것: 죽은 카메라 연출 대상을 걷어낸다.
|
||||
// 매 프레임 · 목록이 비었거나 죽은 항목이 없으면 아무 일도 하지 않는다(근거는 WLIslandCameraRig.cs).
|
||||
if (cfg.fixCamActionTargets != 0)
|
||||
WLDungeonCameraRig.PruneCamActionTargets(MyValue._RealCamera);
|
||||
|
||||
// WL-816i 에러 ② — 투영이 깨진 카메라 감시(자세한 근거는 WLIslandCameraRig.cs)
|
||||
if (cfg.fixDegenerateCameras == 0) return;
|
||||
_guardTimer -= Time.unscaledDeltaTime;
|
||||
|
|
|
|||
|
|
@ -86,6 +86,20 @@ namespace WL.Island
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 던전에서 쓸 카메라 거리(m). WL-816i2 — PD 「던전에서는 카메라를 조금만 더 당기자」.
|
||||
/// 각도·yaw·FOV 는 섬 그대로 두고 **거리만** 던전 전용 값을 쓴다. 0 이하면 섬 값을 그대로 쓴다.
|
||||
/// </summary>
|
||||
public static float DungeonDistance(WLIslandSettings cfg)
|
||||
{
|
||||
if (cfg == null) return 22f;
|
||||
if (DistanceOverride > 0f) return DistanceOverride; // 검증용(프로브)
|
||||
return cfg.dungeonCamDistance > 0f ? cfg.dungeonCamDistance : cfg.camDistance;
|
||||
}
|
||||
|
||||
/// <summary>검증 전용 — 0 보다 크면 그 거리를 쓴다(3단 비교 캡처용 · 실기에는 영향 0).</summary>
|
||||
public static float DistanceOverride = 0f;
|
||||
|
||||
/// <summary>스테이지 진입 시 원본이 쓰는 초기 카메라 방향(MapZoneData.CamRot_Portal) 값.</summary>
|
||||
public static float SolvedYaw(WLIslandSettings cfg)
|
||||
{
|
||||
|
|
@ -112,8 +126,9 @@ namespace WL.Island
|
|||
Save();
|
||||
}
|
||||
|
||||
float dist = DungeonDistance(_cfg); // WL-816i2 — 던전만 조금 더 당긴다(각도·FOV 는 섬 그대로)
|
||||
float camHeight, away, up, rot;
|
||||
if (!Solve(_cfg.camPitch, _cfg.camDistance, _cfg.camYaw, out camHeight, out away, out up, out rot)) return;
|
||||
if (!Solve(_cfg.camPitch, dist, _cfg.camYaw, out camHeight, out away, out up, out rot)) return;
|
||||
|
||||
_rc.cameraHeight = camHeight;
|
||||
_rc.minDistance = away;
|
||||
|
|
@ -148,7 +163,7 @@ namespace WL.Island
|
|||
}
|
||||
|
||||
Applies++;
|
||||
LastApplied = "pitch " + camHeight.ToString("F2") + "° · 거리 " + _cfg.camDistance.ToString("F2") +
|
||||
LastApplied = "pitch " + camHeight.ToString("F2") + "° · 거리 " + dist.ToString("F2") +
|
||||
" m · FOV " + _cfg.camFov.ToString("F1") + " · (RealCamera away " + away.ToString("F4") +
|
||||
" · up " + up.ToString("F4") + " · rotateAround " + rot.ToString("F3") + ")";
|
||||
}
|
||||
|
|
@ -211,6 +226,47 @@ namespace WL.Island
|
|||
public static int Repairs;
|
||||
public static string LastRepair = "";
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────
|
||||
// WL-816i2 — 「재입장하면 전투가 진행되지 않는다」(PD) 의 원인 지점
|
||||
//
|
||||
// 원본 흐름(실측): 전투는 이렇게 **시작**된다.
|
||||
// InGameInfo.StartCam → PCActor.StartCam(PCActor.cs:245)
|
||||
// → LoadMapMgr.Get_PortalPos 콜백 → RealCamera.Set_Target(pc, CamRot_Portal)
|
||||
// → CamStatus = 0 · list_tfCamactionTarget.Add(pc) (RealCamera.cs:84·87)
|
||||
// → LateUpdate 의 CamStatus==0 가지가 목록을 **다 비우면** Start_Game() (RealCamera.cs:212)
|
||||
// → ActorInfo.All_Stop(false) + Time.timeScale + DungeonInfo.Start_Dungeon(true)
|
||||
// 🔴 `list_tfCamactionTarget` 은 원본에 **비우는 곳이 없다**(Add 와 RemoveAt(0) 뿐 · RealCamera.cs:52·122).
|
||||
// 맵을 바꾸면 그 목록의 Transform(이전 맵 PC)은 파괴되는데 항목은 남는다.
|
||||
// 그 상태로 다시 입장하면 CamStatus==0 가지의 첫 줄 `camTarget.position`(RealCamera.cs:197·199)이
|
||||
// **MissingReferenceException** 을 던져 LateUpdate 가 매 프레임 중단된다 →
|
||||
// 목록이 영영 안 비고 → **Start_Game() 이 안 불려 전투가 멈춘 채로 남는다.**
|
||||
// → 원본 0줄 유지를 위해 **죽은 항목만 걷어낸다**. 다 걷어내 비면 지금 대상을 한 개 넣어
|
||||
// 원본이 정상적으로 목록을 소진하고 Start_Game() 에 도달하게 한다(= 첫 입장과 같은 경로).
|
||||
// ─────────────────────────────────────────────────────────────────
|
||||
public static int CamTargetsPruned, CamTargetsRefilled;
|
||||
|
||||
static readonly System.Reflection.FieldInfo F_CamActionList =
|
||||
typeof(RealCamera).GetField("list_tfCamactionTarget",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
/// <summary>죽은 카메라 연출 대상만 걷어낸다. 걷어낸 개수를 돌려준다(정상이면 0 · 아무것도 안 한다).</summary>
|
||||
public static int PruneCamActionTargets(RealCamera rc)
|
||||
{
|
||||
if (rc == null || F_CamActionList == null) return 0;
|
||||
var list = F_CamActionList.GetValue(rc) as System.Collections.Generic.List<Transform>;
|
||||
if (list == null || list.Count == 0) return 0;
|
||||
|
||||
int removed = 0;
|
||||
for (int i = list.Count - 1; i >= 0; i--)
|
||||
if (list[i] == null) { list.RemoveAt(i); removed++; }
|
||||
if (removed == 0) return 0;
|
||||
|
||||
CamTargetsPruned += removed;
|
||||
// 🔴 다 걷어내 비었는데 CamStatus 가 0 이면 원본이 list[0] 에서 터진다 → 지금 대상을 한 개 채워 준다.
|
||||
if (list.Count == 0 && rc.target != null) { list.Add(rc.target); CamTargetsRefilled++; }
|
||||
return removed;
|
||||
}
|
||||
|
||||
/// <summary>투영이 깨진 카메라를 찾아 되살린다. 되살린 수를 돌려준다(정상이면 0 · 로그도 없다).</summary>
|
||||
public static int RepairDegenerateCameras(WLIslandSettings cfg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -328,9 +328,15 @@ namespace WL.Island
|
|||
[Tooltip("섬 카메라 수평 방향(도). 섬은 플레이어를 따라 돌지 않는 고정 구도라 0.")]
|
||||
public float camYaw = 0f;
|
||||
|
||||
[Tooltip("섬 카메라와 대상 사이 거리(m). 섬 실측 = 22 (CinemachineFramingTransposer.m_CameraDistance).")]
|
||||
[Tooltip("섬 카메라와 대상 사이 거리(m). 섬 실측 = 22 (CinemachineFramingTransposer.m_CameraDistance). " +
|
||||
"🔴 섬은 이 값을 쓰지 않는다(FI Cinemachine 이 스스로 잡는다) — 기준 기록용이자 아래 던전 값의 기본값이다.")]
|
||||
public float camDistance = 22f;
|
||||
|
||||
[Tooltip("🔴 **던전 전용** 카메라 거리(m) — WL-816i2 · PD 「던전에서는 카메라를 조금만 더 당기자」. " +
|
||||
"0 이하면 위 섬 값(22)을 그대로 쓴다. 각도 45°·yaw 0°·FOV 60 은 섬과 같게 유지하고 **거리만** 줄인다. " +
|
||||
"섬은 이 값에 전혀 영향받지 않는다.")]
|
||||
public float dungeonCamDistance = 18f;
|
||||
|
||||
[Tooltip("섬 카메라 화각(도). 섬 실측 = 60 · 원근 투영.")]
|
||||
public float camFov = 60f;
|
||||
|
||||
|
|
@ -354,6 +360,12 @@ namespace WL.Island
|
|||
[Tooltip("위 감시 주기(초).")]
|
||||
public float cameraGuardInterval = 0.5f;
|
||||
|
||||
[Tooltip("1 이면 `RealCamera.list_tfCamactionTarget` 에 남은 **죽은 연출 대상**을 걷어낸다(WL-816i2). " +
|
||||
"이게 남아 있으면 재입장 때 RealCamera.LateUpdate 가 매 프레임 예외로 끊겨 " +
|
||||
"`Start_Game()`(= ActorInfo.All_Stop(false) · DungeonInfo.Start_Dungeon)이 불리지 않아 **전투가 시작되지 않는다**. " +
|
||||
"0 이면 무동작(= 816i 까지의 동작).")]
|
||||
public int fixCamActionTargets = 1;
|
||||
|
||||
// ───────────────────────────────── 던전 표
|
||||
[Header("던전 표 — 한 줄 = 던전 하나")]
|
||||
public WLDungeonDef[] dungeons = new WLDungeonDef[0];
|
||||
|
|
|
|||
Loading…
Reference in New Issue