Project_WL/AgentScripts/WL816j2_Final.cs

219 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// WL-816j2 — ⑧ 최종 확인: PD 구도 전/후 · 사방 띠 · 확장 · 걷기 · 성능 · 되돌리기
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
using WL.Look.Farm;
using FIIsland = CryingSnow.FarmingIsland.Island;
public static class WL816j2_Final
{
public const string D = "Screenshots_WL/WL816j2/";
public const int PW = 1280, PH = 720;
public static void Open()
{
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(
"Assets/Scenes/InGame.unity", UnityEditor.SceneManagement.OpenSceneMode.Single);
}
public static void Start()
{
var go = GameObject.Find("~WL816j2F");
if (go != null) Object.DestroyImmediate(go);
go = new GameObject("~WL816j2F");
go.AddComponent<WL816j2_FinalRunner>();
}
public static string Shot(Camera cam, string path, int w, int h)
{
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path));
var rt = new RenderTexture(w, h, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
rt.antiAliasing = 1; rt.Create();
var pT = cam.targetTexture; var pA = RenderTexture.active;
cam.targetTexture = rt; cam.Render(); RenderTexture.active = rt;
var t = new Texture2D(w, h, TextureFormat.RGB24, false);
t.ReadPixels(new Rect(0, 0, w, h), 0, 0); t.Apply();
RenderTexture.active = pA; cam.targetTexture = pT; rt.Release(); Object.DestroyImmediate(rt);
System.IO.File.WriteAllBytes(path, t.EncodeToPNG());
var px = t.GetPixels32();
long r = 0, g = 0, b = 0; int n = 0; long fr = 0, fg = 0, fb = 0; int fn = 0, tot = 0;
for (int y = 20; y < Mathf.Min(320, h); y += 2)
for (int x = 20; x < Mathf.Min(340, w); x += 2) { var c = px[y * w + x]; r += c.r; g += c.g; b += c.b; n++; }
int y1 = (int)(h * 0.55f);
for (int y = 0; y < y1; y++)
for (int x = 0; x < w; x += 2) { var c = px[y * w + x]; tot++; if (c.r > 200 && c.g > 195 && c.b > 195) { fr += c.r; fg += c.g; fb += c.b; fn++; } }
Object.DestroyImmediate(t);
string foam = fn == 0 ? "거품 0%" : "거품 " + (100f * fn / tot).ToString("F2") + "% #"
+ ((int)(fr / fn)).ToString("X2") + ((int)(fg / fn)).ToString("X2") + ((int)(fb / fn)).ToString("X2")
+ "(RB " + ((int)(fr / fn) - (int)(fb / fn)) + ")";
return "바다평균 #" + ((int)(r / n)).ToString("X2") + ((int)(g / n)).ToString("X2") + ((int)(b / n)).ToString("X2")
+ " · " + foam + " → " + path;
}
public static float Ms(Camera cam, int frames)
{
var rt = new RenderTexture(PW, PH, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
rt.antiAliasing = 1; rt.Create();
var pT = cam.targetTexture; cam.targetTexture = rt;
for (int i = 0; i < 10; i++) cam.Render();
var sw = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < frames; i++) cam.Render();
sw.Stop();
cam.targetTexture = pT; rt.Release(); Object.DestroyImmediate(rt);
return (float)sw.Elapsed.TotalMilliseconds / frames;
}
public static void Strip(string[] paths, string outPath)
{
var ts = new Texture2D[paths.Length]; int w = 0, h = 0;
for (int i = 0; i < paths.Length; i++)
{
if (!System.IO.File.Exists(paths[i])) return;
ts[i] = new Texture2D(2, 2, TextureFormat.RGB24, false);
ts[i].LoadImage(System.IO.File.ReadAllBytes(paths[i]));
w = Mathf.Max(w, ts[i].width); h += ts[i].height;
}
var o = new Texture2D(w, h, TextureFormat.RGB24, false);
var f = new Color32[w * h];
for (int i = 0; i < f.Length; i++) f[i] = new Color32(24, 24, 28, 255);
o.SetPixels32(f);
int y = h;
for (int i = 0; i < ts.Length; i++) { y -= ts[i].height; o.SetPixels32(0, y, ts[i].width, ts[i].height, ts[i].GetPixels32()); }
o.Apply();
System.IO.File.WriteAllBytes(outPath, o.EncodeToPNG());
Object.DestroyImmediate(o);
for (int i = 0; i < ts.Length; i++) Object.DestroyImmediate(ts[i]);
}
}
public class WL816j2_FinalRunner : MonoBehaviour
{
static StringBuilder sb;
static void L(string s) { sb.AppendLine(s); }
const string D = WL816j2_Final.D;
const string MatDir = "Assets/WL/Look/Farm/Materials/";
const int PW = WL816j2_Final.PW, PH = WL816j2_Final.PH;
void Start() { StartCoroutine(Co()); }
IEnumerator Co()
{
sb = new StringBuilder();
L("=== WL-816j2 ⑧ 최종 (PD 구도 1280×720) ===");
bool viaGame = false;
try { if (InGameInfo.Ins != null) { InGameInfo.Ins.Load_Map(900); viaGame = true; } } catch { }
L("Load_Map(900) = " + (viaGame ? "성공" : "🔴 로그인 없이는 못 탄다 → LoadSceneAsync(Level01, Additive)"));
if (!viaGame)
{
var op = SceneManager.LoadSceneAsync("Level01", LoadSceneMode.Additive);
while (op != null && !op.isDone) yield return null;
}
for (int i = 0; i < 8; i++) yield return new WaitForSeconds(1f);
Renderer water = null;
foreach (var r in Object.FindObjectsByType<Renderer>(FindObjectsInactive.Exclude, FindObjectsSortMode.None))
if (r != null && r.gameObject.scene.name == "Level01" && r.name == "Water") water = r;
Camera live = null;
foreach (var c in Object.FindObjectsByType<Camera>(FindObjectsInactive.Exclude, FindObjectsSortMode.None))
{
if (!c.gameObject.activeInHierarchy || !c.enabled || c.targetTexture != null) continue;
if (c.name.StartsWith("~WL816")) continue;
if (live == null || c.depth > live.depth) live = c;
}
var foam = Object.FindFirstObjectByType<WLShoreFoam>(FindObjectsInactive.Include);
if (water == null || live == null || foam == null) { L("🔴 없음"); Done(); yield break; }
var mr = foam.GetComponent<MeshRenderer>();
var E = water.sharedMaterial;
var Dm = UnityEditor.AssetDatabase.LoadAssetAtPath<Material>(MatDir + "Farm_Water_WL_D.mat");
var FI = UnityEditor.AssetDatabase.LoadAssetAtPath<Material>(MatDir + "Farm_SimpleWater_Demo.mat");
L("물 = " + E.name + " · 둘레 띠 = " + WLShoreFoam.LastLog);
// 1) 전/후
mr.enabled = false; water.sharedMaterial = Dm; yield return null; yield return new WaitForSeconds(0.4f);
L("");
L("1) [전] main(물 D · 띠 없음 = PD 가 본 화면) " + WL816j2_Final.Shot(live, D + "z2_before_pd.png", PW, PH));
mr.enabled = true; water.sharedMaterial = E; yield return null; yield return new WaitForSeconds(0.4f);
L(" [후] 816j2(물 E · 둘레 띠) " + WL816j2_Final.Shot(live, D + "z2_after_pd.png", PW, PH));
WL816j2_Final.Strip(new[] { D + "z2_before_pd.png", D + "z2_after_pd.png" }, D + "z2_pd_before_after.png");
L(" 세로(게임 기준 1080×1920) " + WL816j2_Final.Shot(live, D + "z2_after_portrait.png", 1080, 1920));
// 2) 사방 + 물가 확대
var tgo = new GameObject("~WL816j2FT"); tgo.hideFlags = HideFlags.DontSave;
var tc = tgo.AddComponent<Camera>();
tc.fieldOfView = 55f; tc.nearClipPlane = 0.1f; tc.farClipPlane = 2000f;
tc.clearFlags = CameraClearFlags.Skybox; tc.cullingMask = ~0; tc.depth = -100f;
tgo.AddComponent<UniversalAdditionalCameraData>().renderPostProcessing = true;
tgo.transform.position = new Vector3(0f, 42f, -12f); tgo.transform.LookAt(Vector3.zero);
L("");
L("2) 사방(위에서) " + WL816j2_Final.Shot(tc, D + "z2_top.png", PW, PH));
var b = mr.bounds;
var zgo = new GameObject("~WL816j2FZ"); zgo.hideFlags = HideFlags.DontSave;
var zc = zgo.AddComponent<Camera>();
zc.fieldOfView = 34f; zc.nearClipPlane = 0.1f; zc.farClipPlane = 2000f;
zc.clearFlags = CameraClearFlags.Skybox; zc.cullingMask = ~0; zc.depth = -100f;
zgo.AddComponent<UniversalAdditionalCameraData>().renderPostProcessing = true;
zgo.transform.position = new Vector3(b.center.x, 3.2f, b.min.z - 9f);
zgo.transform.LookAt(new Vector3(b.center.x, -1f, b.min.z + 2f));
mr.enabled = false; water.sharedMaterial = Dm; yield return null; yield return null;
L(" 물가 확대 [전] " + WL816j2_Final.Shot(zc, D + "z2_zoom_before.png", PW, PH));
mr.enabled = true; water.sharedMaterial = E; yield return null; yield return null;
L(" 물가 확대 [후] " + WL816j2_Final.Shot(zc, D + "z2_zoom_after.png", PW, PH));
WL816j2_Final.Strip(new[] { D + "z2_zoom_before.png", D + "z2_zoom_after.png" }, D + "z2_zoom_pair.png");
// 3) 걷기 + 확장
var cc = Object.FindFirstObjectByType<CharacterController>(FindObjectsInactive.Exclude);
if (cc != null)
{
var p0 = cc.transform.position; var dir = new Vector3(1f, 0f, 1f).normalized; float moved = 0f;
for (int i = 0; i < 120 && moved < 6f; i++) { cc.Move(dir * 0.05f + Vector3.down * 0.05f); moved += 0.05f; yield return null; }
L("");
L("3) 걷기 " + p0.ToString("F2") + " → " + cc.transform.position.ToString("F2") + " · 이동 "
+ Vector3.Distance(new Vector3(p0.x, 0, p0.z), new Vector3(cc.transform.position.x, 0, cc.transform.position.z)).ToString("F2")
+ " m · grounded=" + cc.isGrounded);
}
var islands = Object.FindObjectsByType<FIIsland>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
FIIsland target = null;
foreach (var isl in islands) if (isl != null && isl.IsUnlocked && isl.gameObject.activeInHierarchy) target = isl;
if (target != null)
{
target.gameObject.SetActive(false); yield return new WaitForSeconds(2.5f);
L(" 확장 1칸 잠금 → " + WLShoreFoam.LastLog);
L(" " + WL816j2_Final.Shot(tc, D + "z2_top_locked.png", PW, PH));
target.gameObject.SetActive(true); yield return new WaitForSeconds(3.5f);
L(" 다시 열기 → " + WLShoreFoam.LastLog + " · 띠 재생성 " + WL.Look.Farm.WLIslandLook.ShoreFoamRebuilds + "회");
L(" " + WL816j2_Final.Shot(tc, D + "z2_top_unlocked.png", PW, PH));
WL816j2_Final.Strip(new[] { D + "z2_top.png", D + "z2_top_locked.png", D + "z2_top_unlocked.png" }, D + "z2_expand_steps.png");
}
// 4) 성능
L("");
L("4) 성능 (PD 구도 1280×720 · 60프레임 · 교대 2회)");
for (int round = 0; round < 2; round++)
{
mr.enabled = false; water.sharedMaterial = Dm; yield return null; yield return null;
L(" " + round + "회차 전(물 D · 띠 없음) = " + WL816j2_Final.Ms(live, 60).ToString("F3") + " ms");
mr.enabled = true; water.sharedMaterial = E; yield return null; yield return null;
L(" " + round + "회차 후(물 E · 띠 on) = " + WL816j2_Final.Ms(live, 60).ToString("F3") + " ms");
mr.enabled = false; yield return null; yield return null;
L(" " + round + "회차 후(물 E · 띠 off) = " + WL816j2_Final.Ms(live, 60).ToString("F3") + " ms");
mr.enabled = true;
}
L(" 띠 = " + WLShoreFoam.LastLog);
// 5) 되돌리기
L("");
L("5) 되돌리기");
mr.enabled = false; water.sharedMaterial = Dm; yield return null; yield return new WaitForSeconds(0.3f);
L(" shoreFoamEnabled 0 + waterTo=D → 816j 그대로 " + WL816j2_Final.Shot(live, D + "z2_rollback_816j.png", PW, PH));
water.sharedMaterial = FI; yield return null; yield return new WaitForSeconds(0.3f);
L(" waterMode 0 → FI 원본 물 " + WL816j2_Final.Shot(live, D + "z2_rollback_fi.png", PW, PH));
water.sharedMaterial = E; mr.enabled = true; yield return null;
Object.DestroyImmediate(tgo); Object.DestroyImmediate(zgo);
Done();
}
void Done()
{
System.IO.File.WriteAllText("AgentScripts/WL816j2_FINAL.txt", sb.ToString());
Debug.Log("[816j2 final]\n" + sb);
}
}