443 lines
23 KiB
C#
443 lines
23 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
|
// WLIslandFlowV2.cs — WL-816zc 「섬 초기 플로우 v2」
|
|
//
|
|
// PD 원문(2026-09-15)
|
|
// 「원본 에셋과 같이 섬이 확장되는 방식과 순서는 유지하되, 내가 수정한 초기 플로우만 바뀌어야 해.
|
|
// <최초 시작 시 밭 생성은 보류>
|
|
// ① 캠프파이어 설치 → 상인 설치 → 사과 나무 설치 → 던전 생성
|
|
// ② 전투 승리 후 섬 확장 노드 추가 → 이후 원본 에셋의 확장 순서대로 확장시켜야 함.」
|
|
//
|
|
// ■ 발판은 **한 번에 하나**다. 값을 치르면 그 자리에 그 단계의 설치물이 남고, 다음 단계의 발판이 선다.
|
|
// 순서·문구·가격·자리·설치물은 전부 `WLIslandSettings.flowSteps[]` 값이다(코드 수정 0 · C45).
|
|
// ■ 어디까지 왔는지는 PlayerPrefs 키 **1개**(`flowStepPrefsKey`)로만 센다.
|
|
// 섬으로 돌아오면 이 숫자를 보고 이미 치른 설치물을 다시 놓는다(세이브 복원).
|
|
// ■ 원본 섬 확장 가격판(FI `Purchaser`)은 **첫 던전 승리 전까지 숨긴다**(렌더러·콜라이더만 끈다).
|
|
// 승리하면 그대로 다시 켜지고, 이후 확장 순서는 **FI 원본**(`Island.Constraint`)이 정한다 — 우리는 켜고 끄기만.
|
|
// ■ 되돌리기 = `flowV2Enabled = 0` → 지금까지의 「던전 발판 4개」 방식 그대로.
|
|
//
|
|
// 🔴 원본(Assets/FarmingIsland/** · Assets/Script/**)은 한 줄도 고치지 않는다 — 인스턴스만 만든다.
|
|
// 🔴 Debug.LogError / Debug.LogException 을 쓰지 않는다(ErrorLogHookManager 가 플레이어 팝업을 띄운다).
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using FIPurchaser = CryingSnow.FarmingIsland.Purchaser;
|
|
|
|
namespace WL.Island
|
|
{
|
|
/// <summary>초기 플로우(단계 표) 진행 + 설치물 배치. 정적 · 씬에 남는 상태 없음.</summary>
|
|
public static class WLIslandFlowV2
|
|
{
|
|
const string RootName = "~WL_FlowInstalls";
|
|
|
|
// ── 진단(프로브·보고가 읽는다 · 실측만)
|
|
public static int InstallsMade;
|
|
public static int LastStep;
|
|
public static string LastLog = "";
|
|
|
|
static readonly List<GameObject> s_made = new List<GameObject>(8);
|
|
|
|
/// <summary>이 플로우가 지금 동작 중인가(꺼져 있으면 기존 발판 방식이 그대로 돈다).</summary>
|
|
public static bool Active(WLIslandSettings cfg)
|
|
{
|
|
return cfg != null && cfg.gateFlowEnabled != 0 && cfg.flowV2Enabled != 0 && StepCount(cfg) > 0;
|
|
}
|
|
|
|
/// <summary>켜져 있는 단계 수.</summary>
|
|
public static int StepCount(WLIslandSettings cfg)
|
|
{
|
|
if (cfg == null || cfg.flowSteps == null) return 0;
|
|
int n = 0;
|
|
for (int i = 0; i < cfg.flowSteps.Length; i++)
|
|
if (cfg.flowSteps[i] != null && cfg.flowSteps[i].enabled_ != 0) n++;
|
|
return n;
|
|
}
|
|
|
|
/// <summary>켜져 있는 것 중 n 번째 단계(없으면 null).</summary>
|
|
public static WLFlowStepDef Nth(WLIslandSettings cfg, int n)
|
|
{
|
|
if (cfg == null || cfg.flowSteps == null || n < 0) return null;
|
|
int k = 0;
|
|
for (int i = 0; i < cfg.flowSteps.Length; i++)
|
|
{
|
|
var s = cfg.flowSteps[i];
|
|
if (s == null || s.enabled_ == 0) continue;
|
|
if (k == n) return s;
|
|
k++;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>지금까지 치른 단계 수(PlayerPrefs 1키 · FI 세이브를 건드리지 않는다).</summary>
|
|
public static int Step(WLIslandSettings cfg)
|
|
{
|
|
if (cfg == null || string.IsNullOrEmpty(cfg.flowStepPrefsKey)) return 0;
|
|
return Mathf.Max(0, PlayerPrefs.GetInt(cfg.flowStepPrefsKey, 0));
|
|
}
|
|
|
|
public static void SetStep(WLIslandSettings cfg, int n)
|
|
{
|
|
if (cfg == null || string.IsNullOrEmpty(cfg.flowStepPrefsKey)) return;
|
|
PlayerPrefs.SetInt(cfg.flowStepPrefsKey, Mathf.Max(0, n));
|
|
PlayerPrefs.Save();
|
|
LastStep = Mathf.Max(0, n);
|
|
}
|
|
|
|
/// <summary>n 번째 단계의 발판 자리(표가 가리킨 던전 줄의 좌표 · -1 이면 밭 구역 중심).</summary>
|
|
public static Vector3 PosFor(WLIslandSettings cfg, int n)
|
|
{
|
|
if (cfg == null) return Vector3.zero;
|
|
|
|
var s = Nth(cfg, n);
|
|
Vector3 p;
|
|
if (s == null) p = cfg.platformPosition;
|
|
else if (s.platformFromDungeonRow >= 0)
|
|
{
|
|
var d = cfg.DungeonRow(s.platformFromDungeonRow);
|
|
p = d != null ? d.platformPosition : s.platformPosition;
|
|
}
|
|
else if (cfg.platformUseFarmPosition != 0 && WLIslandGateFlow.HaveFarmCenter) p = WLIslandGateFlow.FarmCenter;
|
|
else p = s.platformPosition;
|
|
|
|
p += cfg.platformOffset;
|
|
return WLIslandGateFlow.SnapToGround(cfg, p);
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────────────
|
|
// 발판 + 설치물 다시 그리기 (섬 준비 직후 · 지불 직후 둘 다 여기로)
|
|
// ─────────────────────────────────────────────────────────────────
|
|
public static void Refresh(WLIslandSettings cfg, Scene scene)
|
|
{
|
|
if (!Active(cfg)) return;
|
|
|
|
int step = Step(cfg);
|
|
int total = StepCount(cfg);
|
|
LastStep = step;
|
|
|
|
// ① 이미 치른 단계의 설치물을 다시 놓는다(세이브 복원 · 매번 지우고 새로 놓는다).
|
|
ClearInstalls();
|
|
InstallsMade = 0;
|
|
for (int i = 0; i < step && i < total; i++)
|
|
if (Install(cfg, scene, Nth(cfg, i), PosFor(cfg, i))) InstallsMade++;
|
|
|
|
// 캠프 장식은 전용 코드가 자기 자리(1단계 자리)에 놓는다.
|
|
WLIslandCampDecor.Refresh(cfg, scene);
|
|
|
|
// ② 다음 발판 1개
|
|
if (WLGoldPlatform.Instance != null)
|
|
{
|
|
Object.Destroy(WLGoldPlatform.Instance.gameObject);
|
|
WLGoldPlatform.Instance = null;
|
|
}
|
|
|
|
if (step >= total)
|
|
{
|
|
LastLog = "발판 없음 — 초기 플로우 " + step + "/" + total + " 단계 완료";
|
|
WLIslandBridge.Log(cfg, LastLog);
|
|
return;
|
|
}
|
|
|
|
var next = Nth(cfg, step);
|
|
Vector3 pos = PosFor(cfg, step);
|
|
string label = string.Format(cfg.flowLabelFormat, next.label, next.price);
|
|
|
|
// 🔴 값을 치른 자리에 다음 발판이 곧바로 생기면 **가만히 서 있기만 해도** 연달아 팔린다(816g 실측).
|
|
// FI 섬 확장처럼 「한 번 내려왔다가 다시 올라오기」를 요구한다.
|
|
var runner = WLIslandBridge.Runner;
|
|
if (cfg.platformRequireStepOff != 0 && runner != null && WLIslandGateFlow.PlayerInRange(cfg, pos))
|
|
{
|
|
runner.StartCoroutine(Co_SpawnWhenClear(cfg, scene, pos, next.price, step, label, total));
|
|
LastLog = "발판 대기 — 자리에서 내려오면 " + (step + 1) + "단계 「" + next.label + "」 발판을 놓는다";
|
|
WLIslandBridge.Log(cfg, LastLog);
|
|
return;
|
|
}
|
|
|
|
Spawn(cfg, scene, pos, next.price, step, label, total);
|
|
}
|
|
|
|
static void Spawn(WLIslandSettings cfg, Scene scene, Vector3 pos, int price, int step, string label, int total)
|
|
{
|
|
var p = WLGoldPlatform.Create(cfg, scene, pos, price, step, label);
|
|
if (p != null) { WLIslandGateFlow.PlatformsMade++; WLIslandGateFlow.LastPlatformPos = pos; }
|
|
LastLog = "플로우 발판 배치 — " + (step + 1) + "/" + total + " 「" + label.Replace("\n", " ") +
|
|
"」 @ " + pos.ToString("F2");
|
|
WLIslandBridge.Log(cfg, LastLog);
|
|
}
|
|
|
|
static IEnumerator Co_SpawnWhenClear(WLIslandSettings cfg, Scene scene, Vector3 pos,
|
|
int price, int step, string label, int total)
|
|
{
|
|
float t = 0f;
|
|
while (t < cfg.platformStepOffTimeoutSeconds && WLIslandGateFlow.PlayerInRange(cfg, pos))
|
|
{
|
|
t += Time.unscaledDeltaTime;
|
|
yield return null;
|
|
}
|
|
if (WLGoldPlatform.Instance != null) yield break; // 그 사이 다른 경로로 이미 생겼다
|
|
Spawn(cfg, scene, pos, price, step, label, total);
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────────────
|
|
// 지불 완료 → 그 단계의 설치물이 그 자리에 남는다
|
|
// ─────────────────────────────────────────────────────────────────
|
|
public static void OnPaid(WLIslandSettings cfg, Vector3 platformPos)
|
|
{
|
|
if (!Active(cfg)) return;
|
|
|
|
int step = Step(cfg);
|
|
int total = StepCount(cfg);
|
|
if (step >= total) return;
|
|
|
|
var s = Nth(cfg, step);
|
|
SetStep(cfg, step + 1);
|
|
|
|
var scene = SceneManager.GetSceneByName(cfg.islandSceneName);
|
|
if (!scene.IsValid() || !scene.isLoaded) scene = SceneManager.GetActiveScene();
|
|
|
|
// 던전 단계 = 원래의 해금 카운터도 같이 올린다 → 섬 복귀 시 `SpawnGates` 가 입구를 다시 놓는다.
|
|
if (s != null && s.kind == "dungeon")
|
|
{
|
|
WLIslandGateFlow.SetUnlockedCount(cfg, DungeonStepsDone(cfg, step + 1));
|
|
WLIslandGateFlow.Unlocks++;
|
|
}
|
|
|
|
LastLog = "🔴 지불 완료 — " + (step + 1) + "/" + total + " 「" + (s != null ? s.label : "?") +
|
|
"」 · 이 자리(" + platformPos.ToString("F1") + ")의 발판은 영영 사라진다";
|
|
WLIslandBridge.Log(cfg, LastLog);
|
|
|
|
Refresh(cfg, scene);
|
|
}
|
|
|
|
/// <summary>치른 단계 중 던전 단계가 몇 개인지(= 열려 있어야 할 던전 수).</summary>
|
|
static int DungeonStepsDone(WLIslandSettings cfg, int stepsDone)
|
|
{
|
|
int n = 0;
|
|
for (int i = 0; i < stepsDone; i++)
|
|
{
|
|
var s = Nth(cfg, i);
|
|
if (s != null && s.kind == "dungeon") n++;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────────────
|
|
// 설치물 하나
|
|
// ─────────────────────────────────────────────────────────────────
|
|
static bool Install(WLIslandSettings cfg, Scene scene, WLFlowStepDef s, Vector3 pos)
|
|
{
|
|
if (cfg == null || s == null) return false;
|
|
|
|
if (s.kind == "camp") return false; // 캠프는 WLIslandCampDecor 가 놓는다
|
|
|
|
if (s.kind == "dungeon")
|
|
{
|
|
var d = cfg.DungeonRow(s.dungeonRow);
|
|
if (d != null) WLIslandBridge.SpawnOneGate(cfg, d, scene); // 이미 있으면 안에서 건너뛴다
|
|
// 2026-09-16 PD 「던전 개방 이후에는 기존 에셋과 동일한 순서로 확장 노드」 — 던전 노드가 열리면 원본 확장 가격판을 개방한다.
|
|
if (d != null && cfg.expansionUnlockOnDungeonOpen != 0) WLIslandExpansionGate.Unlock(cfg);
|
|
return d != null;
|
|
}
|
|
|
|
// kind = prefab
|
|
if (string.IsNullOrEmpty(s.prefabPath)) return false;
|
|
var root = EnsureRoot(scene);
|
|
var go = SpawnPrefab(cfg, s.prefabPath, root.transform, pos, s.yaw, s.scale, s.keepCollider != 0);
|
|
if (go == null) return false;
|
|
|
|
// 덧붙일 것(예: 좌판에 상인이 안 들어 있을 때만 상인을 넣는다) — 원본 프리팹 그대로, 설치물의 자식으로.
|
|
if (!string.IsNullOrEmpty(s.extraPrefabPath) && !HasComponentNamed(go, s.extraSkipIfComponent))
|
|
{
|
|
var rot = Quaternion.Euler(0f, s.yaw, 0f);
|
|
SpawnPrefab(cfg, s.extraPrefabPath, go.transform, pos + rot * s.extraOffset,
|
|
s.yaw, s.scale, s.keepCollider != 0);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static GameObject EnsureRoot(Scene scene)
|
|
{
|
|
for (int i = 0; i < s_made.Count; i++)
|
|
if (s_made[i] != null && s_made[i].name == RootName) return s_made[i];
|
|
|
|
var root = new GameObject(RootName);
|
|
if (scene.IsValid() && scene.isLoaded) SceneManager.MoveGameObjectToScene(root, scene);
|
|
s_made.Add(root);
|
|
return root;
|
|
}
|
|
|
|
static GameObject SpawnPrefab(WLIslandSettings cfg, string path, Transform parent, Vector3 pos,
|
|
float yaw, float scale, bool keepCollider)
|
|
{
|
|
var prefab = WLIslandAssets.LoadPrefab(path);
|
|
if (prefab == null) { WLIslandBridge.Log(cfg, "플로우 설치물 프리팹 없음 — " + path); return null; }
|
|
|
|
// 🔴 부모를 주고 만든다 — FI 스크립트(예: `Merchant.Awake` 의 `GetComponentInParent<Stall>()`)가
|
|
// Awake 시점에 부모를 볼 수 있어야 한다. 부모의 씬에 그대로 들어가므로 씬 이동도 필요 없다.
|
|
var go = Object.Instantiate(prefab, parent);
|
|
go.name = "~WL_Flow_" + prefab.name;
|
|
go.transform.position = Snap(cfg, pos);
|
|
go.transform.rotation = Quaternion.Euler(0f, yaw, 0f);
|
|
float sc = scale > 0.001f ? scale : 1f;
|
|
go.transform.localScale = prefab.transform.localScale * sc;
|
|
|
|
if (!keepCollider)
|
|
{
|
|
// 장식 = 이동 방해 0 · NavMesh 재베이크 없음(816y 캠프 장식과 같은 원칙).
|
|
var cols = go.GetComponentsInChildren<Collider>(true);
|
|
for (int i = 0; i < cols.Length; i++) if (cols[i] != null) cols[i].enabled = false;
|
|
}
|
|
return go;
|
|
}
|
|
|
|
static bool HasComponentNamed(GameObject go, string typeName)
|
|
{
|
|
if (go == null || string.IsNullOrEmpty(typeName)) return false;
|
|
var comps = go.GetComponentsInChildren<Component>(true);
|
|
for (int i = 0; i < comps.Length; i++)
|
|
if (comps[i] != null && comps[i].GetType().Name == typeName) return true;
|
|
return false;
|
|
}
|
|
|
|
static Vector3 Snap(WLIslandSettings cfg, Vector3 p)
|
|
{
|
|
if (cfg.platformSnapToGround == 0) return p;
|
|
// 2026-09-16 PD 「상인이 공중에 떠 있다」 실측: 재훑기마다 다시 스냅하는데, 광선이 **방금 놓은 설치물 자신의 콜라이더**(좌판 3 m 상자) 위를
|
|
// 맞혀 한 번 훑을 때마다 3 m 씩 떠올랐다(y 3.00 · 콜라이더 위 6.00 실측). 설치물(`~WL_FlowInstalls` 밑)은 건너뛰고,
|
|
// 요청 높이보다 `platformSnapMaxRise` 이상 위로 솟는 맞힘(다른 소품 위)도 무시한다 — 설치물은 타일 윗면에 놓는 것이 목적이다.
|
|
var hits = Physics.RaycastAll(new Vector3(p.x, p.y + 30f, p.z), Vector3.down, 60f, ~0, QueryTriggerInteraction.Ignore);
|
|
float best = float.NaN;
|
|
for (int i = 0; i < hits.Length; i++)
|
|
{
|
|
var c = hits[i].collider; if (c == null) continue;
|
|
var t = c.transform; bool ours = false;
|
|
while (t != null) { if (t.name == RootName) { ours = true; break; } t = t.parent; }
|
|
if (ours) continue;
|
|
float y = hits[i].point.y;
|
|
if (y > p.y + Mathf.Max(0f, cfg.platformSnapMaxRise)) continue;
|
|
if (float.IsNaN(best) || y > best) best = y;
|
|
}
|
|
return float.IsNaN(best) ? p : new Vector3(p.x, best, p.z);
|
|
}
|
|
|
|
public static void ClearInstalls()
|
|
{
|
|
for (int i = 0; i < s_made.Count; i++)
|
|
if (s_made[i] != null) Object.Destroy(s_made[i]);
|
|
s_made.Clear();
|
|
}
|
|
}
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
// 원본 섬 확장 노드 — 첫 던전 승리 전까지 숨김
|
|
//
|
|
// 🔴 FI 의 확장 **순서·조건은 건드리지 않는다**(`IslandManager.RefreshIsland` · `Island.Constraint` 그대로).
|
|
// 우리는 이미 만들어진 가격판의 **렌더러·콜라이더만** 껐다 켠다 = FI 세이브·격자에 흔적 0.
|
|
// `SetActive(false)` 를 쓰지 않는 이유는 816g 와 같다(꺼진 오브젝트에서 코루틴이 시작되면 에러).
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
public static class WLIslandExpansionGate
|
|
{
|
|
// ── 진단(프로브·보고가 읽는다 · 실측만)
|
|
public static int PurchasersHidden;
|
|
public static string LastLog = "";
|
|
|
|
static readonly List<Renderer> s_rends = new List<Renderer>(64);
|
|
static readonly List<Collider> s_cols = new List<Collider>(64);
|
|
|
|
/// <summary>첫 던전 승리를 이미 했는가(기능이 꺼져 있으면 항상 true = 원본 그대로).</summary>
|
|
public static bool IsUnlocked(WLIslandSettings cfg)
|
|
{
|
|
if (cfg == null || cfg.expansionAfterFirstWin == 0) return true;
|
|
if (string.IsNullOrEmpty(cfg.expansionUnlockPrefsKey)) return true;
|
|
return PlayerPrefs.GetInt(cfg.expansionUnlockPrefsKey, 0) != 0;
|
|
}
|
|
|
|
/// <summary>전투 승리 시 1회 — 이후 섬 확장은 FI 원본 순서대로 열린다.</summary>
|
|
public static void Unlock(WLIslandSettings cfg)
|
|
{
|
|
if (cfg == null || cfg.expansionAfterFirstWin == 0) return;
|
|
if (string.IsNullOrEmpty(cfg.expansionUnlockPrefsKey)) return;
|
|
if (PlayerPrefs.GetInt(cfg.expansionUnlockPrefsKey, 0) != 0) return;
|
|
|
|
PlayerPrefs.SetInt(cfg.expansionUnlockPrefsKey, 1);
|
|
PlayerPrefs.Save();
|
|
LastLog = "🔴 첫 전투 승리 — 원본 섬 확장 노드 개방(이후 순서는 FI 원본이 정한다)";
|
|
WLIslandBridge.Log(cfg, LastLog);
|
|
}
|
|
|
|
/// <summary>섬이 준비될 때마다 1회 — 아직 승리 전이면 원본 가격판을 숨기고, 승리했으면 그대로 둔다.</summary>
|
|
public static void Apply(WLIslandSettings cfg, Scene scene)
|
|
{
|
|
if (cfg == null || cfg.gateFlowEnabled == 0 || cfg.expansionAfterFirstWin == 0) return;
|
|
|
|
if (IsUnlocked(cfg))
|
|
{
|
|
Restore();
|
|
LastLog = "확장 노드 표시 — 첫 승리 완료(FI 원본 순서)";
|
|
WLIslandBridge.Log(cfg, LastLog);
|
|
return;
|
|
}
|
|
|
|
HideNow(cfg, scene);
|
|
|
|
// FI 는 세이브 복원·이웃 갱신 시점에 가격판을 **나중에** 만들기도 한다 — 잠시 더 훑는다.
|
|
var runner = WLIslandBridge.Runner;
|
|
if (runner != null && cfg.expansionHideSeconds > 0f)
|
|
runner.StartCoroutine(Co_Guard(cfg, scene));
|
|
}
|
|
|
|
public static int HideNow(WLIslandSettings cfg, Scene scene)
|
|
{
|
|
int n = 0;
|
|
var all = Object.FindObjectsByType<FIPurchaser>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
|
for (int i = 0; i < all.Length; i++)
|
|
{
|
|
var p = all[i];
|
|
if (p == null) continue;
|
|
// 2026-09-15 Lead 실측 — FI 가 Instantiate 한 `Purchaser(Clone)` 은 섬 씬이 아니라 **활성 씬(InGame)** 에 생긴다 → 활성 씬도 허용
|
|
if (scene.IsValid() && p.gameObject.scene != scene && p.gameObject.scene != SceneManager.GetActiveScene()) continue;
|
|
if (p.GetComponentInParent<WLGoldPlatform>() != null) continue; // 우리 발판은 건드리지 않는다
|
|
|
|
var rends = p.GetComponentsInChildren<Renderer>(true);
|
|
for (int r = 0; r < rends.Length; r++)
|
|
if (rends[r] != null && rends[r].enabled) { rends[r].enabled = false; s_rends.Add(rends[r]); n++; }
|
|
|
|
var cols = p.GetComponentsInChildren<Collider>(true);
|
|
for (int c = 0; c < cols.Length; c++)
|
|
if (cols[c] != null && cols[c].enabled) { cols[c].enabled = false; s_cols.Add(cols[c]); }
|
|
}
|
|
if (n > 0)
|
|
{
|
|
PurchasersHidden += n;
|
|
LastLog = "원본 확장 가격판 숨김 — 렌더러 " + n + "개(첫 던전 승리 전)";
|
|
WLIslandBridge.Log(cfg, LastLog);
|
|
}
|
|
return n;
|
|
}
|
|
|
|
static IEnumerator Co_Guard(WLIslandSettings cfg, Scene scene)
|
|
{
|
|
float wait = Mathf.Max(0.1f, cfg.expansionHideInterval);
|
|
float t = 0f;
|
|
while (t < cfg.expansionHideSeconds)
|
|
{
|
|
yield return new WaitForSeconds(wait);
|
|
t += wait;
|
|
if (cfg == null || cfg.expansionAfterFirstWin == 0) yield break;
|
|
if (IsUnlocked(cfg)) { Restore(); yield break; }
|
|
HideNow(cfg, scene);
|
|
}
|
|
}
|
|
|
|
/// <summary>우리가 껐던 것만 되돌린다(FI 가 스스로 끈 것은 손대지 않는다).</summary>
|
|
public static void Restore()
|
|
{
|
|
for (int i = 0; i < s_rends.Count; i++) if (s_rends[i] != null) s_rends[i].enabled = true;
|
|
for (int i = 0; i < s_cols.Count; i++) if (s_cols[i] != null) s_cols[i].enabled = true;
|
|
s_rends.Clear();
|
|
s_cols.Clear();
|
|
}
|
|
}
|
|
}
|