Project_WL/AgentScripts/WL816f_Verify.cs

156 lines
8.6 KiB
C#
Raw Normal View History

[WL-816f] 바닥을 데모와 일치 — 잔디 단색 + 풀 대비↓ + 밀도 2.5→1.8 + 밭 칸 표시 톤↓ (#816) PD 「내가 실행할 때는 전혀 풀밭이 아니야 · 바닥이 완전히 같은 느낌이 나도록」 ■ ① PD 실행 경로 실측 = 훅은 실제로 돈다(버그 아님) InGame 활성 + Level01 Additive 재현: 머티리얼 1,575 렌더러 교체 · 풀 생성 · ReferenceLook on · 콘솔 error 0. 「안 나온다」가 아니라 「데모와 전혀 다르게 보인다」였다. 다만 이 경로에서만 생기는 실측 차이 2가지를 찾아 보고에 적었다 (세이브 파일이 활성 씬 이름으로 갈린다 · RenderSettings 가 InGame 소유). ■ ② 바닥 3요소 (같은 화각·같은 거리 캡처로 판정) 체크무늬 : 잔디 타일 텍스처는 단색(#A0E4A2) — 격자 0. 밭(Soil)의 칸 표시는 게임 기능이라 남기고 **색만** 데모 톤으로(soilTint·soilCheckerContrast). 바닥 색 : #AFEDAE → #A0E4A2 (화면색 평균 데모 #94BE81 ↔ 우리 #9AC37E) 풀 색 : 새 복사본 Farm_Grass_Demo.mat (_DiffuseColor #A6E39F · _ShadowDiffuseColor #95CC8F) → 풀이 바닥과 같은 색으로 깔려 「카펫」이 사라진다(에지% 8.09 → 1.96 · 데모 1.79) 밀도 : 2.5 → 1.8 (6.25 → 3.24 개/㎡) 🔴 Assets/FarmingIsland/** 0줄 · Assets/Script/** 0줄 · 3DPixelArtEnvironment 0줄 · ProjectSettings 0줄 · 전역 URP/품질 0. 되돌리기 = enabled_ = 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 05:19:39 +00:00
// WL-816f — PD 경로 Play 에서 ⓓ성능 ⓔ기능(걷기·농사·건설/확장) ⓕ되돌리기를 실측한다.
public static class WL816f_Verify
{
public static void Start()
{
var go = UnityEngine.GameObject.Find("~WL816fVerify");
if (go != null) UnityEngine.Object.DestroyImmediate(go);
go = new UnityEngine.GameObject("~WL816fVerify");
go.AddComponent<WL816f_VerifyRunner>();
}
}
public class WL816f_VerifyRunner : UnityEngine.MonoBehaviour
{
const string Dir = "Screenshots_WL/WL816f/";
static System.Text.StringBuilder sb;
void Start() { StartCoroutine(Co()); }
System.Collections.IEnumerator Co()
{
sb = new System.Text.StringBuilder();
if (UnityEngine.SceneManagement.SceneManager.sceneCount < 2)
{
var op = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync("Level01", UnityEngine.SceneManagement.LoadSceneMode.Additive);
while (op != null && !op.isDone) yield return null;
}
for (int i = 0; i < 6; i++) yield return new UnityEngine.WaitForSeconds(1f);
L("=== WL-816f 검증 (PD 경로 · InGame 활성 + Level01 Additive) ===");
L("풀 : " + WL.Look.Farm.WLIslandGrass.LastLog);
L("Soil 톤 : farm " + WL.Look.Farm.WLIslandLook.SoilFarmsToned + " · 타일 " + WL.Look.Farm.WLIslandLook.SoilTilesRepainted);
// ── ⓓ 성능 : 같은 카메라로 60프레임 오프스크린 렌더 ─────────
var cam = FindLiveCam();
L("");
L("[성능] 카메라 " + (cam ? cam.name : "없음"));
float onMs = RenderBench(cam, 60);
var g = UnityEngine.Object.FindFirstObjectByType<WL.Look.Farm.WLIslandGrass>(UnityEngine.FindObjectsInactive.Include);
int instOn = WL.Look.Farm.WLIslandGrass.Instances;
long triOn = WL.Look.Farm.WLIslandGrass.Triangles;
if (g != null) g.enabled = false; // 풀만 끈 상태
yield return null; yield return null;
float offMs = RenderBench(cam, 60);
if (g != null) g.enabled = true;
yield return null; yield return null;
L("풀 켬 " + onMs.ToString("F3") + " ms/frame · 풀 끔 " + offMs.ToString("F3") + " ms/frame · 델타 " + (onMs - offMs).ToString("F3") + " ms");
L("인스턴스 " + instOn + " · 삼각형(풀) " + triOn + " · 드로우콜 +" + WL.Look.Farm.WLIslandGrass.DrawnConfigs);
// ── ⓔ 기능 ─────────────────────────────────────────────────
L("");
L("[기능]");
// 풀 콜라이더 0 · 레이캐스트 · NavMesh
int colliders = 0;
var gobj = g != null ? g.gameObject : null;
if (gobj != null) colliders = gobj.GetComponentsInChildren<UnityEngine.Collider>(true).Length;
L("풀 오브젝트 콜라이더 = " + colliders + " (0 이어야 한다)");
int hit = 0, nav = 0;
for (int i = 0; i < 100; i++)
{
var p = new UnityEngine.Vector3(UnityEngine.Random.Range(-7f, 7f), 3f, UnityEngine.Random.Range(-7f, 7f));
UnityEngine.RaycastHit h;
if (UnityEngine.Physics.Raycast(p, UnityEngine.Vector3.down, out h, 10f)) hit++;
UnityEngine.AI.NavMeshHit nh;
if (UnityEngine.AI.NavMesh.SamplePosition(new UnityEngine.Vector3(p.x, 0f, p.z), out nh, 1.5f, ~0)) nav++;
}
L("풀밭 100점 아래 레이캐스트 적중 " + hit + "/100 · NavMesh 샘플 " + nav + "/100");
// 걷기 — FI PlayerController 의 CharacterController
var cc = UnityEngine.Object.FindFirstObjectByType<UnityEngine.CharacterController>(UnityEngine.FindObjectsInactive.Exclude);
if (cc != null)
{
var p0 = cc.transform.position;
var dir = new UnityEngine.Vector3(1f, 0f, 1f).normalized;
float moved = 0f;
for (int i = 0; i < 120; i++) { cc.Move(dir * 0.05f + UnityEngine.Vector3.down * 0.02f); yield return null; }
moved = UnityEngine.Vector3.Distance(new UnityEngine.Vector3(p0.x, 0f, p0.z), new UnityEngine.Vector3(cc.transform.position.x, 0f, cc.transform.position.z));
L("걷기 : " + p0.ToString("F2") + " → " + cc.transform.position.ToString("F2") + " = " + moved.ToString("F2") + " m · grounded=" + cc.isGrounded);
}
else L("걷기 : CharacterController 없음(미확인)");
// 농사 — Farm/Soil 개수 + 씨뿌리기 상태 전환
var farms = UnityEngine.Object.FindObjectsByType<CryingSnow.FarmingIsland.Farm>(UnityEngine.FindObjectsInactive.Exclude, UnityEngine.FindObjectsSortMode.None);
var soils = UnityEngine.Object.FindObjectsByType<CryingSnow.FarmingIsland.Soil>(UnityEngine.FindObjectsInactive.Exclude, UnityEngine.FindObjectsSortMode.None);
L("농사 : Farm " + farms.Length + " · Soil " + soils.Length);
int painted = 0;
for (int i = 0; i < soils.Length; i++)
{
var r = soils[i].GetComponentInChildren<UnityEngine.Renderer>(true);
if (r != null && r.sharedMaterial != null) painted++;
}
L("Soil 렌더러 살아있음 " + painted + "/" + soils.Length + " · 첫 Soil 색 " +
(soils.Length > 0 && soils[0].GetComponentInChildren<UnityEngine.Renderer>(true) != null
? UnityEngine.ColorUtility.ToHtmlStringRGB(soils[0].GetComponentInChildren<UnityEngine.Renderer>(true).material.color) : "-"));
// 확장 — 섬 타일 수
var islands = UnityEngine.Object.FindObjectsByType<CryingSnow.FarmingIsland.Island>(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None);
int unlocked = 0; for (int i = 0; i < islands.Length; i++) if (islands[i].IsUnlocked && islands[i].gameObject.activeInHierarchy) unlocked++;
L("확장 : 섬 타일 전체 " + islands.Length + " · 열린 타일 " + unlocked + " · 풀 깔린 타일 " + WL.Look.Farm.WLIslandGrass.Tiles);
// ── 최종 캡처 ───────────────────────────────────────────────
Shot(FindLiveCam(), Dir + "d_final_wide.png");
System.IO.File.WriteAllText("AgentScripts/WL816f_VERIFY.txt", sb.ToString());
UnityEngine.Debug.Log("[816f verify]\n" + sb.ToString());
}
static void L(string s) { sb.AppendLine(s); }
static UnityEngine.Camera FindLiveCam()
{
var cams = UnityEngine.Object.FindObjectsByType<UnityEngine.Camera>(UnityEngine.FindObjectsInactive.Exclude, UnityEngine.FindObjectsSortMode.None);
UnityEngine.Camera top = null;
for (int i = 0; i < cams.Length; i++)
{
var c = cams[i];
if (!c.enabled || c.targetTexture != null) continue;
if (top == null || c.depth > top.depth) top = c;
}
return top;
}
static float RenderBench(UnityEngine.Camera cam, int frames)
{
if (cam == null) return -1f;
var rt = new UnityEngine.RenderTexture(1080, 1920, 24, UnityEngine.RenderTextureFormat.ARGB32, UnityEngine.RenderTextureReadWrite.sRGB);
rt.antiAliasing = 1; rt.Create();
var prev = cam.targetTexture; cam.targetTexture = rt;
cam.Render(); // 워밍업
var sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < frames; i++) cam.Render();
sw.Stop();
cam.targetTexture = prev;
rt.Release(); UnityEngine.Object.DestroyImmediate(rt);
return (float)sw.Elapsed.TotalMilliseconds / frames;
}
static void Shot(UnityEngine.Camera cam, string path)
{
if (cam == null) return;
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path));
var rt = new UnityEngine.RenderTexture(1080, 1920, 24, UnityEngine.RenderTextureFormat.ARGB32, UnityEngine.RenderTextureReadWrite.sRGB);
rt.antiAliasing = 1; rt.Create();
var prevT = cam.targetTexture; var prevA = UnityEngine.RenderTexture.active;
cam.targetTexture = rt; cam.Render();
UnityEngine.RenderTexture.active = rt;
var tex = new UnityEngine.Texture2D(1080, 1920, UnityEngine.TextureFormat.RGB24, false);
tex.ReadPixels(new UnityEngine.Rect(0, 0, 1080, 1920), 0, 0); tex.Apply();
System.IO.File.WriteAllBytes(path, UnityEngine.ImageConversion.EncodeToPNG(tex));
UnityEngine.RenderTexture.active = prevA; cam.targetTexture = prevT;
UnityEngine.Object.DestroyImmediate(tex);
rt.Release(); UnityEngine.Object.DestroyImmediate(rt);
L("캡처 " + path);
}
}