From e4d69ead8cf468b391339225c7aa9d40df52b5e6 Mon Sep 17 00:00:00 2001 From: swrring Date: Thu, 10 Sep 2026 23:30:35 +0900 Subject: [PATCH] =?UTF-8?q?[WL-814b]=20Critter=20=ED=94=BD=EC=85=80=20?= =?UTF-8?q?=EC=B9=B4=EB=A9=94=EB=9D=BC=20=EB=A6=AC=EA=B7=B8:=20=EC=A7=81?= =?UTF-8?q?=EA=B5=90=20=EC=A0=80=ED=95=B4=EC=83=81=EB=8F=84=20RT=20=C2=B7?= =?UTF-8?q?=20=EC=9B=90=EB=B3=B8=20=EC=B9=B4=EB=A9=94=EB=9D=BC=20=EB=AF=B8?= =?UTF-8?q?=EB=9F=AC=20=C2=B7=20=EC=9D=B8=EA=B2=8C=EC=9E=84=20=EC=A1=B0?= =?UTF-8?q?=EB=A6=BD/=EB=B3=B5=EC=9B=90=20=C2=B7=20=EB=A3=A9=20=EC=BA=A1?= =?UTF-8?q?=EC=B2=98=20(#814)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- AgentScripts/WL814b_Import.cs | 78 ++ AgentScripts/WL814b_Probe.cs | 637 +++++++++ AgentScripts/staging/WL814b/EDIT_PROBE.txt | 94 ++ Assets/3DPixelCamera/URP.meta | 8 + Assets/3DPixelCamera/URP/DemoScene.unity | 1226 +++++++++++++++++ Assets/3DPixelCamera/URP/DemoScene.unity.meta | 7 + .../URP/PixelCameraSystem.prefab | 496 +++++++ .../URP/PixelCameraSystem.prefab.meta | 7 + .../3DPixelCamera/URP/UpscaleMaterialURP.mat | 135 ++ .../URP/UpscaleMaterialURP.mat.meta | 8 + .../URP/UpscaleShaderURP.shadergraph | 693 ++++++++++ .../URP/UpscaleShaderURP.shadergraph.meta | 10 + .../Resources/WL/WLPixelCameraSettings.asset | 39 + .../WL/WLPixelCameraSettings.asset.meta | 8 + Assets/WL/PixelCamera.meta | 8 + Assets/WL/PixelCamera/PixelCameraRig.cs | 711 ++++++++++ Assets/WL/PixelCamera/PixelCameraRig.cs.meta | 11 + .../WL/PixelCamera/WLPixelCameraSettings.cs | 152 ++ .../PixelCamera/WLPixelCameraSettings.cs.meta | 11 + 19 files changed, 4339 insertions(+) create mode 100644 AgentScripts/WL814b_Import.cs create mode 100644 AgentScripts/WL814b_Probe.cs create mode 100644 AgentScripts/staging/WL814b/EDIT_PROBE.txt create mode 100644 Assets/3DPixelCamera/URP.meta create mode 100644 Assets/3DPixelCamera/URP/DemoScene.unity create mode 100644 Assets/3DPixelCamera/URP/DemoScene.unity.meta create mode 100644 Assets/3DPixelCamera/URP/PixelCameraSystem.prefab create mode 100644 Assets/3DPixelCamera/URP/PixelCameraSystem.prefab.meta create mode 100644 Assets/3DPixelCamera/URP/UpscaleMaterialURP.mat create mode 100644 Assets/3DPixelCamera/URP/UpscaleMaterialURP.mat.meta create mode 100644 Assets/3DPixelCamera/URP/UpscaleShaderURP.shadergraph create mode 100644 Assets/3DPixelCamera/URP/UpscaleShaderURP.shadergraph.meta create mode 100644 Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset create mode 100644 Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset.meta create mode 100644 Assets/WL/PixelCamera.meta create mode 100644 Assets/WL/PixelCamera/PixelCameraRig.cs create mode 100644 Assets/WL/PixelCamera/PixelCameraRig.cs.meta create mode 100644 Assets/WL/PixelCamera/WLPixelCameraSettings.cs create mode 100644 Assets/WL/PixelCamera/WLPixelCameraSettings.cs.meta diff --git a/AgentScripts/WL814b_Import.cs b/AgentScripts/WL814b_Import.cs new file mode 100644 index 000000000..58e236824 --- /dev/null +++ b/AgentScripts/WL814b_Import.cs @@ -0,0 +1,78 @@ +// WL-814b — Assets/3DPixelCamera/URP.unitypackage 해제(BuiltIn 은 절대 건드리지 않는다). +// 게임 코드 아님. run_script 전용. +public static class WL814b_Import +{ + const string Pkg = "Assets/3DPixelCamera/URP.unitypackage"; + const string Dir = "Assets/3DPixelCamera/URP"; + + /// 1단계 — 스냅샷을 찍고 비동기 임포트를 시작한다. + public static string Run() + { + if (!System.IO.File.Exists(Pkg)) return "FAIL 패키지 없음: " + Pkg; + + var sb = new System.Text.StringBuilder(); + sb.AppendLine("[WL814b-import] before: URP 폴더 존재=" + System.IO.Directory.Exists(Dir)); + UnityEditor.AssetDatabase.ImportPackage(Pkg, false); // false = 대화상자 없이 전부 + sb.AppendLine("[WL814b-import] ImportPackage 호출됨(비동기) — 다음 단계에서 Verify"); + return sb.ToString(); + } + + /// 2단계 — 생긴 파일 목록·GUID 를 뱉는다. + public static string Verify() + { + UnityEditor.AssetDatabase.Refresh(); + var sb = new System.Text.StringBuilder(); + if (!System.IO.Directory.Exists(Dir)) { sb.AppendLine("FAIL URP 폴더 없음"); return sb.ToString(); } + + var files = System.IO.Directory.GetFiles(Dir, "*", System.IO.SearchOption.AllDirectories); + System.Array.Sort(files); + int n = 0; + foreach (var f in files) + { + var rel = f.Replace('\\', '/'); + int i = rel.IndexOf("Assets/"); + if (i >= 0) rel = rel.Substring(i); + if (rel.EndsWith(".meta")) { sb.AppendLine(" meta " + rel); continue; } + n++; + var guid = UnityEditor.AssetDatabase.AssetPathToGUID(rel); + var t = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(rel); + sb.AppendLine(" ASSET " + rel + " | guid=" + guid + " | type=" + (t == null ? "?" : t.Name) + + " | " + new System.IO.FileInfo(f).Length + " B"); + } + sb.AppendLine("[WL814b-import] 에셋 " + n + "개(+meta) · BuiltIn 해제 0"); + + // 프리팹 구조 표 + var pf = UnityEditor.AssetDatabase.LoadAssetAtPath(Dir + "/PixelCameraSystem.prefab"); + if (pf == null) sb.AppendLine("FAIL PixelCameraSystem.prefab 로드 실패"); + else { sb.AppendLine("[구조]"); Dump(pf.transform, 0, sb); } + return sb.ToString(); + } + + static void Dump(UnityEngine.Transform t, int depth, System.Text.StringBuilder sb) + { + sb.Append(' ', depth * 2).Append("- ").Append(t.name).Append(" layer=").Append(t.gameObject.layer); + var comps = t.GetComponents(); + sb.Append(" ["); + for (int i = 0; i < comps.Length; i++) + { + if (comps[i] == null) { sb.Append(" "); continue; } + sb.Append(comps[i].GetType().Name).Append(' '); + } + sb.Append("]"); + var cam = t.GetComponent(); + if (cam != null) + sb.Append(" cam(ortho=").Append(cam.orthographic ? 1 : 0).Append(" size=").Append(cam.orthographicSize) + .Append(" depth=").Append(cam.depth).Append(" mask=").Append(cam.cullingMask) + .Append(" clear=").Append((int)cam.clearFlags).Append(" near=").Append(cam.nearClipPlane) + .Append(" far=").Append(cam.farClipPlane).Append(")"); + var ucd = t.GetComponent(); + if (ucd != null) sb.Append(" urp(type=").Append(ucd.renderType).Append(" post=").Append(ucd.renderPostProcessing ? 1 : 0).Append(")"); + var mr = t.GetComponent(); + if (mr != null) sb.Append(" mat=").Append(mr.sharedMaterial == null ? "null" : mr.sharedMaterial.name); + var lp = t.localPosition; var ls = t.localScale; + sb.Append(" lp=(").Append(lp.x.ToString("0.####")).Append(',').Append(lp.y.ToString("0.####")).Append(',').Append(lp.z.ToString("0.####")).Append(')'); + sb.Append(" ls=(").Append(ls.x.ToString("0.####")).Append(',').Append(ls.y.ToString("0.####")).Append(',').Append(ls.z.ToString("0.####")).Append(')'); + sb.AppendLine(); + for (int i = 0; i < t.childCount; i++) Dump(t.GetChild(i), depth + 1, sb); + } +} diff --git a/AgentScripts/WL814b_Probe.cs b/AgentScripts/WL814b_Probe.cs new file mode 100644 index 000000000..92adece0e --- /dev/null +++ b/AgentScripts/WL814b_Probe.cs @@ -0,0 +1,637 @@ +// PD 지시 #814 · 발주서 WL-814b — Critter 픽셀 카메라 리그 검증 프로브 + 룩 캡처 +// (에디트 모드 전용 · Play 0 · 로그인 0 · 디스크 에셋 무수정) +// +// 실행 (CLAUDE.md §1: using 금지 · 네임스페이스 풀어 쓰기) +// unity command run_script --file AgentScripts/WL814b_Probe.cs --entry WL814b_Probe.MakeAsset --timeout 300 +// unity command run_script --file AgentScripts/WL814b_Probe.cs --entry WL814b_Probe.Edit --timeout 1800 +// +// 무엇을 재는가 +// A. 표 ① 보조 — 원본 Main Camera.prefab 값 · NewGameUI 캔버스 렌더 모드/카메라 · UICamera 스택 +// B. 리그 — 임시 씬(추가 로드 · 저장 0)에 맵 + PC + 잡몹 + 원본 카메라 → 조립 → 구조 표 +// C. 복원 — 원본 카메라 값 스냅샷 == 복원값(문자열 동일) · 리그 오브젝트 0 · RT 해제 +// D. 매핑오차 — Camera.main 투영(WorldToViewportPoint) vs 실제 RT→쿼드→뷰 카메라 화면 좌표(5점 · px) +// E. GC — 프록시 미러 · 회전 스냅 판정 200k 회 할당 증가분(0 B 목표) +// F. C8 — RuntimeDisabled = true → Tick 이 즉시 복원 · 조립 0 +// G. 캡처 — 1080×1920 4장(ortho 3.8×480 · 3.8×360 · 4.6×480 · 대조 원근 원본) +public static class WL814b_Probe +{ + const string kOutDir = @"E:\NerdNavis\nn_himminji\Screenshots_WL\WL814b"; + const string kMap = "Assets/Res_Addr/Map/WL_Nature.prefab"; + const string kPc = "Assets/Res_Addr/PC/Ai01.prefab"; + const string kCam = "Assets/ResWork/Prefabs/Ingame/Main Camera.prefab"; + const string kRig = "Assets/3DPixelCamera/URP/PixelCameraSystem.prefab"; + const string kSo = "Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset"; + const string kSnap = "AgentScripts/staging/WL814b/EDIT_PROBE.txt"; + + const int W = 1080, H = 1920; + + static System.Text.StringBuilder sb; + static int pass, fail; + static UnityEngine.Vector3 s_lookAtWorld; + + static void L(string s) { sb.Append(s).Append('\n'); } + static void Chk(bool ok, string label, string detail) + { + if (ok) pass++; else fail++; + sb.Append(ok ? " PASS " : " FAIL ").Append(label); + if (!string.IsNullOrEmpty(detail)) sb.Append(" ").Append(detail); + sb.Append('\n'); + } + + // ───────────────────────────────────────────────────────────────────────── + // SO 에셋 생성 (1회) — 손으로 YAML 쓰지 않고 에디터가 만들게 한다 + // ───────────────────────────────────────────────────────────────────────── + public static string MakeAsset() + { + sb = new System.Text.StringBuilder(); + var dir = System.IO.Path.GetDirectoryName(kSo).Replace('\\', '/'); + if (!System.IO.Directory.Exists(dir)) { L("FAIL 폴더 없음 " + dir); return sb.ToString(); } + + var so = UnityEditor.AssetDatabase.LoadAssetAtPath(kSo); + bool created = false; + if (so == null) + { + so = UnityEngine.ScriptableObject.CreateInstance(); + UnityEditor.AssetDatabase.CreateAsset(so, kSo); + created = true; + } + + var rig = UnityEditor.AssetDatabase.LoadAssetAtPath(kRig); + so.pixelCameraSystemPrefab = rig; + UnityEditor.EditorUtility.SetDirty(so); + UnityEditor.AssetDatabase.SaveAssets(); + UnityEditor.AssetDatabase.Refresh(); + + L((created ? "생성" : "갱신") + " " + kSo); + L(" prefab=" + (rig == null ? "null(패키지 해제 확인)" : UnityEditor.AssetDatabase.GetAssetPath(rig))); + L(" guid=" + UnityEditor.AssetDatabase.AssetPathToGUID(kSo)); + L(" enabled=" + so.enabled + " orthoSize=" + so.orthoSize + " pixelHeight=" + so.pixelHeight + + " rigLayer=" + so.rigLayer + " proxyMode=" + so.proxyMode + + " compensateViewZoom=" + so.compensateViewZoom); + return sb.ToString(); + } + + // ───────────────────────────────────────────────────────────────────────── + // 본 프로브 + // ───────────────────────────────────────────────────────────────────────── + public static string Edit() + { + sb = new System.Text.StringBuilder(); + pass = fail = 0; + System.IO.Directory.CreateDirectory(kOutDir); + + L("# WL-814b 프로브 — " + System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); + L("unity=" + UnityEngine.Application.unityVersion + " · isPlaying=" + UnityEngine.Application.isPlaying); + + SectionA(); + + // 배치모드 에디터의 현재(무제목·빈) 씬에 직접 짓는다 — 추가 씬 생성은 무제목 씬이 열려 있으면 금지된다. + // 모든 인스턴스는 HideAndDontSave + DestroyImmediate 이므로 씬에 남지도, 저장되지도 않는다(811o 방식). + var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); + L("현재 씬 = '" + scene.name + "' path='" + scene.path + "' dirty(before)=" + scene.isDirty + + " rootCount=" + scene.rootCount); + + UnityEngine.GameObject mapGo = null, pcGo = null, camGo = null, lightGo = null; + var mobs = new System.Collections.Generic.List(); + try + { + BuildScene(ref mapGo, ref pcGo, ref camGo, ref lightGo, mobs); + if (camGo == null) { L("FAIL 카메라 인스턴스 실패 — 중단"); } + else + { + var cam = camGo.GetComponent(); + SectionBCD(cam, pcGo); + SectionE(cam); + SectionF(cam); + SectionG(cam); + } + } + catch (System.Exception ex) { L("EXCEPTION " + ex.GetType().Name + " " + ex.Message); L(ex.StackTrace); fail++; } + finally + { + WL.PixelArt.PixelCameraRig.Teardown("probe end"); + WL.PixelArt.WLPixelCameraSettings.RuntimeDisabled = false; + for (int i = 0; i < mobs.Count; i++) if (mobs[i] != null) UnityEngine.Object.DestroyImmediate(mobs[i]); + if (pcGo != null) UnityEngine.Object.DestroyImmediate(pcGo); + if (camGo != null) UnityEngine.Object.DestroyImmediate(camGo); + if (mapGo != null) UnityEngine.Object.DestroyImmediate(mapGo); + if (lightGo != null) UnityEngine.Object.DestroyImmediate(lightGo); + var after = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); + L("씬 정리 후: dirty=" + after.isDirty + " rootCount=" + after.rootCount + " (저장 0)"); + } + + L(""); + L("RESULT " + (fail == 0 ? "PASS" : "FAIL") + " " + pass + "/" + (pass + fail)); + var outPath = kSnap; + System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(outPath)); + System.IO.File.WriteAllText(outPath, sb.ToString(), new System.Text.UTF8Encoding(false)); + return sb.ToString(); + } + + // ── A. 표 ① 보조 실측 ──────────────────────────────────────────────────── + static void SectionA() + { + L(""); + L("## A. 원본 카메라 · UI 캔버스 실측"); + var camPf = UnityEditor.AssetDatabase.LoadAssetAtPath(kCam); + if (camPf == null) { L("FAIL Main Camera.prefab 로드 실패"); fail++; return; } + var c = camPf.GetComponent(); + var rc = camPf.GetComponent("RealCamera"); + var al = camPf.GetComponent(); + var mrv = camPf.GetComponent("MeshRendererVisibility"); + var ucd = camPf.GetComponent(); + L("Main Camera.prefab: tag=" + camPf.tag + " layer=" + camPf.layer + " parent=" + (camPf.transform.parent == null ? "none" : camPf.transform.parent.name) + + " children=" + camPf.transform.childCount); + L(" Camera: ortho=" + c.orthographic + " fov=" + c.fieldOfView + " size=" + c.orthographicSize + + " near=" + c.nearClipPlane + " far=" + c.farClipPlane + " depth=" + c.depth + + " mask=" + c.cullingMask + " clear=" + c.clearFlags + " hdr=" + c.allowHDR + " msaa=" + c.allowMSAA + + " occlusionCulling=" + c.useOcclusionCulling); + if (ucd != null) + L(" URP: type=" + ucd.renderType + " post=" + ucd.renderPostProcessing + " shadows=" + ucd.renderShadows + + " volumeMask=" + ucd.volumeLayerMask.value + " aa=" + ucd.antialiasing + + " stack=" + (ucd.cameraStack == null ? -1 : ucd.cameraStack.Count)); + L(" 컴포넌트: RealCamera=" + (rc != null) + " AudioListener=" + (al != null) + " MeshRendererVisibility=" + (mrv != null)); + Chk(rc != null && al != null, "원본 카메라 = RealCamera + AudioListener 보유(재부모화·비활성 금지 근거)", ""); + + var uiPf = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Res_Addr/MainUI/NewGameUI.prefab"); + if (uiPf != null) + { + var canvases = uiPf.GetComponentsInChildren(true); + L("NewGameUI.prefab 캔버스 " + canvases.Length + "개"); + for (int i = 0; i < canvases.Length; i++) + { + var cv = canvases[i]; + L(" [" + i + "] " + cv.name + " renderMode=" + cv.renderMode + + " worldCamera=" + (cv.worldCamera == null ? "null" : cv.worldCamera.name) + + " planeDistance=" + cv.planeDistance + " sortingOrder=" + cv.sortingOrder + " layer=" + cv.gameObject.layer); + } + var cams = uiPf.GetComponentsInChildren(true); + for (int i = 0; i < cams.Length; i++) + L(" UI camera: " + cams[i].name + " ortho=" + cams[i].orthographic + " depth=" + cams[i].depth + + " mask=" + cams[i].cullingMask + " clear=" + cams[i].clearFlags); + bool ssc = false; + for (int i = 0; i < canvases.Length; i++) if (canvases[i].renderMode == UnityEngine.RenderMode.ScreenSpaceCamera) ssc = true; + Chk(ssc, "인게임 UI 캔버스 = Screen Space - Camera(UICamera) → 원본 카메라를 끄면 UI 가 사라진다", ""); + } + else { L("FAIL NewGameUI.prefab 로드 실패"); fail++; } + } + + // ── 씬 조립 ────────────────────────────────────────────────────────────── + static void BuildScene(ref UnityEngine.GameObject mapGo, ref UnityEngine.GameObject pcGo, + ref UnityEngine.GameObject camGo, ref UnityEngine.GameObject lightGo, + System.Collections.Generic.List mobs) + { + L(""); + L("## B. 임시 씬(추가 로드 · 저장 0)"); + + var mapPf = UnityEditor.AssetDatabase.LoadAssetAtPath(kMap); + if (mapPf != null) { mapGo = UnityEngine.Object.Instantiate(mapPf); mapGo.name = "__WL814b_Map"; mapGo.hideFlags = UnityEngine.HideFlags.HideAndDontSave; } + L("맵 " + (mapGo == null ? "실패" : mapGo.name + " renderers=" + mapGo.GetComponentsInChildren(true).Length)); + + // 지면 y 찾기 + 소품이 가장 많은 앵커 고르기(룩 캡처라 배경이 비어 있으면 안 된다) + UnityEngine.Physics.SyncTransforms(); + var rends = mapGo == null ? new UnityEngine.Renderer[0] : mapGo.GetComponentsInChildren(true); + // 소품이 실제로 모여 있는 곳을 찾는다 — 소품 중심들 중 반경 10 m 이웃이 가장 많은 지점 + var cands = new System.Collections.Generic.List(); + for (int r = 0; r < rends.Length; r++) + { + if (rends[r] == null) continue; + var b = rends[r].bounds; + if (b.size.y < 1.0f || b.size.y > 20f) continue; // 지형/바닥/거대 오브젝트 제외 + if (b.center.y > 6f) continue; // 언덕 위·공중 제외 + cands.Add(b.center); + } + UnityEngine.Vector3 pcPos = new UnityEngine.Vector3(139f, 0.8f, -20f); + int bestCount = -1; + for (int i = 0; i < cands.Count; i++) + { + int n = 0; + for (int j = 0; j < cands.Count; j++) + if ((cands[j] - cands[i]).sqrMagnitude < 100f) n++; // 반경 10 m + if (n > bestCount) { bestCount = n; pcPos = cands[i]; } + } + string bestHit = "미검출"; + UnityEngine.RaycastHit gh; + if (UnityEngine.Physics.Raycast(new UnityEngine.Vector3(pcPos.x, pcPos.y + 100f, pcPos.z), UnityEngine.Vector3.down, out gh, 400f)) + { pcPos.y = gh.point.y; bestHit = gh.collider.name; } + L(" 소품 후보 " + cands.Count + "개 · 가장 밀집한 지점 반경 10 m 이웃 " + bestCount + "개"); + L("PC 위치 " + pcPos.ToString("F2") + " · 반경 10 m 소품 " + bestCount + "개 (지면 " + bestHit + ")"); + + var pcPf = UnityEditor.AssetDatabase.LoadAssetAtPath(kPc); + if (pcPf != null) + { + pcGo = UnityEngine.Object.Instantiate(pcPf); + pcGo.name = "__WL814b_PC"; + pcGo.hideFlags = UnityEngine.HideFlags.HideAndDontSave; + pcGo.transform.position = pcPos; + pcGo.transform.rotation = UnityEngine.Quaternion.Euler(0f, 200f, 0f); + StripBehaviours(pcGo); + L("PC 포즈: " + PoseIdle(pcGo)); + } + L("PC " + (pcGo == null ? "실패" : "ok")); + + // 잡몹 3 + string[] mobPaths = { + "Assets/Res_Addr/Mobs/Mob/Anto_A.prefab", + "Assets/Res_Addr/Mobs/Mob/Anto_B.prefab", + "Assets/Res_Addr/Mobs/Mob/Angez_A.prefab", + }; + UnityEngine.Vector3[] mobOff = { + new UnityEngine.Vector3(2.2f, 0f, 1.6f), + new UnityEngine.Vector3(-2.4f, 0f, 0.8f), + new UnityEngine.Vector3(0.2f, 0f, 3.0f), + }; + for (int i = 0; i < mobPaths.Length; i++) + { + var pf = UnityEditor.AssetDatabase.LoadAssetAtPath(mobPaths[i]); + if (pf == null) continue; + var g = UnityEngine.Object.Instantiate(pf); + g.name = "__WL814b_Mob" + i; + g.hideFlags = UnityEngine.HideFlags.HideAndDontSave; + var p = pcPos + mobOff[i]; + UnityEngine.RaycastHit mh; + if (UnityEngine.Physics.Raycast(new UnityEngine.Vector3(p.x, 200f, p.z), UnityEngine.Vector3.down, out mh, 500f)) p.y = mh.point.y; + g.transform.position = p; + g.transform.rotation = UnityEngine.Quaternion.Euler(0f, 20f + i * 90f, 0f); + StripBehaviours(g); + PoseIdle(g); + mobs.Add(g); + } + L("잡몹 " + mobs.Count + "체"); + + lightGo = new UnityEngine.GameObject("__WL814b_Sun"); + lightGo.hideFlags = UnityEngine.HideFlags.HideAndDontSave; + var lt = lightGo.AddComponent(); + lt.type = UnityEngine.LightType.Directional; + lt.intensity = 1.1f; + lt.color = new UnityEngine.Color(1f, 0.97f, 0.92f); + lightGo.transform.rotation = UnityEngine.Quaternion.Euler(48f, 35f, 0f); + + // 원본 카메라 인스턴스 — 811o 구도(h 76 · d 3.0 · up 2.4)를 RealCamera 수식으로 직접 계산 + var camPf = UnityEditor.AssetDatabase.LoadAssetAtPath(kCam); + if (camPf == null) return; + camGo = UnityEngine.Object.Instantiate(camPf); + camGo.name = "__WL814b_MainCamera"; + camGo.hideFlags = UnityEngine.HideFlags.HideAndDontSave; + StripBehaviours(camGo); // RealCamera·MeshRendererVisibility 정지(트랜스폼은 우리가 잡는다) + var cam = camGo.GetComponent(); + cam.aspect = (float)W / H; + + const float camHeight = 76f, rotateAround = 347.21f, distanceAway = 3.0f, distanceUp = 2.4f; + var lookAt = new UnityEngine.Vector3(0f, 1.06f, 0f); + var rotv = UnityEngine.Quaternion.Euler(camHeight, rotateAround, 0f) * UnityEngine.Vector3.one; + var camPosition = pcPos + UnityEngine.Vector3.up * distanceUp - rotv * distanceAway; + camGo.transform.position = camPosition; + s_lookAtWorld = pcPos + lookAt; + camGo.transform.LookAt(s_lookAtWorld); + float dist = UnityEngine.Vector3.Distance(camPosition, pcPos + lookAt); + L("카메라(811o 구도) pos=" + camPosition.ToString("F3") + " euler=" + camGo.transform.eulerAngles.ToString("F2")); + L(" PC 주시점까지 거리 = " + dist.ToString("F3") + " m → 원근 fov 60 의 반높이 = " + (dist * UnityEngine.Mathf.Tan(30f * UnityEngine.Mathf.Deg2Rad)).ToString("F3") + " m"); + } + + /// 에디트 모드에서는 Animator 가 돌지 않아 T 포즈가 된다 → idle 클립을 1프레임 샘플링한다. + static string PoseIdle(UnityEngine.GameObject go) + { + var anim = go.GetComponentInChildren(true); + if (anim == null || anim.runtimeAnimatorController == null) return "Animator 없음(T 포즈)"; + var clips = anim.runtimeAnimatorController.animationClips; + if (clips == null || clips.Length == 0) return "클립 0(T 포즈)"; + UnityEngine.AnimationClip pick = null; + for (int i = 0; i < clips.Length; i++) + { + if (clips[i] == null) continue; + var n = clips[i].name.ToLower(); + if (n.Contains("idle") || n.Contains("wait") || n.Contains("stand")) { pick = clips[i]; break; } + } + if (pick == null) pick = clips[0]; + pick.SampleAnimation(anim.gameObject, 0.4f); + return pick.name + " @0.4s (" + clips.Length + "클립)"; + } + + /// 임시 씬에서 원본 로직이 돌지 않게 MonoBehaviour 를 전부 끈다(에셋 무변경 · 인스턴스만). + static void StripBehaviours(UnityEngine.GameObject go) + { + var all = go.GetComponentsInChildren(true); + for (int i = 0; i < all.Length; i++) + { + if (all[i] == null) continue; + if (all[i] is UnityEngine.Rendering.Universal.UniversalAdditionalCameraData) continue; + try { all[i].enabled = false; } catch { } + } + } + + // ── B/C/D. 조립 · 복원 · 매핑 오차 ────────────────────────────────────── + static void SectionBCD(UnityEngine.Camera cam, UnityEngine.GameObject pcGo) + { + L(""); + L("## B. 리그 조립"); + var cfg = MakeCfg(3.8f, 480, false); + if (cfg == null) { L("FAIL SO/프리팹 없음 — 중단"); fail++; return; } + + string before = WL.PixelArt.PixelCameraRig.CurrentSummary(cam); + int origMask = cam.cullingMask; + L("조립 전 원본 카메라: " + before); + + bool ok = WL.PixelArt.PixelCameraRig.Assemble(cfg, cam); + Chk(ok && WL.PixelArt.PixelCameraRig.IsAssembled, "조립 성공", WL.PixelArt.PixelCameraRig.LastLog); + if (!ok) return; + + var rig = WL.PixelArt.PixelCameraRig.RigRoot; + var gameCam = WL.PixelArt.PixelCameraRig.GameCamera; + var viewCam = WL.PixelArt.PixelCameraRig.ViewCamera; + var mgr = WL.PixelArt.PixelCameraRig.Manager; + var proxy = WL.PixelArt.PixelCameraRig.Proxy; + + L("리그 구조:"); + Dump(rig.transform, 1); + L("프록시: " + (proxy == null ? "null" : proxy.name + " parent=" + (proxy.parent == null ? "none" : proxy.parent.name) + + " worldPos=" + proxy.position.ToString("F4") + " camPos=" + cam.transform.position.ToString("F4"))); + Chk(proxy != null && (proxy.position - cam.transform.position).sqrMagnitude < 1e-8f, + "프록시 월드 위치 == 원본 카메라 위치(지연 0)", ""); + Chk(proxy != null && UnityEngine.Quaternion.Angle(proxy.rotation, cam.transform.rotation) < 1e-3f, + "프록시 회전 == 원본 카메라 회전", ""); + + string after = WL.PixelArt.PixelCameraRig.CurrentSummary(cam); + L("조립 후 원본 카메라: " + after); + Chk(cam.orthographic, "원본 카메라 직교 전환", "size=" + cam.orthographicSize); + Chk(cam.cullingMask == 0, "원본 카메라 월드 미렌더(cullingMask 0)", "mask=" + cam.cullingMask); + Chk(cam.tag == "MainCamera" && cam.enabled, "MainCamera 태그·enabled 유지(Camera.main 보존)", "tag=" + cam.tag); + + // Critter 를 1프레임 강제로 돌린다(에디트 모드에는 LateUpdate 가 안 올 수 있다) + viewCam.aspect = (float)W / H; + mgr.SendMessage("LateUpdate", UnityEngine.SendMessageOptions.DontRequireReceiver); + + var rt = gameCam.targetTexture; + L("게임 카메라: ortho=" + gameCam.orthographic + " size=" + gameCam.orthographicSize.ToString("F4") + + " mask=" + gameCam.cullingMask + " depth=" + gameCam.depth + + " RT=" + (rt == null ? "null" : rt.width + "×" + rt.height + " filter=" + rt.filterMode + " fmt=" + rt.format)); + L("뷰 카메라: ortho=" + viewCam.orthographic + " size=" + viewCam.orthographicSize.ToString("F4") + + " mask=" + viewCam.cullingMask + " near=" + viewCam.nearClipPlane + " far=" + viewCam.farClipPlane + + " localPos=" + viewCam.transform.localPosition.ToString("F5")); + L("Critter: GameResolution=" + mgr.GameResolution + " zoom=" + mgr.GameCameraZoom.ToString("F5") + + " viewZoom=" + mgr.ViewCameraZoom + " grid=" + mgr.VoxelGridMovement + " sub=" + mgr.SubpixelAdjustments + + " followRot=" + mgr.FollowRotation); + Chk(rt != null && rt.height == 480 && rt.filterMode == UnityEngine.FilterMode.Point, + "저해상도 RT 480줄 · 포인트 필터", rt == null ? "null" : rt.width + "×" + rt.height); + Chk(gameCam.cullingMask == (origMask & ~(1 << cfg.rigLayer)), + "게임 카메라 = 원본 cullingMask 승계", "orig=" + origMask + " game=" + gameCam.cullingMask); + Chk((gameCam.cullingMask & (1 << cfg.rigLayer)) == 0, "게임 카메라가 픽셀 쿼드를 다시 그리지 않는다(리그 레이어 제외)", ""); + Chk(viewCam.cullingMask == (1 << cfg.rigLayer), "뷰 카메라는 픽셀 쿼드만 그린다", "mask=" + viewCam.cullingMask); + + // ── D. 매핑 오차 + L(""); + L("## D. 매핑 오차 — Camera.main 투영 vs 실제 화면(1080×1920 · px)"); + MappingTable(cam, gameCam, viewCam, mgr, pcGo); + + // ── C. 복원 + L(""); + L("## C. 복원"); + var rtRef = gameCam.targetTexture; + WL.PixelArt.PixelCameraRig.Teardown("probe C"); + string restored = WL.PixelArt.PixelCameraRig.CurrentSummary(cam); + L("복원 후 원본 카메라: " + restored); + Chk(restored == before, "원본 카메라 값 스냅샷 == 복원값(문자열 완전 일치)", restored == before ? "" : "\n before=" + before + "\n after =" + restored); + Chk(!WL.PixelArt.PixelCameraRig.IsAssembled, "리그 오브젝트 0", ""); + Chk(rtRef == null, "RT 참조 해제(Release + Destroy)", "rt=" + (rtRef == null ? "null" : "alive")); + int strays = 0; + var left = UnityEngine.Object.FindObjectsByType(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None); + strays = left == null ? 0 : left.Length; + Chk(strays == 0, "씬에 PixelCameraManager 잔재 0", "found=" + strays); + int proxyLeft = 0; + for (int i = 0; i < cam.transform.childCount; i++) if (cam.transform.GetChild(i).name == WL.PixelArt.PixelCameraRig.ProxyName) proxyLeft++; + Chk(proxyLeft == 0, "원본 카메라 자식 프록시 0", "found=" + proxyLeft); + + var mat = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/3DPixelCamera/URP/UpscaleMaterialURP.mat"); + bool matClean = mat == null || !mat.HasProperty("_LowResTexture") || mat.GetTexture("_LowResTexture") == null; + Chk(matClean, "디스크 UpscaleMaterialURP.mat 의 _LowResTexture 오염 0(런타임 인스턴스 사용)", + mat == null ? "mat=null" : ("tex=" + (mat.GetTexture("_LowResTexture") == null ? "null" : mat.GetTexture("_LowResTexture").name))); + } + + static void MappingTable(UnityEngine.Camera src, UnityEngine.Camera gameCam, UnityEngine.Camera viewCam, + PixelCamera.PixelCameraManager mgr, UnityEngine.GameObject pcGo) + { + var quad = FindQuad(); + if (quad == null) { L("FAIL 픽셀 쿼드를 못 찾음"); fail++; return; } + var rt = gameCam.targetTexture; + if (rt == null) { L("FAIL RT 없음"); fail++; return; } + + var basePos = pcGo != null ? pcGo.transform.position : src.transform.position + src.transform.forward * 6f; + var pts = new UnityEngine.Vector3[] + { + basePos, + basePos + new UnityEngine.Vector3(0f, 1.7f, 0f), + basePos + new UnityEngine.Vector3(1.8f, 0.2f, 1.4f), + basePos + new UnityEngine.Vector3(-2.1f, 1.0f, 1.0f), + basePos + new UnityEngine.Vector3(0.4f, 0.6f, 2.6f), + }; + + L(" # | world | Camera.main px | 실제 화면 px | 오차 px | RT양자화 포함 오차 px"); + float maxErr = 0f, maxErrQ = 0f, sumErr = 0f, sumErrQ = 0f; + for (int i = 0; i < pts.Length; i++) + { + var p = pts[i]; + var vSrc = src.WorldToViewportPoint(p); + var expect = new UnityEngine.Vector2(vSrc.x * W, vSrc.y * H); + + var vGame = gameCam.WorldToViewportPoint(p); + var actual = ViewportToScreen(vGame.x, vGame.y, quad, viewCam); + + float qx = (UnityEngine.Mathf.Floor(vGame.x * rt.width) + 0.5f) / rt.width; + float qy = (UnityEngine.Mathf.Floor(vGame.y * rt.height) + 0.5f) / rt.height; + var actualQ = ViewportToScreen(qx, qy, quad, viewCam); + + float e = UnityEngine.Vector2.Distance(expect, actual); + float eq = UnityEngine.Vector2.Distance(expect, actualQ); + maxErr = UnityEngine.Mathf.Max(maxErr, e); maxErrQ = UnityEngine.Mathf.Max(maxErrQ, eq); + sumErr += e; sumErrQ += eq; + L(" " + (i + 1) + " | " + p.ToString("F2") + + " | (" + expect.x.ToString("F1") + "," + expect.y.ToString("F1") + ")" + + " | (" + actual.x.ToString("F1") + "," + actual.y.ToString("F1") + ")" + + " | " + e.ToString("F2") + + " | " + eq.ToString("F2")); + } + L(" 최대 " + maxErr.ToString("F2") + " px · 평균 " + (sumErr / pts.Length).ToString("F2") + + " px (연속) / 최대 " + maxErrQ.ToString("F2") + " px · 평균 " + (sumErrQ / pts.Length).ToString("F2") + " px (RT 양자화 포함)"); + L(" 참고: 1 RT 픽셀 = 화면 " + ((float)H / rt.height).ToString("F2") + " px(세로) · " + ((float)W / rt.width).ToString("F2") + " px(가로)"); + Chk(maxErr <= 2.0f, "연속 매핑 오차 ≤ 2 px (compensateViewZoom 보정 확인)", "max=" + maxErr.ToString("F2") + " px"); + Chk(maxErrQ <= (float)H / rt.height, "RT 양자화 포함 오차 ≤ 업스케일 1픽셀", "max=" + maxErrQ.ToString("F2") + " px"); + } + + static UnityEngine.Vector2 ViewportToScreen(float vx, float vy, UnityEngine.Transform quad, UnityEngine.Camera viewCam) + { + var quadLocal = new UnityEngine.Vector3(vx - 0.5f, vy - 0.5f, 0f); + var quadWorld = quad.TransformPoint(quadLocal); + var vView = viewCam.WorldToViewportPoint(quadWorld); + return new UnityEngine.Vector2(vView.x * W, vView.y * H); + } + + static UnityEngine.Transform FindQuad() + { + var rig = WL.PixelArt.PixelCameraRig.RigRoot; + if (rig == null) return null; + var uc = rig.GetComponentInChildren(true); + return uc == null ? null : uc.transform; + } + + static void Dump(UnityEngine.Transform t, int depth) + { + var line = new System.Text.StringBuilder(); + line.Append(' ', depth * 2).Append("- ").Append(t.name).Append(" layer=").Append(t.gameObject.layer); + var comps = t.GetComponents(); + line.Append(" ["); + for (int i = 0; i < comps.Length; i++) if (comps[i] != null) line.Append(comps[i].GetType().Name).Append(' '); + line.Append("]"); + line.Append(" lp=").Append(t.localPosition.ToString("F4")).Append(" ls=").Append(t.localScale.ToString("F4")); + L(line.ToString()); + for (int i = 0; i < t.childCount; i++) Dump(t.GetChild(i), depth + 1); + } + + // ── E. GC ──────────────────────────────────────────────────────────────── + static void SectionE(UnityEngine.Camera cam) + { + L(""); + L("## E. GC (200k 회)"); + var probeGo = new UnityEngine.GameObject("__WL814b_MirrorProbe"); + probeGo.hideFlags = UnityEngine.HideFlags.HideAndDontSave; + var mirror = probeGo.AddComponent(); + mirror.Source = cam.transform; + + System.GC.Collect(); + long m0 = System.GC.GetAllocatedBytesForCurrentThread(); + long t0 = System.GC.GetTotalMemory(false); + int g0 = System.GC.CollectionCount(0); + for (int i = 0; i < 200000; i++) mirror.Mirror(); + long m1 = System.GC.GetAllocatedBytesForCurrentThread(); + long t1 = System.GC.GetTotalMemory(false); + int g1 = System.GC.CollectionCount(0); + L("프록시 미러 ×200k: thread Δ" + (m1 - m0) + " B · total Δ" + (t1 - t0) + " B · gen0 " + (g1 - g0)); + Chk(m1 - m0 == 0, "프록시 미러 GC 0 B", "Δ=" + (m1 - m0)); + UnityEngine.Object.DestroyImmediate(probeGo); + + var cfg = MakeCfg(3.8f, 480, false); + WL.PixelArt.PixelCameraRig.Assemble(cfg, cam); + System.GC.Collect(); + long s0 = System.GC.GetAllocatedBytesForCurrentThread(); + for (int i = 0; i < 200000; i++) WL.PixelArt.PixelCameraRig.ProbeSnapTick(); + long s1 = System.GC.GetAllocatedBytesForCurrentThread(); + L("회전 스냅 판정 ×200k: thread Δ" + (s1 - s0) + " B"); + Chk(s1 - s0 == 0, "회전 스냅 판정 GC 0 B", "Δ=" + (s1 - s0)); + WL.PixelArt.PixelCameraRig.Teardown("probe E"); + } + + // ── F. C8 ──────────────────────────────────────────────────────────────── + static void SectionF(UnityEngine.Camera cam) + { + L(""); + L("## F. C8 롤백"); + var so = WL.PixelArt.WLPixelCameraSettings.Instance; + Chk(so != null, "SO 로드(Resources/WL/WLPixelCameraSettings)", so == null ? "null" : "enabled=" + so.enabled); + + string before = WL.PixelArt.PixelCameraRig.CurrentSummary(cam); + var cfg = MakeCfg(3.8f, 480, false); + WL.PixelArt.PixelCameraRig.Assemble(cfg, cam); + Chk(WL.PixelArt.PixelCameraRig.IsAssembled, "조립됨(C8 전)", ""); + + WL.PixelArt.WLPixelCameraSettings.RuntimeDisabled = true; + Chk(!WL.PixelArt.WLPixelCameraSettings.Enabled, "RuntimeDisabled → Enabled=false", ""); + WL.PixelArt.PixelCameraRig.Tick(); // Active=false → 즉시 Teardown + Chk(!WL.PixelArt.PixelCameraRig.IsAssembled, "Tick 1회에 리그 해체", ""); + string after = WL.PixelArt.PixelCameraRig.CurrentSummary(cam); + Chk(after == before, "C8 복원값 == 원값", after == before ? "" : "\n before=" + before + "\n after =" + after); + + WL.PixelArt.PixelCameraRig.Tick(); // 재호출해도 조립 0 + Chk(!WL.PixelArt.PixelCameraRig.IsAssembled, "C8 상태에서 재조립 0", ""); + WL.PixelArt.WLPixelCameraSettings.RuntimeDisabled = false; + } + + // ── G. 캡처 ────────────────────────────────────────────────────────────── + static void SectionG(UnityEngine.Camera cam) + { + L(""); + L("## G. 룩 캡처 1080×1920 → " + kOutDir); + L(CaptureControl(cam, "look_00_persp_original")); + L(CaptureRig(cam, 3.8f, 480, "look_01_ortho38_px480")); + L(CaptureRig(cam, 3.8f, 360, "look_02_ortho38_px360")); + L(CaptureRig(cam, 4.6f, 480, "look_03_ortho46_px480")); + // 보너스 — 811o 구도의 실측 거리(카메라→주시점)에서 원근 fov 60 과 PC 평면 크기가 정확히 같아지는 ortho + float matched = UnityEngine.Vector3.Distance(cam.transform.position, s_lookAtWorld) * UnityEngine.Mathf.Tan(30f * UnityEngine.Mathf.Deg2Rad); + L(CaptureRig(cam, matched, 480, "look_04_orthoMatched_px480") + " ← 실측 정합값 ortho " + matched.ToString("F3")); + } + + static string CaptureControl(UnityEngine.Camera cam, string tag) + { + var rt = new UnityEngine.RenderTexture(W, H, 24, UnityEngine.RenderTextureFormat.ARGB32); + var prevTarget = cam.targetTexture; + float prevAspect = cam.aspect; + cam.aspect = (float)W / H; + cam.targetTexture = rt; + cam.Render(); + cam.targetTexture = prevTarget; + cam.aspect = prevAspect; + string path = WritePng(rt, tag); + rt.Release(); UnityEngine.Object.DestroyImmediate(rt); + return " 대조(원근 fov " + cam.fieldOfView + ") → " + path; + } + + static string CaptureRig(UnityEngine.Camera cam, float orthoSize, int pixelHeight, string tag) + { + var cfg = MakeCfg(orthoSize, pixelHeight, false); // viewCameraInMainStack=false → 뷰 카메라를 Base 로 직접 렌더 + if (cfg == null) return " FAIL cfg"; + if (!WL.PixelArt.PixelCameraRig.Assemble(cfg, cam)) return " FAIL assemble " + tag; + + var gameCam = WL.PixelArt.PixelCameraRig.GameCamera; + var viewCam = WL.PixelArt.PixelCameraRig.ViewCamera; + var mgr = WL.PixelArt.PixelCameraRig.Manager; + + var cap = new UnityEngine.RenderTexture(W, H, 24, UnityEngine.RenderTextureFormat.ARGB32); + viewCam.aspect = (float)W / H; + viewCam.targetTexture = cap; + mgr.SendMessage("LateUpdate", UnityEngine.SendMessageOptions.DontRequireReceiver); + mgr.SendMessage("LateUpdate", UnityEngine.SendMessageOptions.DontRequireReceiver); // RT 생성 후 위치·줌 확정 + + var lowRt = gameCam.targetTexture; + gameCam.Render(); // 저해상도 RT 를 채운다 + viewCam.Render(); // 쿼드를 1080×1920 으로 업스케일 + + string path = WritePng(cap, tag); + string info = " ortho " + orthoSize.ToString("0.##") + " × px " + pixelHeight + + " → RT " + (lowRt == null ? "null" : lowRt.width + "×" + lowRt.height) + + " · gameZoom " + mgr.GameCameraZoom.ToString("F4") + + " · viewSize " + viewCam.orthographicSize.ToString("F4") + + " → " + path; + + viewCam.targetTexture = null; + cap.Release(); UnityEngine.Object.DestroyImmediate(cap); + WL.PixelArt.PixelCameraRig.Teardown("capture " + tag); + return info; + } + + static string WritePng(UnityEngine.RenderTexture rt, string tag) + { + var prev = UnityEngine.RenderTexture.active; + UnityEngine.RenderTexture.active = rt; + var tex = new UnityEngine.Texture2D(rt.width, rt.height, UnityEngine.TextureFormat.RGB24, false); + tex.ReadPixels(new UnityEngine.Rect(0, 0, rt.width, rt.height), 0, 0); + tex.Apply(); + UnityEngine.RenderTexture.active = prev; + var path = System.IO.Path.Combine(kOutDir, tag + ".png"); + System.IO.File.WriteAllBytes(path, UnityEngine.ImageConversion.EncodeToPNG(tex)); + UnityEngine.Object.DestroyImmediate(tex); + return path; + } + + // ── 임시 설정(디스크 SO 를 절대 건드리지 않는다) ───────────────────────── + static WL.PixelArt.WLPixelCameraSettings MakeCfg(float orthoSize, int pixelHeight, bool inStack) + { + var rig = UnityEditor.AssetDatabase.LoadAssetAtPath(kRig); + if (rig == null) return null; + var cfg = UnityEngine.ScriptableObject.CreateInstance(); + cfg.hideFlags = UnityEngine.HideFlags.HideAndDontSave; + cfg.pixelCameraSystemPrefab = rig; + cfg.orthoSize = orthoSize; + cfg.pixelHeight = pixelHeight; + cfg.viewCameraInMainStack = inStack; + cfg.verboseLog = false; + return cfg; + } +} diff --git a/AgentScripts/staging/WL814b/EDIT_PROBE.txt b/AgentScripts/staging/WL814b/EDIT_PROBE.txt new file mode 100644 index 000000000..e4915207a --- /dev/null +++ b/AgentScripts/staging/WL814b/EDIT_PROBE.txt @@ -0,0 +1,94 @@ +# WL-814b 프로브 — 2026-09-10 23:27:24 +unity=6000.3.23f1 · isPlaying=False + +## A. 원본 카메라 · UI 캔버스 실측 +Main Camera.prefab: tag=MainCamera layer=0 parent=none children=0 + Camera: ortho=False fov=60 size=5 near=0.3 far=1000 depth=5 mask=95 clear=Skybox hdr=True msaa=True occlusionCulling=False + URP: type=Base post=True shadows=False volumeMask=1 aa=None stack=0 + 컴포넌트: RealCamera=True AudioListener=True MeshRendererVisibility=False + PASS 원본 카메라 = RealCamera + AudioListener 보유(재부모화·비활성 금지 근거) +NewGameUI.prefab 캔버스 1개 + [0] NewGameUI renderMode=ScreenSpaceCamera worldCamera=Camera planeDistance=100 sortingOrder=0 layer=5 + UI camera: Camera ortho=True depth=6 mask=32 clear=Nothing + PASS 인게임 UI 캔버스 = Screen Space - Camera(UICamera) → 원본 카메라를 끄면 UI 가 사라진다 +현재 씬 = '' path='' dirty(before)=False rootCount=0 + +## B. 임시 씬(추가 로드 · 저장 0) +맵 __WL814b_Map renderers=1299 + 소품 후보 799개 · 가장 밀집한 지점 반경 10 m 이웃 36개 +PC 위치 (192.32, 1.99, -46.40) · 반경 10 m 소품 36개 (지면 Collider) +PC 포즈: Idle @0.4s (26클립) +PC ok +잡몹 3체 +카메라(811o 구도) pos=(190.198, 6.579, -50.608) euler=(36.79, 26.73, 0.00) + PC 주시점까지 거리 = 5.887 m → 원근 fov 60 의 반높이 = 3.399 m + +## B. 리그 조립 +조립 전 원본 카메라: ortho=0 size=5 fov=60 near=0.3 far=1000 depth=5 mask=95 clear=1 bg=0,0,0,1 hdr=1 msaa=1 occ=0 rt=0 type=0 post=1 shadow=0 vmask=1 aa=0 stack=0 + PASS 조립 성공 조립 — ortho 3.8 · RT 640×480 · zoom 3.8159 · layer 31 +리그 구조: + - WL_PixelCameraRig layer=31 [Transform ] lp=(190.1982, 6.5791, -50.6082) ls=(1.0000, 1.0000, 1.0000) + - PixelCameraTransform layer=31 [Transform ] lp=(0.0000, 0.0000, 0.0000) ls=(1.0000, 1.0000, 1.0000) + - PixelCamera layer=31 [Transform Camera PixelCameraManager UniversalAdditionalCameraData ] lp=(0.0000, 0.0000, 0.0000) ls=(1.0000, 1.0000, 1.0000) + - UpscaledDisplay layer=31 [Transform ] lp=(0.0000, 0.0000, -1.0000) ls=(1.0000, 1.0000, 1.0000) + - ViewCamera layer=31 [Transform Camera UniversalAdditionalCameraData CanvasViewCamera ] lp=(0.0000, 0.0086, -1.0000) ls=(1.0000, 1.0000, 1.0000) + - QuadCanvas layer=31 [Transform MeshFilter MeshRenderer UpscaledCanvas ] lp=(0.0000, 0.0000, 0.0000) ls=(19.8022, 10.0556, 1.0000) +프록시: WL_PixelFollow parent=__WL814b_MainCamera worldPos=(190.1982, 6.5791, -50.6082) camPos=(190.1982, 6.5791, -50.6082) + PASS 프록시 월드 위치 == 원본 카메라 위치(지연 0) + PASS 프록시 회전 == 원본 카메라 회전 +조립 후 원본 카메라: ortho=1 size=3.8 fov=60 near=0.3 far=1000 depth=5 mask=0 clear=2 bg=0,0,0,1 hdr=1 msaa=1 occ=0 rt=0 type=0 post=0 shadow=0 vmask=1 aa=0 stack=0 + PASS 원본 카메라 직교 전환 size=3.8 + PASS 원본 카메라 월드 미렌더(cullingMask 0) mask=0 + PASS MainCamera 태그·enabled 유지(Camera.main 보존) tag=MainCamera +게임 카메라: ortho=True size=3.8159 mask=95 depth=4 RT=270×480 filter=Point fmt=ARGB32 +뷰 카메라: ortho=True size=3.8000 mask=-2147483648 near=0 far=1001 localPos=(-0.00383, 0.00197, -1.00000) +Critter: GameResolution=(270, 480) zoom=3.81590 viewZoom=1 grid=True sub=True followRot=True + PASS 저해상도 RT 480줄 · 포인트 필터 270×480 + PASS 게임 카메라 = 원본 cullingMask 승계 orig=95 game=95 + PASS 게임 카메라가 픽셀 쿼드를 다시 그리지 않는다(리그 레이어 제외) + PASS 뷰 카메라는 픽셀 쿼드만 그린다 mask=-2147483648 + +## D. 매핑 오차 — Camera.main 투영 vs 실제 화면(1080×1920 · px) + # | world | Camera.main px | 실제 화면 px | 오차 px | RT양자화 포함 오차 px + 1 | (192.32, 1.99, -46.40) | (540.0,745.5) | (540.0,745.5) | 0.00 | 1.40 + 2 | (192.32, 3.69, -46.40) | (540.0,1089.5) | (540.0,1089.5) | 0.00 | 1.19 + 3 | (194.12, 2.19, -45.00) | (787.1,1097.7) | (787.1,1097.7) | 0.00 | 1.03 + 4 | (190.22, 2.99, -45.40) | (-47.5,940.1) | (-47.5,940.1) | 0.00 | 1.35 + 5 | (192.72, 2.59, -43.80) | (334.8,1245.5) | (334.8,1245.5) | 0.00 | 1.43 + 최대 0.00 px · 평균 0.00 px (연속) / 최대 1.43 px · 평균 1.28 px (RT 양자화 포함) + 참고: 1 RT 픽셀 = 화면 4.00 px(세로) · 4.00 px(가로) + PASS 연속 매핑 오차 ≤ 2 px (compensateViewZoom 보정 확인) max=0.00 px + PASS RT 양자화 포함 오차 ≤ 업스케일 1픽셀 max=1.43 px + +## C. 복원 +복원 후 원본 카메라: ortho=0 size=5 fov=60 near=0.3 far=1000 depth=5 mask=95 clear=1 bg=0,0,0,1 hdr=1 msaa=1 occ=0 rt=0 type=0 post=1 shadow=0 vmask=1 aa=0 stack=0 + PASS 원본 카메라 값 스냅샷 == 복원값(문자열 완전 일치) + PASS 리그 오브젝트 0 + PASS RT 참조 해제(Release + Destroy) rt=null + PASS 씬에 PixelCameraManager 잔재 0 found=0 + PASS 원본 카메라 자식 프록시 0 found=0 + PASS 디스크 UpscaleMaterialURP.mat 의 _LowResTexture 오염 0(런타임 인스턴스 사용) tex=null + +## E. GC (200k 회) +프록시 미러 ×200k: thread Δ0 B · total Δ0 B · gen0 0 + PASS 프록시 미러 GC 0 B Δ=0 +회전 스냅 판정 ×200k: thread Δ0 B + PASS 회전 스냅 판정 GC 0 B Δ=0 + +## F. C8 롤백 + PASS SO 로드(Resources/WL/WLPixelCameraSettings) enabled=True + PASS 조립됨(C8 전) + PASS RuntimeDisabled → Enabled=false + PASS Tick 1회에 리그 해체 + PASS C8 복원값 == 원값 + PASS C8 상태에서 재조립 0 + +## G. 룩 캡처 1080×1920 → E:\NerdNavis\nn_himminji\Screenshots_WL\WL814b + 대조(원근 fov 60) → E:\NerdNavis\nn_himminji\Screenshots_WL\WL814b\look_00_persp_original.png + ortho 3.8 × px 480 → RT 270×480 · gameZoom 3.8159 · viewSize 3.8000 → E:\NerdNavis\nn_himminji\Screenshots_WL\WL814b\look_01_ortho38_px480.png + ortho 3.8 × px 360 → RT 202×360 · gameZoom 3.8212 · viewSize 3.8000 → E:\NerdNavis\nn_himminji\Screenshots_WL\WL814b\look_02_ortho38_px360.png + ortho 4.6 × px 480 → RT 270×480 · gameZoom 4.6192 · viewSize 4.6000 → E:\NerdNavis\nn_himminji\Screenshots_WL\WL814b\look_03_ortho46_px480.png + ortho 3.4 × px 480 → RT 270×480 · gameZoom 3.4128 · viewSize 3.3986 → E:\NerdNavis\nn_himminji\Screenshots_WL\WL814b\look_04_orthoMatched_px480.png ← 실측 정합값 ortho 3.399 +씬 정리 후: dirty=False rootCount=0 (저장 0) + +RESULT PASS 28/28 diff --git a/Assets/3DPixelCamera/URP.meta b/Assets/3DPixelCamera/URP.meta new file mode 100644 index 000000000..b42537d64 --- /dev/null +++ b/Assets/3DPixelCamera/URP.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 89ba2272d61bfaf4f8e60603c1027381 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/3DPixelCamera/URP/DemoScene.unity b/Assets/3DPixelCamera/URP/DemoScene.unity new file mode 100644 index 000000000..597f44845 --- /dev/null +++ b/Assets/3DPixelCamera/URP/DemoScene.unity @@ -0,0 +1,1226 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &9044789 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9044793} + - component: {fileID: 9044792} + - component: {fileID: 9044791} + - component: {fileID: 9044790} + m_Layer: 0 + m_Name: Plane + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!64 &9044790 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9044789} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 5 + m_Convex: 0 + m_CookingOptions: 30 + m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &9044791 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9044789} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &9044792 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9044789} + m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &9044793 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9044789} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 2, y: 2, z: 2} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1086287180} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &117850981 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 117850982} + - component: {fileID: 117850985} + - component: {fileID: 117850984} + - component: {fileID: 117850983} + - component: {fileID: 117850986} + m_Layer: 0 + m_Name: Cube (1) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &117850982 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117850981} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -3.85, y: 0.194, z: 1.02} + m_LocalScale: {x: 2, y: 2, z: 2} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1086287180} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &117850983 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117850981} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &117850984 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117850981} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &117850985 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117850981} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &117850986 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117850981} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4798ff58957f62449d109e13a21fbba, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &520135022 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 520135024} + - component: {fileID: 520135023} + - component: {fileID: 520135025} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &520135023 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 520135022} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &520135024 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 520135022} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!114 &520135025 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 520135022} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Version: 3 + m_UsePipelineSettings: 1 + m_AdditionalLightsShadowResolutionTier: 2 + m_LightLayerMask: 1 + m_RenderingLayers: 1 + m_CustomShadowLayers: 0 + m_ShadowLayerMask: 1 + m_ShadowRenderingLayers: 1 + m_LightCookieSize: {x: 1, y: 1} + m_LightCookieOffset: {x: 0, y: 0} + m_SoftShadowQuality: 0 +--- !u!1 &623101536 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 4231759119073248400, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + m_PrefabInstance: {fileID: 1894754018} + m_PrefabAsset: {fileID: 0} +--- !u!114 &623101541 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 623101536} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c494d07a7bc3166488d4f75fed12a580, type: 3} + m_Name: + m_EditorClassIdentifier: + MoveSpeed: 10 + ViewScrollSpeed: 0.1 + GameScrollSpeed: 1 + DragSpeed: 0.5 + AutoRotateSpeed: 30 + DistanceToPivot: 30 + RotationQuantDegrees: 45 +--- !u!1 &1086287179 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1086287180} + m_Layer: 0 + m_Name: Environment Objects + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1086287180 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1086287179} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1.5, y: 1.5, z: 1.5} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 117850982} + - {fileID: 1735178365} + - {fileID: 1543652227} + - {fileID: 1282468167} + - {fileID: 1973597450} + - {fileID: 9044793} + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1282468166 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1282468167} + - component: {fileID: 1282468170} + - component: {fileID: 1282468169} + - component: {fileID: 1282468168} + - component: {fileID: 1282468171} + m_Layer: 0 + m_Name: Cube (3) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1282468167 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1282468166} + m_LocalRotation: {x: 0, y: 0.38268343, z: 0, w: 0.92387956} + m_LocalPosition: {x: 1.92, y: 0.33, z: 0.82} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1086287180} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 45, z: 0} +--- !u!65 &1282468168 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1282468166} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1282468169 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1282468166} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1282468170 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1282468166} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &1282468171 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1282468166} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4798ff58957f62449d109e13a21fbba, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1543652226 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1543652227} + - component: {fileID: 1543652230} + - component: {fileID: 1543652229} + - component: {fileID: 1543652228} + - component: {fileID: 1543652231} + m_Layer: 0 + m_Name: Cube (2) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1543652227 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543652226} + m_LocalRotation: {x: 0, y: 0.38268343, z: 0, w: 0.92387956} + m_LocalPosition: {x: 3.65, y: 1.96, z: 1.79} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1086287180} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 45, z: 0} +--- !u!65 &1543652228 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543652226} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1543652229 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543652226} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1543652230 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543652226} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &1543652231 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1543652226} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4798ff58957f62449d109e13a21fbba, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1735178364 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1735178365} + - component: {fileID: 1735178368} + - component: {fileID: 1735178367} + - component: {fileID: 1735178366} + - component: {fileID: 1735178369} + m_Layer: 0 + m_Name: Cylinder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1735178365 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1735178364} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: -0.5, z: 3.64} + m_LocalScale: {x: 2, y: 2, z: 2} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1086287180} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!136 &1735178366 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1735178364} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5000001 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0.000000059604645, y: 0, z: -0.00000008940697} +--- !u!23 &1735178367 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1735178364} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1735178368 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1735178364} + m_Mesh: {fileID: 10206, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &1735178369 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1735178364} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4798ff58957f62449d109e13a21fbba, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1748296576 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 6842119547268722464, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + m_PrefabInstance: {fileID: 1894754018} + m_PrefabAsset: {fileID: 0} +--- !u!20 &1748296581 stripped +Camera: + m_CorrespondingSourceObject: {fileID: 1798342755243477739, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + m_PrefabInstance: {fileID: 1894754018} + m_PrefabAsset: {fileID: 0} +--- !u!114 &1748296582 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1748296576} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 61da2c9a624d7e440994f25060697d82, type: 3} + m_Name: + m_EditorClassIdentifier: + ViewCamera: {fileID: 1748296581} +--- !u!1001 &1894754018 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + serializedVersion: 3 + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 1798342755243477739, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: orthographic size + value: 4.9722223 + objectReference: {fileID: 0} + - target: {fileID: 1813454538314249935, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalScale.x + value: 17.777779 + objectReference: {fileID: 0} + - target: {fileID: 1813454538314249935, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalScale.y + value: 10 + objectReference: {fileID: 0} + - target: {fileID: 2255326839739188927, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_Name + value: PixelCameraSystem + objectReference: {fileID: 0} + - target: {fileID: 2475294716756555193, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.x + value: 0.01019054 + objectReference: {fileID: 0} + - target: {fileID: 2475294716756555193, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.y + value: 0.0007158518 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_RootOrder + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.x + value: -1.3786983 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.z + value: -20.377922 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 3132409262940554809, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 7303396614074331432, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.y + value: 13.84 + objectReference: {fileID: 0} + - target: {fileID: 7303396614074331432, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.z + value: -0.87 + objectReference: {fileID: 0} + - target: {fileID: 7303396614074331432, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalRotation.w + value: 0.9659258 + objectReference: {fileID: 0} + - target: {fileID: 7303396614074331432, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalRotation.x + value: 0.2588191 + objectReference: {fileID: 0} + - target: {fileID: 7303396614074331432, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 30 + objectReference: {fileID: 0} + - target: {fileID: 8788124287499514057, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.x + value: -0.010190606 + objectReference: {fileID: 0} + - target: {fileID: 8788124287499514057, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.y + value: 13.845427 + objectReference: {fileID: 0} + - target: {fileID: 8788124287499514057, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalPosition.z + value: -0.88083076 + objectReference: {fileID: 0} + - target: {fileID: 8788124287499514057, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalRotation.w + value: 0.9659258 + objectReference: {fileID: 0} + - target: {fileID: 8788124287499514057, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_LocalRotation.x + value: 0.2588191 + objectReference: {fileID: 0} + - target: {fileID: 9205371885998440386, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + propertyPath: m_TargetTexture + value: + objectReference: {fileID: 1985181849} + m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: + - targetCorrespondingSourceObject: {fileID: 4231759119073248400, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + insertIndex: -1 + addedObject: {fileID: 623101541} + - targetCorrespondingSourceObject: {fileID: 6842119547268722464, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + insertIndex: -1 + addedObject: {fileID: 1748296582} + m_SourcePrefab: {fileID: 100100000, guid: e96cffa9d00b6b545adfeb26165952cc, type: 3} +--- !u!1 &1973597449 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1973597450} + - component: {fileID: 1973597453} + - component: {fileID: 1973597452} + - component: {fileID: 1973597451} + - component: {fileID: 1973597454} + m_Layer: 0 + m_Name: Sphere + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1973597450 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1973597449} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -5.94, y: 0.85, z: -1.74} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1086287180} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!135 &1973597451 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1973597449} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Radius: 0.5 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1973597452 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1973597449} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1973597453 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1973597449} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &1973597454 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1973597449} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4798ff58957f62449d109e13a21fbba, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!84 &1985181849 +RenderTexture: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_ImageContentsHash: + serializedVersion: 2 + Hash: 00000000000000000000000000000000 + m_ForcedFallbackFormat: 4 + m_DownscaleFallback: 0 + m_IsAlphaChannelOptional: 0 + serializedVersion: 5 + m_Width: 640 + m_Height: 360 + m_AntiAliasing: 1 + m_MipCount: -1 + m_DepthStencilFormat: 94 + m_ColorFormat: 4 + m_MipMap: 0 + m_GenerateMips: 1 + m_SRGB: 1 + m_UseDynamicScale: 0 + m_BindMS: 0 + m_EnableCompatibleFormat: 1 + m_TextureSettings: + serializedVersion: 2 + m_FilterMode: 0 + m_Aniso: 1 + m_MipBias: 0 + m_WrapU: 1 + m_WrapV: 1 + m_WrapW: 1 + m_Dimension: 2 + m_VolumeDepth: 1 + m_ShadowSamplingMode: 2 diff --git a/Assets/3DPixelCamera/URP/DemoScene.unity.meta b/Assets/3DPixelCamera/URP/DemoScene.unity.meta new file mode 100644 index 000000000..710fa0308 --- /dev/null +++ b/Assets/3DPixelCamera/URP/DemoScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 67fa8744e3c0f97478b2a6fd3292b65d +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/3DPixelCamera/URP/PixelCameraSystem.prefab b/Assets/3DPixelCamera/URP/PixelCameraSystem.prefab new file mode 100644 index 000000000..65c813bb1 --- /dev/null +++ b/Assets/3DPixelCamera/URP/PixelCameraSystem.prefab @@ -0,0 +1,496 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1532677598533230704 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7303396614074331432} + m_Layer: 0 + m_Name: PixelCameraTransform + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7303396614074331432 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1532677598533230704} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3132409262940554809} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2255326839739188927 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3132409262940554809} + m_Layer: 0 + m_Name: PixelCameraSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3132409262940554809 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2255326839739188927} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7303396614074331432} + - {fileID: 8788124287499514057} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &3474214803470865388 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1813454538314249935} + - component: {fileID: 5422343619921320258} + - component: {fileID: 418977516687070584} + - component: {fileID: 5593218058142784318} + m_Layer: 0 + m_Name: QuadCanvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1813454538314249935 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3474214803470865388} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 19.802168, y: 10.055555, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8987800775158610402} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &5422343619921320258 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3474214803470865388} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &418977516687070584 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3474214803470865388} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 0 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 1af8e993bbdb2f547989713359c47b1c, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &5593218058142784318 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3474214803470865388} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ab692ebf91361b44cbd447f7d7b5fddf, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &4231759119073248400 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8788124287499514057} + - component: {fileID: 9205371885998440386} + - component: {fileID: 6298985930916582049} + - component: {fileID: 4103191127918928509} + m_Layer: 0 + m_Name: PixelCamera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8788124287499514057 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4231759119073248400} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8987800775158610402} + m_Father: {fileID: 3132409262940554809} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!20 &9205371885998440386 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4231759119073248400} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!114 &6298985930916582049 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4231759119073248400} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a6fe4c3a8238df440bdf10c687b2537f, type: 3} + m_Name: + m_EditorClassIdentifier: + FollowedTransform: {fileID: 7303396614074331432} + VoxelGridMovement: 1 + SubpixelAdjustments: 1 + FollowRotation: 1 + resolutionSynchronizationMode: 0 + GameResolution: {x: 640, y: 360} + ControlGameZoom: 1 + GameCameraZoom: 5 + ViewCameraZoom: 1 +--- !u!114 &4103191127918928509 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4231759119073248400} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_RenderShadows: 1 + m_RequiresDepthTextureOption: 2 + m_RequiresOpaqueTextureOption: 2 + m_CameraType: 0 + m_Cameras: [] + m_RendererIndex: -1 + m_VolumeLayerMask: + serializedVersion: 2 + m_Bits: 1 + m_VolumeTrigger: {fileID: 0} + m_VolumeFrameworkUpdateModeOption: 2 + m_RenderPostProcessing: 0 + m_Antialiasing: 0 + m_AntialiasingQuality: 2 + m_StopNaN: 0 + m_Dithering: 0 + m_ClearDepth: 1 + m_AllowXRRendering: 1 + m_AllowHDROutput: 1 + m_UseScreenCoordOverride: 0 + m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0} + m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0} + m_RequiresDepthTexture: 0 + m_RequiresColorTexture: 0 + m_Version: 2 + m_TaaSettings: + quality: 3 + frameInfluence: 0.1 + jitterScale: 1 + mipBias: 0 + varianceClampScale: 0.9 + contrastAdaptiveSharpening: 0 +--- !u!1 &6842119547268722464 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2475294716756555193} + - component: {fileID: 1798342755243477739} + - component: {fileID: 439820793684178854} + - component: {fileID: 3231981177195013634} + - component: {fileID: 1032179972197267321} + m_Layer: 0 + m_Name: ViewCamera + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2475294716756555193 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6842119547268722464} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0.008579807, z: -1} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8987800775158610402} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!20 &1798342755243477739 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6842119547268722464} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0 + far clip plane: 1001 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!81 &439820793684178854 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6842119547268722464} + m_Enabled: 1 +--- !u!114 &3231981177195013634 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6842119547268722464} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_RenderShadows: 0 + m_RequiresDepthTextureOption: 2 + m_RequiresOpaqueTextureOption: 2 + m_CameraType: 0 + m_Cameras: [] + m_RendererIndex: -1 + m_VolumeLayerMask: + serializedVersion: 2 + m_Bits: 1 + m_VolumeTrigger: {fileID: 0} + m_VolumeFrameworkUpdateModeOption: 2 + m_RenderPostProcessing: 0 + m_Antialiasing: 0 + m_AntialiasingQuality: 2 + m_StopNaN: 0 + m_Dithering: 0 + m_ClearDepth: 1 + m_AllowXRRendering: 1 + m_AllowHDROutput: 1 + m_UseScreenCoordOverride: 0 + m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0} + m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0} + m_RequiresDepthTexture: 0 + m_RequiresColorTexture: 0 + m_Version: 2 + m_TaaSettings: + quality: 3 + frameInfluence: 0.1 + jitterScale: 1 + mipBias: 0 + varianceClampScale: 0.9 + contrastAdaptiveSharpening: 0 +--- !u!114 &1032179972197267321 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6842119547268722464} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: de5b95231816236418041ca173b33a29, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &7295925279294691889 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8987800775158610402} + m_Layer: 0 + m_Name: UpscaledDisplay + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8987800775158610402 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7295925279294691889} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -1} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2475294716756555193} + - {fileID: 1813454538314249935} + m_Father: {fileID: 8788124287499514057} + m_RootOrder: -1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/3DPixelCamera/URP/PixelCameraSystem.prefab.meta b/Assets/3DPixelCamera/URP/PixelCameraSystem.prefab.meta new file mode 100644 index 000000000..c9dcc70b4 --- /dev/null +++ b/Assets/3DPixelCamera/URP/PixelCameraSystem.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e96cffa9d00b6b545adfeb26165952cc +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/3DPixelCamera/URP/UpscaleMaterialURP.mat b/Assets/3DPixelCamera/URP/UpscaleMaterialURP.mat new file mode 100644 index 000000000..2b3e0dbc0 --- /dev/null +++ b/Assets/3DPixelCamera/URP/UpscaleMaterialURP.mat @@ -0,0 +1,135 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: UpscaleMaterialURP + m_Shader: {fileID: -6465566751694194690, guid: c63d04c1c20ea83498addf7813ae3dc5, + type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DownscaledTexture: + m_Texture: {fileID: 8400000, guid: b341653440931de4ba25940d113f4375, type: 2} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _LowResTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendOp: 0 + - _BumpScale: 1 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _QueueControl: 0 + - _QueueOffset: 0 + - _SampleGI: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &4363459520997935123 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 10 diff --git a/Assets/3DPixelCamera/URP/UpscaleMaterialURP.mat.meta b/Assets/3DPixelCamera/URP/UpscaleMaterialURP.mat.meta new file mode 100644 index 000000000..405bdedee --- /dev/null +++ b/Assets/3DPixelCamera/URP/UpscaleMaterialURP.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1af8e993bbdb2f547989713359c47b1c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/3DPixelCamera/URP/UpscaleShaderURP.shadergraph b/Assets/3DPixelCamera/URP/UpscaleShaderURP.shadergraph new file mode 100644 index 000000000..678e9ce23 --- /dev/null +++ b/Assets/3DPixelCamera/URP/UpscaleShaderURP.shadergraph @@ -0,0 +1,693 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "4b4aee54c62b40958070f4140352fba7", + "m_Properties": [ + { + "m_Id": "3ba9df8d7b064813844ee1a01ff30884" + } + ], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "5b7e26a64997477b8fceed79720cbe18" + } + ], + "m_Nodes": [ + { + "m_Id": "e89eafddf99b406dba0daa5373d685ee" + }, + { + "m_Id": "54acbcd866754623a9971b65c87753b5" + }, + { + "m_Id": "3a3ed0c7f46f423bb7e2448b2a885805" + }, + { + "m_Id": "b646594906c747a4a535fe5a190c267e" + }, + { + "m_Id": "8346d6ed11034b1785db95ef2e8bf371" + }, + { + "m_Id": "8d0d097456884c839b0e1bccbd948c83" + } + ], + "m_GroupDatas": [], + "m_StickyNoteDatas": [ + { + "m_Id": "2bcf8277985449668ed3ecc75283b25f" + } + ], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8346d6ed11034b1785db95ef2e8bf371" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "8d0d097456884c839b0e1bccbd948c83" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8d0d097456884c839b0e1bccbd948c83" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b646594906c747a4a535fe5a190c267e" + }, + "m_SlotId": 0 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": 878.666748046875, + "y": -616.0001220703125 + }, + "m_Blocks": [ + { + "m_Id": "e89eafddf99b406dba0daa5373d685ee" + }, + { + "m_Id": "54acbcd866754623a9971b65c87753b5" + }, + { + "m_Id": "3a3ed0c7f46f423bb7e2448b2a885805" + } + ] + }, + "m_FragmentContext": { + "m_Position": { + "x": 879.3333740234375, + "y": -363.3334655761719 + }, + "m_Blocks": [ + { + "m_Id": "b646594906c747a4a535fe5a190c267e" + } + ] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Shader Graphs", + "m_GraphPrecision": 0, + "m_PreviewMode": 2, + "m_OutputNode": { + "m_Id": "" + }, + "m_ActiveTargets": [ + { + "m_Id": "0d38844c2de34d5ba592090e3a320f9d" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "012c063cd77b4055a5d02d510505e55e", + "m_Id": 5, + "m_DisplayName": "G", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalTarget", + "m_ObjectId": "0d38844c2de34d5ba592090e3a320f9d", + "m_Datas": [], + "m_ActiveSubTarget": { + "m_Id": "82a2f491e31c4a83a8bfa01a377c3b68" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZTestMode": 4, + "m_ZWriteControl": 0, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CastShadows": true, + "m_ReceiveShadows": true, + "m_SupportsLODCrossFade": false, + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "1bd6c17f30d843c5bded4563c487ef31", + "m_Id": 6, + "m_DisplayName": "B", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "2bcf8277985449668ed3ecc75283b25f", + "m_Title": "Hello!", + "m_Content": "This shader is intended to display the game on a quad. The 'LowResTexture' is a low-resolution rendertexture of the game. A full-resolution camera then looks at said quad and performs adjustments to create subpixel movement.\n\nThis way you can have your FX, post-processing, gameobjects, and virtually everything rendered on low-resolution which creates significant boost in performance for GPU. \n\n*** Add \"post-post-processing\" here *** \n\nBecause this shader displays the final result of your game, you can adjust this shader to create your own effects on top of all that.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": 360.6666564941406, + "y": -648.0, + "width": 366.66668701171877, + "height": 226.00003051757813 + }, + "m_Group": { + "m_Id": "" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "3a3ed0c7f46f423bb7e2448b2a885805", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Tangent", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "95d25e4d952f48c38ba5e62dc3fab9cd" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Tangent" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Internal.Texture2DShaderProperty", + "m_ObjectId": "3ba9df8d7b064813844ee1a01ff30884", + "m_Guid": { + "m_GuidSerialized": "cdef0278-d3f3-407a-9b37-d7731b76ad2c" + }, + "m_Name": "LowResTexture", + "m_DefaultRefNameVersion": 0, + "m_RefNameGeneratedByDisplayName": "", + "m_DefaultReferenceName": "Texture2D_3ba9df8d7b064813844ee1a01ff30884", + "m_OverrideReferenceName": "_LowResTexture", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_DismissedVersion": 0, + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "m_Hidden": false, + "m_Value": { + "m_SerializedTexture": "{\"texture\":{\"fileID\":8400000,\"guid\":\"dc06a050ca5352e469850f311104ce88\",\"type\":2}}", + "m_Guid": "" + }, + "isMainTexture": false, + "useTilingAndOffset": false, + "m_Modifiable": true, + "m_DefaultType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "3e6a598eb5204f6287316d0d3809b215", + "m_Id": 7, + "m_DisplayName": "A", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "4da2c55cfe2e4cf9a6659081084573f0", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SamplerStateMaterialSlot", + "m_ObjectId": "5186d854ec8f4e55a948afefab209f95", + "m_Id": 3, + "m_DisplayName": "Sampler", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Sampler", + "m_StageCapability": 3, + "m_BareResource": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "54acbcd866754623a9971b65c87753b5", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Normal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "bdebc5a760f846638151adf9af8840ef" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Normal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "5b7e26a64997477b8fceed79720cbe18", + "m_Name": "", + "m_ChildObjectList": [ + { + "m_Id": "3ba9df8d7b064813844ee1a01ff30884" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "5c5be1888bc54fd2b3729d265949c03d", + "m_Id": 0, + "m_DisplayName": "Base Color", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 2, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "65e0744788694ef2a6997127e52e86df", + "m_Id": 0, + "m_DisplayName": "RGBA", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "RGBA", + "m_StageCapability": 2, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalUnlitSubTarget", + "m_ObjectId": "82a2f491e31c4a83a8bfa01a377c3b68" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "8346d6ed11034b1785db95ef2e8bf371", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 397.9999694824219, + "y": -323.3333435058594, + "width": 166.66665649414063, + "height": 33.99998474121094 + } + }, + "m_Slots": [ + { + "m_Id": "9314c3adf5944d85aecd153224b0d052" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "3ba9df8d7b064813844ee1a01ff30884" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SampleTexture2DNode", + "m_ObjectId": "8d0d097456884c839b0e1bccbd948c83", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Sample Texture 2D", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 579.9999389648438, + "y": -363.9999694824219, + "width": 186.66668701171876, + "height": 250.66668701171876 + } + }, + "m_Slots": [ + { + "m_Id": "65e0744788694ef2a6997127e52e86df" + }, + { + "m_Id": "fc04b5e5ba934388a44813680a77fbcc" + }, + { + "m_Id": "012c063cd77b4055a5d02d510505e55e" + }, + { + "m_Id": "1bd6c17f30d843c5bded4563c487ef31" + }, + { + "m_Id": "3e6a598eb5204f6287316d0d3809b215" + }, + { + "m_Id": "c81c4d76704d4e9abb6058defef68892" + }, + { + "m_Id": "dffb325305ee488f981ffcfee4bbe1fa" + }, + { + "m_Id": "5186d854ec8f4e55a948afefab209f95" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_TextureType": 0, + "m_NormalMapSpace": 1, + "m_EnableGlobalMipBias": true, + "m_MipSamplingMode": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Texture2DMaterialSlot", + "m_ObjectId": "9314c3adf5944d85aecd153224b0d052", + "m_Id": 0, + "m_DisplayName": "LowResTexture", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_BareResource": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "95d25e4d952f48c38ba5e62dc3fab9cd", + "m_Id": 0, + "m_DisplayName": "Tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Tangent", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "b646594906c747a4a535fe5a190c267e", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BaseColor", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "5c5be1888bc54fd2b3729d265949c03d" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BaseColor" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "bdebc5a760f846638151adf9af8840ef", + "m_Id": 0, + "m_DisplayName": "Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Normal", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Texture2DInputMaterialSlot", + "m_ObjectId": "c81c4d76704d4e9abb6058defef68892", + "m_Id": 1, + "m_DisplayName": "Texture", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Texture", + "m_StageCapability": 3, + "m_BareResource": false, + "m_Texture": { + "m_SerializedTexture": "{\"texture\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "m_DefaultType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "dffb325305ee488f981ffcfee4bbe1fa", + "m_Id": 2, + "m_DisplayName": "UV", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "UV", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "e89eafddf99b406dba0daa5373d685ee", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -81.33334350585938, + "y": -847.3334350585938, + "width": 200.0, + "height": 40.66668701171875 + } + }, + "m_Slots": [ + { + "m_Id": "4da2c55cfe2e4cf9a6659081084573f0" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Position" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "fc04b5e5ba934388a44813680a77fbcc", + "m_Id": 4, + "m_DisplayName": "R", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + diff --git a/Assets/3DPixelCamera/URP/UpscaleShaderURP.shadergraph.meta b/Assets/3DPixelCamera/URP/UpscaleShaderURP.shadergraph.meta new file mode 100644 index 000000000..811b5fdfe --- /dev/null +++ b/Assets/3DPixelCamera/URP/UpscaleShaderURP.shadergraph.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c63d04c1c20ea83498addf7813ae3dc5 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} diff --git a/Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset b/Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset new file mode 100644 index 000000000..d4cecf9ba --- /dev/null +++ b/Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset @@ -0,0 +1,39 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: aedb96845e568d44889723065b993c14, type: 3} + m_Name: WLPixelCameraSettings + m_EditorClassIdentifier: Assembly-CSharp::WL.PixelArt.WLPixelCameraSettings + enabled: 1 + verboseLog: 0 + assembleOnMapEnter: 1 + assembleInLobby: 0 + pollSeconds: 0.25 + pixelCameraSystemPrefab: {fileID: 2255326839739188927, guid: e96cffa9d00b6b545adfeb26165952cc, + type: 3} + rigLayer: 31 + proxyMode: 0 + orthoSize: 3.8 + pixelHeight: 480 + compensateViewZoom: 1 + voxelGridMovement: 1 + subpixelAdjustments: 1 + followRotation: 1 + controlGameZoom: 1 + viewCameraZoom: 1 + viewCameraInMainStack: 1 + disableSnapWhileRotating: 1 + rotationSnapOffDegPerSec: 30 + rotationSnapResumeSeconds: 0.25 + mainCameraCullingMask: 0 + mainCameraPostProcessingOff: 1 + copyPostProcessingToGameCamera: 1 + mainCameraSolidBlack: 1 diff --git a/Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset.meta b/Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset.meta new file mode 100644 index 000000000..5b42f5f2c --- /dev/null +++ b/Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6b6db3e9a69baba4381dc38c3c2c414f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/WL/PixelCamera.meta b/Assets/WL/PixelCamera.meta new file mode 100644 index 000000000..e40cbf426 --- /dev/null +++ b/Assets/WL/PixelCamera.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7bcfe795ab749ec4bad536c992cb5e70 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/WL/PixelCamera/PixelCameraRig.cs b/Assets/WL/PixelCamera/PixelCameraRig.cs new file mode 100644 index 000000000..ecca6b8ca --- /dev/null +++ b/Assets/WL/PixelCamera/PixelCameraRig.cs @@ -0,0 +1,711 @@ +// ───────────────────────────────────────────────────────────────────────────── +// PixelCameraRig.cs — Critter 3D Pixel Camera 를 인게임에서 런타임 조립/복원하는 WL 리그 +// +// PD 지시 #814(「Critter 3D Pixel Art Toolkit 으로 도트 게임처럼」) · 발주서 WL-814b §1-3 +// +// ■ 왜 이렇게 만들었나 (실측 근거 — 보고서 표 ①) +// · 원본 인게임 카메라는 `Assets/ResWork/Prefabs/Ingame/Main Camera.prefab`(tag MainCamera · fov 60 · 원근)이고 +// `Assets/Script/Util/RealCamera.cs` 가 **LateUpdate 에서** 트랜스폼을 쓴다. CamStatus 1/2 는 +// `Vector3.Lerp(transform.position, …)` = **현재 위치에서 보간**이라 누가 카메라 트랜스폼에 되쓰면 +// 그 값이 다음 프레임의 입력이 된다(피드백 루프). → 리그는 카메라 트랜스폼에 **절대 쓰지 않는다**. +// · `RealCamera.Shaking()` 은 `transform.localPosition` 을 쓴다(811gh 셰이크). 원본 카메라를 **재부모화하면 +// 셰이크 기준이 깨진다** → 재부모화 0. 대신 **원본 카메라의 자식**으로 빈 프록시를 하나 달아 +// Critter 가 그것을 따라가게 한다(지연 0 · 프레임당 비용 0 · 셰이크도 그대로 미러된다). +// · `MyValue.m_RealCamera` 는 `Camera.main.GetComponent()` 다 → 원본 카메라가 **계속 +// MainCamera 태그를 달고 enabled 여야** 한다(`Camera.main` 은 활성 카메라만 돌려준다). +// · 인게임 UI 캔버스는 **Screen Space - Camera(UICamera)** 이고 `NewGameUI.cs:38` 이 그 UICamera 를 +// **`Camera.main` 의 URP 카메라 스택에 Overlay 로** 넣는다 → 원본 카메라를 끄면 UI 가 사라진다. +// 그래서 원본 카메라는 화면 Base 로 남기고, Critter 뷰 카메라를 같은 스택의 **0번 Overlay** 로 끼운다. +// 스택 = [원본 Main Camera(Base · 월드 미렌더)] → [ViewCamera(Overlay · 픽셀 쿼드)] → [UICamera(Overlay · UI)] +// · `HUDBase.cs:28,55`(HP 바 · 데미지 숫자)와 `DSUtil.cs:859`·`InGameTouchInfo.cs:37` 은 전부 +// `Camera.main` 의 투영을 쓴다 → 원본 카메라를 **직교로 바꿔** 픽셀 카메라와 같은 투영을 갖게 한다. +// +// ■ 리그 구조 (Assemble 이 만든다 · 디스크 에셋 수정 0) +// WL_PixelCameraRig = PixelCameraSystem.prefab 인스턴스(루트 이름만 바꿈) +// ├─ PixelCameraTransform 프리팹 기본 followed(ChildOfCamera 모드에서는 쓰지 않는다 · 삭제하면 +// │ Critter 의 `parent.childCount` 권고에서 벗어나므로 그대로 둔다) +// └─ PixelCamera 직교 카메라 + PixelCameraManager · 저해상도 RT 로 월드를 그린다 +// └─ UpscaledDisplay +// ├─ QuadCanvas RT 를 붙인 쿼드(UpscaledCanvas) · rigLayer +// └─ ViewCamera 직교 · CanvasViewCamera(서브픽셀 보정) · rigLayer 만 그린다 +// Main Camera (원본 · 트랜스폼 무변경) +// └─ WL_PixelFollow 프록시(빈 오브젝트 · localPos 0 · localRot identity) +// +// ■ C8 롤백 +// `WLPixelCameraSettings.enabled = 0`(또는 `RuntimeDisabled`) → 다음 틱에 Teardown → 원본 카메라 값 +// (직교/사이즈/컬링/클리어/배경/near·far/fov/depth/포스트/스택)이 **스냅샷 그대로** 복원되고 리그 오브젝트 0 · RT 해제. +// +// 🔴 이 파일은 Debug.LogError / Debug.LogException 을 쓰지 않는다(813z · ErrorLogHookManager 팝업). +// 🔴 Assets/WL/ 에 .asmdef 를 만들지 말 것. +// ───────────────────────────────────────────────────────────────────────────── + +using UnityEngine; +using UnityEngine.Rendering.Universal; +using PixelCamera; + +namespace WL.PixelArt +{ + /// Critter 픽셀 카메라 리그의 조립·복원. 정적 · 전용 러너 1개. + public static class PixelCameraRig + { + public const string RigName = "WL_PixelCameraRig"; + public const string ProxyName = "WL_PixelFollow"; + + // ───────────────────────────────────────── 진단(프로브가 읽는다) + public static int Boundaries, Assembled, Restored, SkippedLobby, SkippedNoCam, SkippedNoPrefab, Faults; + public static string LastReason = "", LastLog = ""; + + /// 지금 리그가 조립돼 있는가. + public static bool IsAssembled { get { return s_rigRoot != null; } } + + /// 조립된 리그의 핵심 참조(프로브 전용). + public static GameObject RigRoot { get { return s_rigRoot; } } + public static Camera SourceCamera { get { return s_src; } } + public static Camera GameCamera { get { return s_gameCam; } } + public static Camera ViewCamera { get { return s_viewCam; } } + public static Transform Proxy { get { return s_proxy; } } + public static PixelCameraManager Manager { get { return s_mgr; } } + + /// 지금 회전 때문에 스냅이 꺼져 있는가(진단). + public static bool SnapSuspended { get { return s_snapSuspended; } } + + // ───────────────────────────────────────── 내부 상태 + static Camera s_src; + static GameObject s_rigRoot, s_proxyGo; + static Transform s_proxy; + static Camera s_gameCam, s_viewCam; + static PixelCameraManager s_mgr; + static UpscaledCanvas s_canvas; + static Material s_matInstance; + static MeshRenderer s_quadRenderer; + static Material s_quadSharedMat; + + static CamSnapshot s_snap; + static bool s_faulted; + + static PCActor s_lastPc; + static int s_lastMapId = int.MinValue; + static float s_nextPoll; + + static bool s_snapSuspended; + static float s_snapResumeAt; + static Quaternion s_lastSrcRot = Quaternion.identity; + static bool s_hasLastRot; + + static WLPixelCameraSettings Cfg { get { return WLPixelCameraSettings.Instance; } } + static bool Active { get { return WLPixelCameraSettings.Enabled; } } + + // ───────────────────────────────────────────────────────────────────── + // 틱 (러너가 매 프레임 부른다 · 에디트 모드에서는 프로브가 직접 부를 수 있다) + // ───────────────────────────────────────────────────────────────────── + + /// 1프레임. (프로브가 별도 어셈블리에서 부르므로 public) + public static void Tick() + { + if (s_faulted) return; + + // C8 — 기능이 꺼지면 즉시 원상복구. + if (!Active) { if (IsAssembled) Teardown("off"); return; } + + try + { + var cfg = Cfg; + UpdateSnapSuspension(cfg); + + float now = Time.unscaledTime; + if (now < s_nextPoll) return; + s_nextPoll = now + Mathf.Max(0.02f, cfg.pollSeconds); + if (cfg.assembleOnMapEnter) PollBoundary(cfg); + } + catch (System.Exception ex) + { + s_faulted = true; Faults++; + LastLog = "중단(예외) — " + ex.Message; + Log(LastLog); // 🔴 LogError 금지(813z) + } + } + + /// 맵 진입/이탈 경계 — 811q EffectWarmup · 811o CameraFramingOverride 와 같은 규칙. + static void PollBoundary(WLPixelCameraSettings cfg) + { + if (!Application.isPlaying) return; // 에디트 모드 오염 0(프로브는 ProbeAssemble 로 들어온다) + + var pc = MyValue.MyPC; + if (DSUtil.CheckNull(pc)) + { + // 맵 이탈 — PC 가 사라졌다. 리그를 걷는다. + if (s_lastPc != null && IsAssembled) Teardown("맵 이탈"); + s_lastPc = null; + return; + } + + var info = InGameInfo.Ins; + if (DSUtil.CheckNull(info)) return; // 인게임 정보가 아직 없다 — 경계를 소비하지 않는다 + + int map = MyValue.MyChoiceMapData != null ? MyValue.MyChoiceMapData.n_MapID : int.MinValue; + bool pcChanged = !ReferenceEquals(pc, s_lastPc); + bool mapChanged = map != s_lastMapId; + if (!pcChanged && !mapChanged) return; + + bool lobby = info.Get_GameMode() == eGameMode.Lobby; + if (!cfg.assembleInLobby && lobby) + { + s_lastPc = pc; s_lastMapId = map; + Boundaries++; SkippedLobby++; + LastReason = "lobby"; + if (IsAssembled) Teardown("로비 진입"); + return; + } + + var cam = Camera.main; + if (cam == null) { SkippedNoCam++; return; } // 경계를 소비하지 않는다 — 다음 폴링에서 다시 본다 + + s_lastPc = pc; s_lastMapId = map; + Boundaries++; + LastReason = pcChanged ? "pc" : ("map " + map); + + if (IsAssembled) Teardown("경계 재조립"); + Assemble(cfg, cam); + } + + // ───────────────────────────────────────────────────────────────────── + // 조립 + // ───────────────────────────────────────────────────────────────────── + + /// 리그를 조립한다. 성공 시 true. + public static bool Assemble(WLPixelCameraSettings cfg, Camera src) + { + if (cfg == null || src == null) return false; + if (IsAssembled) return true; + + var prefab = cfg.pixelCameraSystemPrefab; + if (prefab == null) + { + SkippedNoPrefab++; + LastLog = "PixelCameraSystem 프리팹 미설정 — 조립 안 함(URP.unitypackage 해제 확인)"; + Log(LastLog); + return false; + } + + // 이전 잔재(에디트 모드 재실행 등) 제거 — Critter 의 FindAnyObjectByType 가 엉뚱한 걸 잡지 않게. + DestroyStrays(); + + s_src = src; + s_snap.Capture(src); + + // ── 리그 인스턴스. 프리팹이 followed/뷰/캔버스를 이미 배선해 두었으므로 활성 상태로 만들어 + // Critter Initialize() 의 LogError 경로(부모 없음 · followed null · 뷰/캔버스 못 찾음)를 전부 피한다. + // 값 보정은 같은 프레임 안에서 끝나므로(LateUpdate 이전) 잘못된 프레임이 그려지지 않는다. + s_rigRoot = Object.Instantiate(prefab); + s_rigRoot.name = RigName; + s_rigRoot.transform.SetPositionAndRotation(src.transform.position, src.transform.rotation); + + s_mgr = s_rigRoot.GetComponentInChildren(true); + var view = s_rigRoot.GetComponentInChildren(true); + s_canvas = s_rigRoot.GetComponentInChildren(true); + if (s_mgr == null || view == null || s_canvas == null) + { + LastLog = "리그 프리팹 구조가 예상과 다르다 — 조립 취소"; + Log(LastLog); + Teardown("구조 불일치"); + Faults++; + return false; + } + + s_gameCam = s_mgr.GetComponent(); + s_viewCam = view.GetComponent(); + if (s_gameCam == null || s_viewCam == null) + { + LastLog = "리그 카메라 컴포넌트 없음 — 조립 취소"; + Log(LastLog); + Teardown("카메라 없음"); + Faults++; + return false; + } + + // 🔴 Critter 프리팹의 ViewCamera 에는 AudioListener 가 달려 있다(실측). 원본 Main Camera 의 것과 + // 겹치면 Unity 가 "There are 2 audio listeners in the scene" 경고를 매 프레임 낸다 → 리그 것은 끈다. + var listeners = s_rigRoot.GetComponentsInChildren(true); + for (int i = 0; i < listeners.Length; i++) if (listeners[i] != null) DestroyObj(listeners[i]); + + int layer = Mathf.Clamp(cfg.rigLayer, 0, 31); + SetLayerRecursive(s_rigRoot.transform, layer); + s_rigRoot.tag = "Untagged"; + s_gameCam.gameObject.tag = "Untagged"; + s_viewCam.gameObject.tag = "Untagged"; + + // ── 쿼드 머티리얼을 런타임 인스턴스로 갈아 끼운다. + // Critter 의 UpscaledCanvas 는 sharedMaterial 에 _LowResTexture 를 직접 SetTexture 한다 → + // 그대로 두면 **디스크의 .mat 에셋이 더러워진다**(에디트 모드에서 특히). 인스턴스로 바꾸고 + // OnEnable 을 다시 돌려 캐시를 갱신한다. + s_quadRenderer = s_canvas.GetComponent(); + if (s_quadRenderer != null && s_quadRenderer.sharedMaterial != null) + { + s_quadSharedMat = s_quadRenderer.sharedMaterial; + s_matInstance = new Material(s_quadSharedMat); + s_matInstance.name = s_quadSharedMat.name + " (WL rig runtime)"; + s_quadRenderer.sharedMaterial = s_matInstance; + s_canvas.enabled = false; s_canvas.enabled = true; // OnEnable 재실행 → 인스턴스 캐시 + } + + // ── 프록시 + if (cfg.proxyMode == PixelProxyMode.ChildOfCamera) + { + s_proxyGo = new GameObject(ProxyName); + s_proxyGo.layer = layer; + s_proxyGo.transform.SetParent(src.transform, false); + s_proxyGo.transform.localPosition = Vector3.zero; + s_proxyGo.transform.localRotation = Quaternion.identity; + s_proxyGo.transform.localScale = Vector3.one; + s_proxy = s_proxyGo.transform; + } + else + { + s_proxyGo = new GameObject(ProxyName); + s_proxyGo.layer = layer; + s_proxyGo.transform.SetPositionAndRotation(src.transform.position, src.transform.rotation); + var mirror = s_proxyGo.AddComponent(); + mirror.Source = src.transform; + s_proxy = s_proxyGo.transform; + } + + // ── 저해상도 게임 카메라 = 원본이 보던 월드를 그대로 본다(리그 레이어만 뺀다) + s_gameCam.orthographic = true; + s_gameCam.nearClipPlane = s_snap.near; + s_gameCam.farClipPlane = s_snap.far; + s_gameCam.cullingMask = s_snap.cullingMask & ~(1 << layer); + s_gameCam.clearFlags = s_snap.clearFlags; + s_gameCam.backgroundColor = s_snap.background; + s_gameCam.allowHDR = s_snap.allowHDR; + s_gameCam.allowMSAA = s_snap.allowMSAA; + s_gameCam.useOcclusionCulling = s_snap.occlusionCulling; + s_gameCam.depth = s_snap.depth - 1f; // 원본(화면 Base)보다 먼저 RT 를 채운다 + s_gameCam.targetTexture = null; // Critter 가 만든다 + + var srcData = s_src.GetUniversalAdditionalCameraData(); + var gameData = s_gameCam.GetUniversalAdditionalCameraData(); + if (gameData != null) + { + gameData.renderType = CameraRenderType.Base; + if (gameData.cameraStack != null) gameData.cameraStack.Clear(); + if (srcData != null) + { + gameData.renderShadows = srcData.renderShadows; + gameData.volumeLayerMask = srcData.volumeLayerMask; + gameData.volumeTrigger = srcData.volumeTrigger; + gameData.renderPostProcessing = cfg.copyPostProcessingToGameCamera && srcData.renderPostProcessing; + gameData.antialiasing = srcData.antialiasing; + gameData.antialiasingQuality = srcData.antialiasingQuality; + gameData.stopNaN = srcData.stopNaN; + gameData.dithering = srcData.dithering; + } + } + + // ── Critter 값 + float aspect = ScreenAspect(); + int px = Mathf.Max(3, cfg.pixelHeight); + s_mgr.FollowedTransform = s_proxy; + s_mgr.VoxelGridMovement = cfg.voxelGridMovement; + s_mgr.SubpixelAdjustments = cfg.subpixelAdjustments; + s_mgr.FollowRotation = cfg.followRotation; + s_mgr.resolutionSynchronizationMode = ResolutionSynchronizationMode.SetHeight; + s_mgr.GameResolution = new Vector2Int(Mathf.Max(2, Mathf.RoundToInt(px * aspect)), px); + s_mgr.ControlGameZoom = cfg.controlGameZoom; + s_mgr.GameCameraZoom = GameZoomFor(cfg); + s_mgr.ViewCameraZoom = cfg.viewCameraZoom; + + // ── 뷰 카메라 = 픽셀 쿼드만 그린다 + s_viewCam.orthographic = true; + s_viewCam.cullingMask = 1 << layer; + s_viewCam.allowHDR = s_snap.allowHDR; + s_viewCam.allowMSAA = false; + s_viewCam.useOcclusionCulling = false; + var viewData = s_viewCam.GetUniversalAdditionalCameraData(); + if (viewData != null) + { + viewData.renderPostProcessing = false; + viewData.renderShadows = false; + viewData.renderType = cfg.viewCameraInMainStack ? CameraRenderType.Overlay : CameraRenderType.Base; + if (viewData.cameraStack != null && viewData.renderType == CameraRenderType.Base) viewData.cameraStack.Clear(); + } + if (!cfg.viewCameraInMainStack) s_viewCam.depth = s_snap.depth + 1f; + + // ── 원본 카메라 = 화면 Base 로 남되 월드는 그리지 않는다(투영만 픽셀 카메라와 맞춘다) + s_src.orthographic = true; + s_src.orthographicSize = cfg.orthoSize; + s_src.cullingMask = cfg.mainCameraCullingMask; + if (cfg.mainCameraSolidBlack) + { + s_src.clearFlags = CameraClearFlags.SolidColor; + s_src.backgroundColor = Color.black; + } + if (srcData != null) + { + if (cfg.mainCameraPostProcessingOff) srcData.renderPostProcessing = false; + srcData.renderShadows = false; + if (cfg.viewCameraInMainStack && srcData.cameraStack != null) + srcData.cameraStack.Insert(0, s_viewCam); // ViewCamera → UICamera 순서 + } + + Assembled++; + s_hasLastRot = false; + s_snapSuspended = false; + LastLog = "조립 — ortho " + cfg.orthoSize.ToString("0.###") + + " · RT " + s_mgr.GameResolution.x + "×" + s_mgr.GameResolution.y + + " · zoom " + s_mgr.GameCameraZoom.ToString("0.####") + + " · layer " + layer; + Log(LastLog); + return true; + } + + /// SO 값으로 Critter 게임 카메라 줌(= 캔버스 반높이)을 계산한다. + public static float GameZoomFor(WLPixelCameraSettings cfg) + { + if (cfg == null) return 5f; + if (!cfg.compensateViewZoom) return cfg.orthoSize; + return cfg.orthoSize / CanvasOnScreenLimit(cfg.pixelHeight); + } + + /// Critter 가 캔버스 가장자리를 넘지 않으려고 쓰는 줌 한계 = 1 − 2/pixelHeight. + public static float CanvasOnScreenLimit(int pixelHeight) + { + int py = Mathf.Max(3, pixelHeight); + return 1f - (2f / py); + } + + static float ScreenAspect() + { + float w = Screen.width, h = Screen.height; + if (w <= 0f || h <= 0f) return 9f / 16f; + return w / h; + } + + // ───────────────────────────────────────────────────────────────────── + // 복원 + // ───────────────────────────────────────────────────────────────────── + + /// 리그를 걷고 원본 카메라를 스냅샷 그대로 되돌린다. + public static void Teardown(string why) + { + bool had = s_rigRoot != null || s_proxyGo != null; + + // 원본 카메라 복원 — 스택에서 뷰 카메라부터 뺀다. + if (s_src != null) + { + var srcData = s_src.GetUniversalAdditionalCameraData(); + if (srcData != null && srcData.cameraStack != null) + { + srcData.cameraStack.Clear(); + if (s_snap.stack != null) + for (int i = 0; i < s_snap.stack.Length; i++) + if (s_snap.stack[i] != null) srcData.cameraStack.Add(s_snap.stack[i]); + } + s_snap.Restore(s_src); + } + + // RT 해제 — Critter 가 만든 것을 우리가 반납한다. + if (s_gameCam != null) + { + var rt = s_gameCam.targetTexture; + s_gameCam.targetTexture = null; + if (rt != null) { rt.Release(); DestroyObj(rt); } + } + + // 쿼드 머티리얼 인스턴스 반납 + 원본 sharedMaterial 복귀(디스크 에셋 무변경 보장) + if (s_quadRenderer != null && s_quadSharedMat != null) s_quadRenderer.sharedMaterial = s_quadSharedMat; + if (s_matInstance != null) { DestroyObj(s_matInstance); s_matInstance = null; } + + if (s_rigRoot != null) { DestroyObj(s_rigRoot); s_rigRoot = null; } + if (s_proxyGo != null) { DestroyObj(s_proxyGo); s_proxyGo = null; } + DestroyStrays(); + + s_proxy = null; s_gameCam = null; s_viewCam = null; s_mgr = null; s_canvas = null; + s_quadRenderer = null; s_quadSharedMat = null; + s_snapSuspended = false; s_hasLastRot = false; + s_src = null; + + if (had) + { + Restored++; + LastLog = "복원 — " + why; + Log(LastLog); + } + } + + /// 이름으로 남은 리그·프록시 잔재를 지운다(도메인 리로드·에디트 모드 재실행 대비). + static void DestroyStrays() + { + var all = Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None); + for (int i = 0; i < all.Length; i++) + { + if (all[i] == null) continue; + var root = all[i].transform.parent != null ? all[i].transform.parent.gameObject : all[i].gameObject; + if (root == s_rigRoot) continue; + if (root.name == RigName) DestroyObj(root); + } + + // 프록시(원본 카메라의 자식)도 이름으로 정리 + var cam = Camera.main; + if (cam != null) + { + for (int i = cam.transform.childCount - 1; i >= 0; i--) + { + var c = cam.transform.GetChild(i); + if (c != null && c.gameObject != s_proxyGo && c.name == ProxyName) DestroyObj(c.gameObject); + } + } + } + + static void DestroyObj(Object o) + { + if (o == null) return; + if (Application.isPlaying) Object.Destroy(o); + else Object.DestroyImmediate(o); + } + + static void SetLayerRecursive(Transform t, int layer) + { + t.gameObject.layer = layer; + for (int i = 0; i < t.childCount; i++) SetLayerRecursive(t.GetChild(i), layer); + } + + // ───────────────────────────────────────────────────────────────────── + // 회전 중 스냅 해제 (Critter 문서 권고 · 811o 구도 전환 · 보스 연출) + // ───────────────────────────────────────────────────────────────────── + + static void UpdateSnapSuspension(WLPixelCameraSettings cfg) + { + if (s_mgr == null || s_src == null) { s_hasLastRot = false; return; } + if (!cfg.disableSnapWhileRotating) + { + if (s_snapSuspended) { s_mgr.VoxelGridMovement = cfg.voxelGridMovement; s_mgr.SubpixelAdjustments = cfg.subpixelAdjustments; s_snapSuspended = false; } + return; + } + + var rot = s_src.transform.rotation; + float dt = Mathf.Max(1e-4f, Time.unscaledDeltaTime); + if (!s_hasLastRot) { s_lastSrcRot = rot; s_hasLastRot = true; return; } + + float degPerSec = Quaternion.Angle(s_lastSrcRot, rot) / dt; + s_lastSrcRot = rot; + + float now = Time.unscaledTime; + if (degPerSec >= Mathf.Max(0f, cfg.rotationSnapOffDegPerSec)) + { + s_snapResumeAt = now + Mathf.Max(0f, cfg.rotationSnapResumeSeconds); + if (!s_snapSuspended) + { + s_snapSuspended = true; + s_mgr.VoxelGridMovement = false; + s_mgr.SubpixelAdjustments = false; + } + } + else if (s_snapSuspended && now >= s_snapResumeAt) + { + s_snapSuspended = false; + s_mgr.VoxelGridMovement = cfg.voxelGridMovement; + s_mgr.SubpixelAdjustments = cfg.subpixelAdjustments; + } + } + + // ───────────────────────────────────────────────────────────────────── + // 프로브 진입점 + // ───────────────────────────────────────────────────────────────────── + + /// 프로브·에디트 모드: 경계 폴링을 건너뛰고 지금 바로 조립한다. + public static bool ProbeAssemble(Camera src) + { + var cfg = Cfg; + if (cfg == null) return false; + if (IsAssembled) Teardown("probe 재조립"); + return Assemble(cfg, src); + } + + /// 프로브: 지금 바로 복원한다. + public static void ProbeTeardown() { Teardown("probe"); } + + /// 프로브: 회전 스냅 판정을 1회 돌린다(에디트 모드). + public static void ProbeSnapTick() { var c = Cfg; if (c != null) UpdateSnapSuspension(c); } + + /// 프로브: 원본 카메라 스냅샷을 한 줄로. + public static string SnapshotSummary() { return s_snap.Summary(); } + + /// 프로브: 지금 원본 카메라 상태를 스냅샷과 같은 형식으로. + public static string CurrentSummary(Camera cam) { var s = new CamSnapshot(); s.Capture(cam); return s.Summary(); } + + public static void ResetAll() + { + Teardown("reset"); + Boundaries = Assembled = Restored = SkippedLobby = SkippedNoCam = SkippedNoPrefab = Faults = 0; + LastReason = LastLog = ""; + s_faulted = false; + s_lastPc = null; s_lastMapId = int.MinValue; s_nextPoll = 0f; + } + + static void Log(string msg) + { + var cfg = Cfg; + if (cfg != null && cfg.verboseLog) Debug.Log("[PixelCameraRig] " + msg); + } + + // ───────────────────────────────────────────────────────────────────── + // 러너 + // ───────────────────────────────────────────────────────────────────── + + static GameObject s_runner; + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] + static void Boot() + { + if (s_runner != null) return; + if (!Active) return; // C8 — 러너 자체가 뜨지 않는다 + s_runner = new GameObject("[WL814b] PixelCameraRigRunner"); + s_runner.hideFlags = HideFlags.HideAndDontSave; + s_runner.AddComponent(); + Object.DontDestroyOnLoad(s_runner); + } + + internal static void OnRunnerQuit() { Teardown("quit"); } + +#if UNITY_EDITOR + /// 에디터: Play 진입/이탈 경계에서 반드시 복원한다(에디트 모드 프로브 잔재 0). + [UnityEditor.InitializeOnLoadMethod] + static void EditorHook() + { + UnityEditor.EditorApplication.playModeStateChanged -= OnPlayModeChanged; + UnityEditor.EditorApplication.playModeStateChanged += OnPlayModeChanged; + } + + static void OnPlayModeChanged(UnityEditor.PlayModeStateChange s) + { + if (s == UnityEditor.PlayModeStateChange.ExitingEditMode || s == UnityEditor.PlayModeStateChange.ExitingPlayMode) + Teardown("playmode " + s); + } +#endif + } + + /// 매 프레임 리그 틱. Critter(기본 실행 순서 0)보다 먼저 돌아야 회전 스냅 해제가 그 프레임에 반영된다. + [DefaultExecutionOrder(-100)] + internal sealed class PixelCameraRigRunner : MonoBehaviour + { + void Update() { PixelCameraRig.Tick(); } + void OnApplicationQuit() { PixelCameraRig.OnRunnerQuit(); } + void OnDestroy() { PixelCameraRig.OnRunnerQuit(); } + } + + /// MirrorScript 모드용 프록시. 원본 카메라 트랜스폼을 읽기만 한다(역방향 쓰기 0 = 피드백 루프 0). + [DefaultExecutionOrder(-100)] + public sealed class PixelCameraProxyMirror : MonoBehaviour + { + public Transform Source; + + void LateUpdate() + { + if (Source == null) return; + transform.SetPositionAndRotation(Source.position, Source.rotation); + } + + /// 프로브: 1회 미러(에디트 모드). + public void Mirror() { LateUpdate(); } + } + + /// 원본 Camera + URP 데이터의 되돌릴 값 전부. + internal struct CamSnapshot + { + public bool valid; + public bool ortho; + public float orthoSize, fov, near, far, depth; + public int cullingMask; + public CameraClearFlags clearFlags; + public Color background; + public bool allowHDR, allowMSAA, occlusionCulling; + public RenderTexture target; + + public bool hasData; + public CameraRenderType renderType; + public bool renderPost, renderShadows; + public LayerMask volumeMask; + public Transform volumeTrigger; + public AntialiasingMode aa; + public AntialiasingQuality aaQuality; + public Camera[] stack; + + public void Capture(Camera c) + { + valid = c != null; + if (!valid) return; + ortho = c.orthographic; orthoSize = c.orthographicSize; fov = c.fieldOfView; + near = c.nearClipPlane; far = c.farClipPlane; depth = c.depth; + cullingMask = c.cullingMask; clearFlags = c.clearFlags; background = c.backgroundColor; + allowHDR = c.allowHDR; allowMSAA = c.allowMSAA; occlusionCulling = c.useOcclusionCulling; + target = c.targetTexture; + + var d = c.GetUniversalAdditionalCameraData(); + hasData = d != null; + if (!hasData) { stack = null; return; } + renderType = d.renderType; + renderPost = d.renderPostProcessing; + renderShadows = d.renderShadows; + volumeMask = d.volumeLayerMask; + volumeTrigger = d.volumeTrigger; + aa = d.antialiasing; + aaQuality = d.antialiasingQuality; + + var st = d.cameraStack; + if (st == null) { stack = null; return; } + stack = new Camera[st.Count]; + for (int i = 0; i < st.Count; i++) stack[i] = st[i]; + } + + public void Restore(Camera c) + { + if (!valid || c == null) return; + c.orthographic = ortho; c.orthographicSize = orthoSize; c.fieldOfView = fov; + c.nearClipPlane = near; c.farClipPlane = far; c.depth = depth; + c.cullingMask = cullingMask; c.clearFlags = clearFlags; c.backgroundColor = background; + c.allowHDR = allowHDR; c.allowMSAA = allowMSAA; c.useOcclusionCulling = occlusionCulling; + c.targetTexture = target; + + if (!hasData) return; + var d = c.GetUniversalAdditionalCameraData(); + if (d == null) return; + d.renderType = renderType; + d.renderPostProcessing = renderPost; + d.renderShadows = renderShadows; + d.volumeLayerMask = volumeMask; + d.volumeTrigger = volumeTrigger; + d.antialiasing = aa; + d.antialiasingQuality = aaQuality; + } + + /// 비교용 한 줄 요약(프로브가 조립 전/후를 문자열로 대조한다). + public string Summary() + { + if (!valid) return "(none)"; + var sb = new System.Text.StringBuilder(160); + sb.Append("ortho=").Append(ortho ? 1 : 0) + .Append(" size=").Append(orthoSize.ToString("0.####")) + .Append(" fov=").Append(fov.ToString("0.###")) + .Append(" near=").Append(near.ToString("0.###")) + .Append(" far=").Append(far.ToString("0.#")) + .Append(" depth=").Append(depth.ToString("0.##")) + .Append(" mask=").Append(cullingMask) + .Append(" clear=").Append((int)clearFlags) + .Append(" bg=").Append(background.r.ToString("0.###")).Append(',').Append(background.g.ToString("0.###")).Append(',').Append(background.b.ToString("0.###")).Append(',').Append(background.a.ToString("0.###")) + .Append(" hdr=").Append(allowHDR ? 1 : 0) + .Append(" msaa=").Append(allowMSAA ? 1 : 0) + .Append(" occ=").Append(occlusionCulling ? 1 : 0) + .Append(" rt=").Append(target == null ? 0 : 1); + if (hasData) + { + sb.Append(" type=").Append((int)renderType) + .Append(" post=").Append(renderPost ? 1 : 0) + .Append(" shadow=").Append(renderShadows ? 1 : 0) + .Append(" vmask=").Append(volumeMask.value) + .Append(" aa=").Append((int)aa) + .Append(" stack=").Append(stack == null ? 0 : stack.Length); + } + return sb.ToString(); + } + } +} diff --git a/Assets/WL/PixelCamera/PixelCameraRig.cs.meta b/Assets/WL/PixelCamera/PixelCameraRig.cs.meta new file mode 100644 index 000000000..25a41d403 --- /dev/null +++ b/Assets/WL/PixelCamera/PixelCameraRig.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 861b4bf4226c29b438df6f1367a332b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/WL/PixelCamera/WLPixelCameraSettings.cs b/Assets/WL/PixelCamera/WLPixelCameraSettings.cs new file mode 100644 index 000000000..90800bc31 --- /dev/null +++ b/Assets/WL/PixelCamera/WLPixelCameraSettings.cs @@ -0,0 +1,152 @@ +// ───────────────────────────────────────────────────────────────────────────── +// WLPixelCameraSettings.cs — Critter 3D Pixel Camera 리그 값의 SOT (C45) +// +// PD 지시 #814(「도트 게임처럼」) · 발주서 WL-814b §1-3 (2026-09-10) +// +// 값의 SOT = Assets/WL/Combat/Settings/Resources/WL/WLPixelCameraSettings.asset +// → Resources.Load("WL/WLPixelCameraSettings") 1회 로드 후 캐시(기존 WL 설정 SO 관례). +// +// 🔴 C8 — enabled = 0 (또는 RuntimeDisabled = true) 이면 리그가 아예 조립되지 않고, +// 이미 조립돼 있으면 다음 틱에 원본 카메라 값이 100 % 복원된다(원본 동작과 동일). +// +// 🔴 원본 스크립트 0 · 원본 프리팹/씬 디스크 수정 0. 이 SO 와 PixelCameraRig.cs 만이 WL 신규 파일이다. +// ───────────────────────────────────────────────────────────────────────────── + +using UnityEngine; + +namespace WL.PixelArt +{ + /// Followed 프록시를 어떻게 원본 카메라에 붙일지. + public enum PixelProxyMode + { + /// 원본 Main Camera 의 자식(localPos 0 · localRot identity). 지연 0 · 프레임당 비용 0 · GC 0. 권장. + ChildOfCamera = 0, + /// 독립 오브젝트 + 미러 스크립트([DefaultExecutionOrder(-100)] LateUpdate). 1프레임 지연. + MirrorScript = 1, + } + + /// Critter 픽셀 카메라 리그 값. 전부 여기서만 바꾼다(코드 상수 0). + [CreateAssetMenu(fileName = "WLPixelCameraSettings", menuName = "WL/Pixel Camera Settings", order = 814)] + public sealed class WLPixelCameraSettings : ScriptableObject + { + public const string ResourcesPath = "WL/WLPixelCameraSettings"; + + static WLPixelCameraSettings s_cached; + static bool s_lookupDone; + + /// Resources 에서 1회 로드 후 캐시. 없으면 null(= 기능 off). + public static WLPixelCameraSettings Instance + { + get + { + if (!s_lookupDone) + { + s_lookupDone = true; + s_cached = Resources.Load(ResourcesPath); + } + return s_cached; + } + } + + /// 진단·A/B 전용 런타임 스위치(WLHitFeel.RuntimeDisabled 선례). 에셋을 안 건드리고 이 기능만 끈다. + public static bool RuntimeDisabled; + + /// 이 기능이 살아 있는가(에셋 존재 + enabled + !RuntimeDisabled). + public static bool Enabled + { + get { var i = Instance; return i != null && i.enabled && !RuntimeDisabled; } + } + + /// 테스트용: 캐시를 비워 다음 접근 때 다시 Resources.Load 한다. + public static void ClearCache() { s_cached = null; s_lookupDone = false; } + + // ───────────────────────────────────────── 마스터 + [Header("마스터 (C8)")] + [Tooltip("0 이면 리그를 만들지 않고, 이미 만들었으면 원본 카메라를 100 % 복원한다.")] + public bool enabled = true; + + [Tooltip("1 이면 조립/복원 로그를 1줄씩 남긴다. LogError 는 쓰지 않는다(813z).")] + public bool verboseLog = false; + + // ───────────────────────────────────────── 조립 경계 + [Header("조립 경계 (811q EffectWarmup / 811o CameraFramingOverride 와 같은 판정)")] + [Tooltip("맵 진입 경계(메인 PC 교체 또는 맵 ID 변경)에서 자동 조립한다. 0 이면 프로브만 조립할 수 있다.")] + public bool assembleOnMapEnter = true; + + [Tooltip("로비에서도 조립할지. 기본 0 = 인게임 맵에서만.")] + public bool assembleInLobby = false; + + [Tooltip("경계 폴링 주기(초).")] + public float pollSeconds = 0.25f; + + // ───────────────────────────────────────── 리그 원본 + [Header("Critter 리그")] + [Tooltip("Assets/3DPixelCamera/URP/PixelCameraSystem.prefab (URP.unitypackage 해제로 생긴 프리팹).")] + public GameObject pixelCameraSystemPrefab; + + [Tooltip("리그 전용 레이어 인덱스. 게임 카메라는 이 레이어를 빼고, 뷰 카메라는 이 레이어만 그린다. 프로젝트 미명명 레이어를 쓴다(TagManager 수정 0).")] + [Range(0, 31)] public int rigLayer = 31; + + [Tooltip("프록시 방식. ChildOfCamera = 원본 카메라의 자식(지연 0 · 권장).")] + public PixelProxyMode proxyMode = PixelProxyMode.ChildOfCamera; + + // ───────────────────────────────────────── 투영·해상도 + [Header("직교 투영 · 픽셀 해상도")] + [Tooltip("원본 Main Camera 에 적용할 orthographicSize(= 화면 세로 절반의 월드 단위). " + + "기본 3.8 = 원근 fov 60 · 카메라 거리 6.58 m 의 반높이(tan30° × 6.58).")] + [Range(1f, 12f)] public float orthoSize = 3.8f; + + [Tooltip("저해상도 RT 의 세로 픽셀 수(SetHeight). 가로는 화면 비율로 자동(9:16 · 480 → 270×480).")] + [Range(60, 1080)] public int pixelHeight = 480; + + [Tooltip("Critter 뷰 카메라가 캔버스 가장자리를 넘지 않으려고 (1 − 2/pixelHeight) 만큼 줌아웃하는 것을 보정한다. " + + "1 이면 GameCameraZoom = orthoSize / (1 − 2/pixelHeight) 로 올려 화면 매핑을 orthoSize 와 정확히 맞춘다.")] + public bool compensateViewZoom = true; + + // ───────────────────────────────────────── Critter 값 + [Header("Critter PixelCameraManager 값")] + [Tooltip("픽셀 격자(voxel grid) 스냅. 정지 물체의 픽셀이 떨리지 않게 한다.")] + public bool voxelGridMovement = true; + + [Tooltip("서브픽셀 보정. 격자 스냅의 뚝뚝 끊김을 뷰 카메라 오프셋으로 되돌린다.")] + public bool subpixelAdjustments = true; + + [Tooltip("followed 트랜스폼의 회전도 따라간다.")] + public bool followRotation = true; + + [Tooltip("Critter 가 게임 카메라의 orthographicSize 를 직접 제어한다.")] + public bool controlGameZoom = true; + + [Tooltip("뷰 카메라 줌(−1~1). 1 = 캔버스를 화면에 꽉 채운다.")] + [Range(-1f, 1f)] public float viewCameraZoom = 1f; + + [Tooltip("뷰 카메라를 원본 Main Camera 의 URP 카메라 스택에 Overlay 로 끼운다(권장). " + + "0 이면 Base 로 두고 depth 를 원본보다 1 높인다.")] + public bool viewCameraInMainStack = true; + + // ───────────────────────────────────────── 회전 중 스냅 해제 + [Header("회전 중 스냅 해제 (Critter 문서 권고)")] + [Tooltip("카메라가 빠르게 돌 때 격자 스냅·서브픽셀 보정을 잠시 끈다(811o 구도 전환 · 보스 연출).")] + public bool disableSnapWhileRotating = true; + + [Tooltip("이 각속도(도/초)를 넘으면 회전 중으로 본다.")] + public float rotationSnapOffDegPerSec = 30f; + + [Tooltip("회전이 멎고 이 시간(초)이 지나면 스냅을 다시 켠다.")] + public float rotationSnapResumeSeconds = 0.25f; + + // ───────────────────────────────────────── 원본 카메라 처리 + [Header("원본 Main Camera 처리 (MainCamera 태그·RealCamera·AudioListener 전부 유지)")] + [Tooltip("원본 카메라가 그릴 레이어. 기본 0 = 월드를 그리지 않는다(인게임 UI 캔버스는 UICamera Overlay 가 그린다).")] + public int mainCameraCullingMask = 0; + + [Tooltip("원본 카메라의 포스트프로세싱을 끈다(픽셀 결과를 다시 후처리하지 않게). 게임 카메라 쪽에서 처리한다.")] + public bool mainCameraPostProcessingOff = true; + + [Tooltip("원본 카메라의 포스트프로세싱 설정을 저해상도 게임 카메라로 복사한다(블룸 등이 픽셀 해상도로 들어간다).")] + public bool copyPostProcessingToGameCamera = true; + + [Tooltip("원본 카메라의 배경을 단색 검정으로 바꾼다(스카이박스 클리어 비용 제거). 복원 시 원값으로 되돌린다.")] + public bool mainCameraSolidBlack = true; + } +} diff --git a/Assets/WL/PixelCamera/WLPixelCameraSettings.cs.meta b/Assets/WL/PixelCamera/WLPixelCameraSettings.cs.meta new file mode 100644 index 000000000..ec8533971 --- /dev/null +++ b/Assets/WL/PixelCamera/WLPixelCameraSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aedb96845e568d44889723065b993c14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: