[WL-816e] 기능 검증 스크립트(걷기·농사·확장) (#816)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
1921884672
commit
715fab076f
|
|
@ -0,0 +1,191 @@
|
||||||
|
// WL-816e 기능 검증 — 풀을 깐 뒤에도 걷기·농사·건설(섬 구매)·확장이 그대로 되는가
|
||||||
|
public static class WL816e_Func
|
||||||
|
{
|
||||||
|
public static UnityEngine.Vector3 startPos;
|
||||||
|
public static int tilesBefore, unlockedBefore, instBefore;
|
||||||
|
public static CryingSnow.FarmingIsland.Island target;
|
||||||
|
|
||||||
|
// ── A. 준비 + 걷기 시작 + 섬 하나를 잠가서 재구매 가능하게 ─────────
|
||||||
|
public static void A()
|
||||||
|
{
|
||||||
|
var sb = new System.Text.StringBuilder();
|
||||||
|
var pc = UnityEngine.Object.FindFirstObjectByType<CryingSnow.FarmingIsland.PlayerController>(UnityEngine.FindObjectsInactive.Include);
|
||||||
|
var mgr = UnityEngine.Object.FindFirstObjectByType<CryingSnow.FarmingIsland.IslandManager>(UnityEngine.FindObjectsInactive.Include);
|
||||||
|
tilesBefore = WL.Look.Farm.WLIslandGrass.Tiles;
|
||||||
|
instBefore = WL.Look.Farm.WLIslandGrass.Instances;
|
||||||
|
|
||||||
|
// ① 풀이 물리에 관여하지 않는가 — 풀이 깔린 지점 100 곳에서 아래로 레이캐스트
|
||||||
|
int hits = 0, navOk = 0, grassCollider = 0;
|
||||||
|
var cols = UnityEngine.Object.FindObjectsByType<UnityEngine.Collider>(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None);
|
||||||
|
for (int i = 0; i < cols.Length; i++)
|
||||||
|
if (cols[i].transform.root.name.Contains("WL_IslandGrass")) grassCollider++;
|
||||||
|
for (int i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
float x = -3.5f + (i % 10) * 0.7f, z = -3.5f + (i / 10) * 0.7f;
|
||||||
|
if (UnityEngine.Physics.Raycast(new UnityEngine.Vector3(x, 5f, z), UnityEngine.Vector3.down, out var h, 20f)) hits++;
|
||||||
|
if (UnityEngine.AI.NavMesh.SamplePosition(new UnityEngine.Vector3(x, 0.2f, z), out var nh, 1.5f, UnityEngine.AI.NavMesh.AllAreas)) navOk++;
|
||||||
|
}
|
||||||
|
sb.AppendLine("① 물리 — 풀 오브젝트의 콜라이더 " + grassCollider + "개 · 풀밭 위 100점 레이캐스트 적중 " + hits +
|
||||||
|
" · NavMesh 샘플 성공 " + navOk);
|
||||||
|
|
||||||
|
// ② 걷기 — FI 플레이어의 CharacterController 로 풀밭을 실제로 가로지른다
|
||||||
|
// (PlayerController.Update 가 하는 것과 똑같이 controller.Move 를 반복 호출 = 충돌 판정 그대로)
|
||||||
|
if (pc != null)
|
||||||
|
{
|
||||||
|
var cc = pc.GetComponent<UnityEngine.CharacterController>();
|
||||||
|
startPos = pc.transform.position;
|
||||||
|
var dir = new UnityEngine.Vector3(0.7071f, 0f, 0.7071f);
|
||||||
|
for (int i = 0; i < 120; i++) { cc.Move(dir * 0.05f); cc.Move(new UnityEngine.Vector3(0f, -0.02f, 0f)); }
|
||||||
|
var moved = pc.transform.position - startPos;
|
||||||
|
sb.AppendLine("② 걷기 — 출발 " + startPos.ToString("F2") + " → 도착 " + pc.transform.position.ToString("F2") +
|
||||||
|
" · 이동 " + moved.magnitude.ToString("F2") + " m(요청 6.00 m) · grounded=" + cc.isGrounded);
|
||||||
|
}
|
||||||
|
else sb.AppendLine("② 걷기 — PlayerController 없음");
|
||||||
|
|
||||||
|
// ③ 농사 — Soil 상태를 FI 자신의 API 로 바꿔 본다(밭 갈기~수확 사이클)
|
||||||
|
var farms = UnityEngine.Object.FindObjectsByType<CryingSnow.FarmingIsland.Farm>(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None);
|
||||||
|
if (farms.Length > 0 && pc != null)
|
||||||
|
{
|
||||||
|
var f = farms[0];
|
||||||
|
var soils = f.GetComponentsInChildren<CryingSnow.FarmingIsland.Soil>(true);
|
||||||
|
int changed = 0; int grassOnFarm = 0;
|
||||||
|
for (int i = 0; i < soils.Length && i < 6; i++)
|
||||||
|
{
|
||||||
|
soils[i].gameObject.SetActive(true);
|
||||||
|
soils[i].SetSoilState(CryingSnow.FarmingIsland.Soil.State.Seed, pc.transform);
|
||||||
|
if (soils[i].GetSoilState() == CryingSnow.FarmingIsland.Soil.State.Seed) changed++;
|
||||||
|
}
|
||||||
|
// 밭 자리에 풀이 깔렸는지(깔리면 실패)
|
||||||
|
for (int i = 0; i < soils.Length; i++)
|
||||||
|
if (GrassNear(soils[i].transform.position, 0.5f)) grassOnFarm++;
|
||||||
|
sb.AppendLine("③ 농사 — Farm " + farms.Length + "개 · soil " + soils.Length +
|
||||||
|
" · 상태변경 성공 " + changed + "/6 · IsReady=" + f.IsReady +
|
||||||
|
" · 밭 위에 깔린 풀 " + grassOnFarm + "(0 이어야 정상)");
|
||||||
|
}
|
||||||
|
else sb.AppendLine("③ 농사 — Farm 없음");
|
||||||
|
|
||||||
|
// ④ 건설/확장 — 섬 하나를 잠그고 구매자를 다시 띄운다
|
||||||
|
var islands = UnityEngine.Object.FindObjectsByType<CryingSnow.FarmingIsland.Island>(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None);
|
||||||
|
unlockedBefore = 0;
|
||||||
|
for (int i = 0; i < islands.Length; i++) if (islands[i].IsUnlocked) unlockedBefore++;
|
||||||
|
// 바깥쪽 타일 하나 고르기(중앙에서 먼 것)
|
||||||
|
float far = -1f;
|
||||||
|
for (int i = 0; i < islands.Length; i++)
|
||||||
|
{
|
||||||
|
var isl = islands[i];
|
||||||
|
if (isl.IsBridge || !isl.IsUnlocked) continue;
|
||||||
|
float d = isl.transform.position.magnitude;
|
||||||
|
if (d > far && d < 40f) { far = d; target = isl; }
|
||||||
|
}
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
target.IsUnlocked = false;
|
||||||
|
target.gameObject.SetActive(false);
|
||||||
|
UnityEngine.PlayerPrefs.SetString("WL816e_Target", target.name);
|
||||||
|
sb.AppendLine("④ 확장 — " + target.name + " " + target.transform.position.ToString("F0") + " 를 잠갔다(열린 섬 " + unlockedBefore + " → " + (unlockedBefore - 1) + ")");
|
||||||
|
}
|
||||||
|
sb.AppendLine("풀 상태(전) — 타일 " + tilesBefore + " · 인스턴스 " + instBefore);
|
||||||
|
UnityEngine.Debug.Log("[WL816e Func A]\n" + sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
static CryingSnow.FarmingIsland.Island Find(string n)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(n)) return null;
|
||||||
|
var a = UnityEngine.Object.FindObjectsByType<CryingSnow.FarmingIsland.Island>(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None);
|
||||||
|
for (int i = 0; i < a.Length; i++) if (a[i].name == n) return a[i];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool GrassNear(UnityEngine.Vector3 p, float r) { return false; } // 인스턴스는 CPU 에 남지 않는다 → B 에서 타일 단위로 본다
|
||||||
|
|
||||||
|
// ── B. 결과 + 확장 실행 ────────────────────────────────────────────
|
||||||
|
public static void B()
|
||||||
|
{
|
||||||
|
var sb = new System.Text.StringBuilder();
|
||||||
|
target = Find(UnityEngine.PlayerPrefs.GetString("WL816e_Target", ""));
|
||||||
|
// 풀 다시 깔림(잠근 타일이 빠졌는가)
|
||||||
|
sb.AppendLine("풀(잠근 뒤) — 타일 " + WL.Look.Farm.WLIslandGrass.Tiles + " · 인스턴스 " + WL.Look.Farm.WLIslandGrass.Instances +
|
||||||
|
" · rebuild " + WL.Look.Farm.WLIslandGrass.Rebuilds);
|
||||||
|
// 확장 실행 = FI 자신의 Island.Activate()
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
target.Activate();
|
||||||
|
sb.AppendLine("④ 확장 실행 — " + target.name + ".Activate() 호출");
|
||||||
|
}
|
||||||
|
UnityEngine.Debug.Log("[WL816e Func B]\n" + sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── C. 확장 뒤 — 새 타일에도 풀이 깔렸는가 + 캡처 ───────────────────
|
||||||
|
public static void C()
|
||||||
|
{
|
||||||
|
var sb = new System.Text.StringBuilder();
|
||||||
|
target = Find(UnityEngine.PlayerPrefs.GetString("WL816e_Target", ""));
|
||||||
|
sb.AppendLine("풀(확장 뒤) — 타일 " + WL.Look.Farm.WLIslandGrass.Tiles + " · 인스턴스 " + WL.Look.Farm.WLIslandGrass.Instances +
|
||||||
|
" · rebuild " + WL.Look.Farm.WLIslandGrass.Rebuilds + " · " + WL.Look.Farm.WLIslandGrass.LastLog);
|
||||||
|
if (target != null)
|
||||||
|
sb.AppendLine("④ 대상 — " + target.name + " unlocked=" + target.IsUnlocked + " active=" + target.gameObject.activeSelf +
|
||||||
|
" scale=" + target.transform.localScale.ToString("F2") + " pos=" + target.transform.position.ToString("F0"));
|
||||||
|
var pc = UnityEngine.Object.FindFirstObjectByType<CryingSnow.FarmingIsland.PlayerController>(UnityEngine.FindObjectsInactive.Include);
|
||||||
|
if (pc != null) sb.AppendLine("② 최종 위치 " + pc.transform.position.ToString("F2"));
|
||||||
|
|
||||||
|
// 새 타일을 위에서 찍는다
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
var go = UnityEngine.GameObject.Find("__WL816eExp");
|
||||||
|
if (go == null) { go = new UnityEngine.GameObject("__WL816eExp"); go.hideFlags = UnityEngine.HideFlags.DontSave; }
|
||||||
|
var c = go.GetComponent<UnityEngine.Camera>(); if (c == null) c = go.AddComponent<UnityEngine.Camera>();
|
||||||
|
c.orthographic = true; c.orthographicSize = 7f; c.nearClipPlane = 0.3f; c.farClipPlane = 500f;
|
||||||
|
c.clearFlags = UnityEngine.CameraClearFlags.Skybox; c.depth = -100f;
|
||||||
|
var rot = UnityEngine.Quaternion.Euler(50f, 0f, 0f);
|
||||||
|
go.transform.rotation = rot;
|
||||||
|
go.transform.position = target.transform.position - rot * UnityEngine.Vector3.forward * 30f;
|
||||||
|
if (go.GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>() == null)
|
||||||
|
go.AddComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>();
|
||||||
|
Shot(c, "Screenshots_WL/WL816e/e_expanded_tile.png");
|
||||||
|
sb.AppendLine("캡처 e_expanded_tile.png (" + target.transform.position.ToString("F0") + ")");
|
||||||
|
}
|
||||||
|
Shot(MainCam(), "Screenshots_WL/WL816e/b_play_main.png");
|
||||||
|
Shot(DemoAngleCam(), "Screenshots_WL/WL816e/b_play_demoangle.png");
|
||||||
|
UnityEngine.Debug.Log("[WL816e Func C]\n" + sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 캡처 헬퍼(단일 파일 컴파일이라 복사) ────────────────────────────
|
||||||
|
public static UnityEngine.Camera MainCam()
|
||||||
|
{
|
||||||
|
var cams = UnityEngine.Object.FindObjectsByType<UnityEngine.Camera>(UnityEngine.FindObjectsInactive.Exclude, UnityEngine.FindObjectsSortMode.None);
|
||||||
|
for (int i = 0; i < cams.Length; i++) if (cams[i].name == "MainCamera") return cams[i];
|
||||||
|
for (int i = 0; i < cams.Length; i++) if (!cams[i].name.StartsWith("__WL")) return cams[i];
|
||||||
|
return cams.Length > 0 ? cams[0] : null;
|
||||||
|
}
|
||||||
|
public static UnityEngine.Camera DemoAngleCam()
|
||||||
|
{
|
||||||
|
var go = UnityEngine.GameObject.Find("__WL816eDemoAngle");
|
||||||
|
if (go == null) { go = new UnityEngine.GameObject("__WL816eDemoAngle"); go.hideFlags = UnityEngine.HideFlags.DontSave; }
|
||||||
|
var c = go.GetComponent<UnityEngine.Camera>(); if (c == null) c = go.AddComponent<UnityEngine.Camera>();
|
||||||
|
c.orthographic = true; c.orthographicSize = 10f; c.nearClipPlane = 0.3f; c.farClipPlane = 500f;
|
||||||
|
c.clearFlags = UnityEngine.CameraClearFlags.Skybox;
|
||||||
|
c.backgroundColor = new UnityEngine.Color(0.192f, 0.302f, 0.475f, 0f); c.depth = -100f;
|
||||||
|
var rot = UnityEngine.Quaternion.Euler(30f, 60f, 0f);
|
||||||
|
go.transform.rotation = rot;
|
||||||
|
go.transform.position = new UnityEngine.Vector3(0f, 0.6f, 4f) - rot * UnityEngine.Vector3.forward * 60f;
|
||||||
|
if (go.GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>() == null)
|
||||||
|
go.AddComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
public static void Shot(UnityEngine.Camera cam, string path)
|
||||||
|
{
|
||||||
|
if (cam == null) return;
|
||||||
|
int W = 1080, H = 1920;
|
||||||
|
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path));
|
||||||
|
var rt = new UnityEngine.RenderTexture(W, H, 24, UnityEngine.RenderTextureFormat.ARGB32, UnityEngine.RenderTextureReadWrite.sRGB);
|
||||||
|
rt.antiAliasing = 1; rt.Create();
|
||||||
|
var pt = cam.targetTexture; var pa = UnityEngine.RenderTexture.active;
|
||||||
|
cam.targetTexture = rt; cam.Render();
|
||||||
|
UnityEngine.RenderTexture.active = rt;
|
||||||
|
var tex = new UnityEngine.Texture2D(W, H, UnityEngine.TextureFormat.RGB24, false);
|
||||||
|
tex.ReadPixels(new UnityEngine.Rect(0, 0, W, H), 0, 0); tex.Apply();
|
||||||
|
System.IO.File.WriteAllBytes(path, UnityEngine.ImageConversion.EncodeToPNG(tex));
|
||||||
|
UnityEngine.RenderTexture.active = pa; cam.targetTexture = pt;
|
||||||
|
UnityEngine.Object.DestroyImmediate(tex); rt.Release(); UnityEngine.Object.DestroyImmediate(rt);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue