diff --git a/Assets/WL/Island/Resources/WL/WLIslandSettings.asset b/Assets/WL/Island/Resources/WL/WLIslandSettings.asset
index f77790e6c..f73ded1a9 100644
--- a/Assets/WL/Island/Resources/WL/WLIslandSettings.asset
+++ b/Assets/WL/Island/Resources/WL/WLIslandSettings.asset
@@ -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
diff --git a/Assets/WL/Island/WLIslandBridge.cs b/Assets/WL/Island/WLIslandBridge.cs
index efd871b9d..14631f09d 100644
--- a/Assets/WL/Island/WLIslandBridge.cs
+++ b/Assets/WL/Island/WLIslandBridge.cs
@@ -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;
diff --git a/Assets/WL/Island/WLIslandCameraRig.cs b/Assets/WL/Island/WLIslandCameraRig.cs
index a815d9fbc..f7728c666 100644
--- a/Assets/WL/Island/WLIslandCameraRig.cs
+++ b/Assets/WL/Island/WLIslandCameraRig.cs
@@ -86,6 +86,20 @@ namespace WL.Island
return true;
}
+ ///
+ /// λμ μμ μΈ μΉ΄λ©λΌ 거리(m). WL-816i2 β PD γλμ μμλ μΉ΄λ©λΌλ₯Ό μ‘°κΈλ§ λ λΉκΈ°μγ.
+ /// κ°λΒ·yawΒ·FOV λ μ¬ κ·Έλλ‘ λκ³ **거리λ§** λμ μ μ© κ°μ μ΄λ€. 0 μ΄νλ©΄ μ¬ κ°μ κ·Έλλ‘ μ΄λ€.
+ ///
+ public static float DungeonDistance(WLIslandSettings cfg)
+ {
+ if (cfg == null) return 22f;
+ if (DistanceOverride > 0f) return DistanceOverride; // κ²μ¦μ©(νλ‘λΈ)
+ return cfg.dungeonCamDistance > 0f ? cfg.dungeonCamDistance : cfg.camDistance;
+ }
+
+ /// κ²μ¦ μ μ© β 0 λ³΄λ€ ν¬λ©΄ κ·Έ 거리λ₯Ό μ΄λ€(3λ¨ λΉκ΅ μΊ‘μ²μ© Β· μ€κΈ°μλ μν₯ 0).
+ public static float DistanceOverride = 0f;
+
/// μ€ν
μ΄μ§ μ§μ
μ μλ³Έμ΄ μ°λ μ΄κΈ° μΉ΄λ©λΌ λ°©ν₯(MapZoneData.CamRot_Portal) κ°.
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);
+
+ /// μ£½μ μΉ΄λ©λΌ μ°μΆ λμλ§ κ±·μ΄λΈλ€. κ±·μ΄λΈ κ°μλ₯Ό λλ €μ€λ€(μ μμ΄λ©΄ 0 Β· μ무κ²λ μ νλ€).
+ 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;
+ 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;
+ }
+
/// ν¬μμ΄ κΉ¨μ§ μΉ΄λ©λΌλ₯Ό μ°Ύμ λμ΄λ¦°λ€. λμ΄λ¦° μλ₯Ό λλ €μ€λ€(μ μμ΄λ©΄ 0 Β· λ‘κ·Έλ μλ€).
public static int RepairDegenerateCameras(WLIslandSettings cfg)
{
diff --git a/Assets/WL/Island/WLIslandSettings.cs b/Assets/WL/Island/WLIslandSettings.cs
index c7c9c1f47..ce4655aa7 100644
--- a/Assets/WL/Island/WLIslandSettings.cs
+++ b/Assets/WL/Island/WLIslandSettings.cs
@@ -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];