Project_WL/AgentScripts/WL816e_Func.cs

192 lines
12 KiB
C#

// 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);
}
}