219 lines
12 KiB
C#
219 lines
12 KiB
C#
// 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")
|
||
+ "(R−B " + ((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);
|
||
}
|
||
}
|