[WL-814q] 시범 전투장 씬(Critter 만듦새 · 반경 14m) (#814)
- 지형 스플랫 SetAlphamaps 를 CreateAsset 뒤로(전에 쓰면 채널이 날아감) · 스카이박스는 GetBuiltinExtraResource 로(콘솔 에러 0) - 캐릭터 Idle 포즈 1프레임 굽기(T 포즈 방지 · 씬 인스턴스 한정) - 경계 바위 56 + 나무 20 + 아치 2 · 바닥 포석 14 + 잔돌 26 · 가로등 2 + 포인트 라이트 2 - 실측: ToonTerrain(Shader Graphs/ToonTerrain) 은 터레인 스플랫을 쓰지 않는다 — _RedHighlight 만 나온다(Probe3) → 흙바닥용 머티리얼 변형은 무의미해 폐기하고 데모 원본 Terrain.mat 그대로 사용(편차 0) - 캡처 5장 Screenshots_WL/WL814q/ (미추적) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
6e9f711529
commit
2a0e8b28dc
|
|
@ -179,7 +179,9 @@ public static class WL814q_BuildArena
|
|||
UnityEngine.RenderSettings.ambientEquatorColor = new UnityEngine.Color(0.114f, 0.125f, 0.133f, 1f);
|
||||
UnityEngine.RenderSettings.ambientGroundColor = new UnityEngine.Color(0.047f, 0.043f, 0.035f, 1f);
|
||||
UnityEngine.RenderSettings.ambientIntensity = 1f;
|
||||
UnityEngine.RenderSettings.skybox = UnityEngine.Resources.GetBuiltinResource<UnityEngine.Material>("Default-Skybox.mat");
|
||||
// 🔴 Resources.GetBuiltinResource 로는 못 찾는다(콘솔 에러) — 빌트인 extra 리소스로 받아야 한다
|
||||
UnityEngine.RenderSettings.skybox =
|
||||
UnityEditor.AssetDatabase.GetBuiltinExtraResource<UnityEngine.Material>("Default-Skybox.mat");
|
||||
UnityEngine.RenderSettings.subtractiveShadowColor = new UnityEngine.Color(0.42f, 0.478f, 0.627f, 1f);
|
||||
|
||||
// ── 4. 경계(반경 14 m) — 바위 띠를 촘촘히 + 나무 숲 + 아치 2개
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ public static class WL814q_Capture
|
|||
if (cam == null) return "NO CAMERA";
|
||||
var camPos = cam.transform.position;
|
||||
var camRot = cam.transform.rotation;
|
||||
// 🔴 씬을 연 직후 첫 렌더는 터레인 머티리얼/스플랫이 아직 안 붙는다 — 버리는 렌더 2장으로 예열
|
||||
for (int i = 0; i < 2; i++) UnityEngine.Object.DestroyImmediate(Shot(cam, 64, 64));
|
||||
|
||||
// ⓐ 일반 모드 — 같은 위치·각도 · 퍼스펙티브 · 풀해상도(도트 없음)
|
||||
cam.orthographic = false;
|
||||
|
|
@ -109,11 +111,11 @@ public static class WL814q_Capture
|
|||
sb.AppendLine("b_dotA: ortho 3.4 · 135x240 -> point x8");
|
||||
|
||||
// ⓒ 캐릭터가 보이는 눈높이 구도(도트A) — 더 가깝고 낮게
|
||||
cam.transform.position = new UnityEngine.Vector3(0f, 1.15f, 0f)
|
||||
+ UnityEngine.Quaternion.Euler(0f, 205f, 0f) * new UnityEngine.Vector3(0f, 0f, -4.2f)
|
||||
+ UnityEngine.Vector3.up * 0.55f;
|
||||
cam.transform.LookAt(new UnityEngine.Vector3(0f, 0.75f, 0f));
|
||||
Save(DotA(cam, 2.0f), "c_dotA_eye_1080x1920.png");
|
||||
// 캐릭터를 크게 — 도트A 각도(43.61°) 유지 · orthoSize 만 줄이고 주시점을 앞으로 밀어 캐릭터를 아래쪽에
|
||||
cam.transform.position = camPos; cam.transform.rotation = camRot;
|
||||
var fwd = cam.transform.forward; fwd.y = 0f; fwd.Normalize();
|
||||
cam.transform.position = camPos + fwd * 1.9f;
|
||||
Save(DotA(cam, 2.2f), "c_dotA_eye_1080x1920.png");
|
||||
sb.AppendLine("c_dotA_eye: ortho 2.0 · 135x240 -> point x8 · pos=" + cam.transform.position);
|
||||
|
||||
// 개요(참고) — 아레나 전체 + 연못 + 풍차 (퍼스펙티브 3/4 뷰)
|
||||
|
|
@ -125,10 +127,13 @@ public static class WL814q_Capture
|
|||
sb.AppendLine("e_overview: perspective fov40 @" + cam.transform.position);
|
||||
cam.orthographic = true; cam.orthographicSize = 3.4f;
|
||||
|
||||
// ⓓ 비교용 — 새 아레나(도트A) 렌더를 먼저 잡아 둔다
|
||||
cam.transform.position = camPos; cam.transform.rotation = camRot;
|
||||
cam.orthographic = true; cam.orthographicSize = 3.4f;
|
||||
var mine = DotA(cam, 3.4f);
|
||||
// ⓓ 비교용 — 데모의 부품은 우리보다 5~6배 크다(House 9.2 m · Tree 13.5 m vs 캐릭터 1.19 m).
|
||||
// 도트A(ortho 3.4)로 데모를 찍으면 집 벽 한 조각만 나온다 → 두 씬 모두 ortho 10 · 같은 내림각 43.61° 로 맞춘다.
|
||||
const float CmpOrtho = 10f;
|
||||
float kk = CmpOrtho / 3.4f; // 각도 유지 · 카메라만 뒤로(near 0.3 에 잘리지 않게)
|
||||
cam.transform.position = camPos * kk; cam.transform.rotation = camRot;
|
||||
cam.orthographic = true; cam.orthographicSize = CmpOrtho;
|
||||
var mine = DotA(cam, CmpOrtho);
|
||||
var mineHalf = Upscale(mine, W / 2, H / 2);
|
||||
UnityEngine.Object.DestroyImmediate(mine);
|
||||
// 텍스처를 씬 전환에서 지키기
|
||||
|
|
@ -144,19 +149,29 @@ public static class WL814q_Capture
|
|||
UnityEngine.Texture2D demoHalf = null;
|
||||
if (demoCam != null)
|
||||
{
|
||||
// 데모의 마을 중심(House 2채 + Light_Post 일대)을 우리와 같은 내림각 43.61°·도트A 규격으로
|
||||
var dt = UnityEngine.Object.FindFirstObjectByType<UnityEngine.Terrain>();
|
||||
var fxz = new UnityEngine.Vector3(94f, 0f, 78f);
|
||||
float fy = dt != null ? dt.SampleHeight(fxz) + dt.transform.position.y : 4f;
|
||||
var focus = new UnityEngine.Vector3(fxz.x, fy, fxz.z);
|
||||
// 데모의 집 앞(House (2))을 기준점으로 — 오브젝트 바운즈에서 직접 발밑을 잡는다(지형 추정 금지)
|
||||
var focus = new UnityEngine.Vector3(94f, 4f, 78f);
|
||||
var hg = UnityEngine.GameObject.Find("House (2)");
|
||||
if (hg == null) hg = UnityEngine.GameObject.Find("Light_Post");
|
||||
if (hg != null)
|
||||
{
|
||||
var hr = hg.GetComponentInChildren<UnityEngine.Renderer>();
|
||||
if (hr != null)
|
||||
{
|
||||
var hb = hr.bounds;
|
||||
focus = new UnityEngine.Vector3(hb.center.x, hb.min.y, hb.center.z);
|
||||
sb.AppendLine("demo focus = " + hg.name + " bounds " + hb.size + " @ " + focus);
|
||||
}
|
||||
}
|
||||
float camUp = 5.4335f, camHoriz = 4.5911f;
|
||||
float yaw = 215f;
|
||||
var dir = new UnityEngine.Vector3(UnityEngine.Mathf.Sin(yaw * UnityEngine.Mathf.Deg2Rad), 0f,
|
||||
UnityEngine.Mathf.Cos(yaw * UnityEngine.Mathf.Deg2Rad));
|
||||
demoCam.transform.position = focus + UnityEngine.Vector3.up * camUp - dir * camHoriz;
|
||||
float k = CmpOrtho / 3.4f; // 같은 각도를 유지한 채 카메라만 뒤로
|
||||
demoCam.transform.position = focus + UnityEngine.Vector3.up * camUp * k - dir * camHoriz * k;
|
||||
demoCam.transform.LookAt(focus + UnityEngine.Vector3.up * 1.06f);
|
||||
demoCam.orthographic = true; demoCam.orthographicSize = 3.4f;
|
||||
var d = DotA(demoCam, 3.4f);
|
||||
demoCam.orthographic = true; demoCam.orthographicSize = CmpOrtho;
|
||||
var d = DotA(demoCam, CmpOrtho);
|
||||
demoHalf = Upscale(d, W / 2, H / 2);
|
||||
demoHalf.hideFlags = UnityEngine.HideFlags.HideAndDontSave;
|
||||
UnityEngine.Object.DestroyImmediate(d);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
// WL-814q 마감 — 전투장 바닥이 「흙」으로 읽히게 ToonTerrain 머티리얼 변형 1개를 우리 폴더에 만든다.
|
||||
// 🔴 원본 Assets/3DPixelArtEnvironment/Materials/Terrain.mat 은 건드리지 않는다(복사본 생성).
|
||||
// 되돌리기 = 씬 Terrain 의 materialTemplate 을 원본 Terrain.mat 으로 되돌리면 끝.
|
||||
public static class WL814q_Polish
|
||||
{
|
||||
const string ScenePath = "Assets/WL/Look/Arena/Scenes/WL_ArenaProto.unity";
|
||||
const string SrcMat = "Assets/3DPixelArtEnvironment/Materials/Terrain.mat";
|
||||
const string MatDir = "Assets/WL/Look/Arena/Materials";
|
||||
const string NewMat = MatDir + "/WL_ArenaTerrain.mat";
|
||||
|
||||
public static string Run()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
if (!UnityEditor.AssetDatabase.IsValidFolder(MatDir))
|
||||
UnityEditor.AssetDatabase.CreateFolder("Assets/WL/Look/Arena", "Materials");
|
||||
if (UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Material>(NewMat) == null)
|
||||
{
|
||||
if (!UnityEditor.AssetDatabase.CopyAsset(SrcMat, NewMat)) return "CopyAsset FAILED";
|
||||
UnityEditor.AssetDatabase.Refresh();
|
||||
}
|
||||
var m = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Material>(NewMat);
|
||||
if (m == null) return "NEW MAT NOT FOUND";
|
||||
// 데모 원본: _GreenHighlight(0.840,0.830,0.646 카키) → 렌더 결과가 풀과 거의 같은 초록(실측 152,188,119 vs 170,203,126)
|
||||
// 전투장 바닥이 흙으로 읽히도록 이 채널만 Trunk.mat 계열 따뜻한 흙색으로 바꾼다. 나머지 값은 원본 그대로.
|
||||
m.SetColor("_GreenHighlight", new UnityEngine.Color(0.7924528f, 0.6389284f, 0.5121039f, 0f));
|
||||
m.SetColor("_GreenShadow", new UnityEngine.Color(0.3254902f, 0.2352941f, 0.1490196f, 0f));
|
||||
UnityEditor.EditorUtility.SetDirty(m);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
sb.AppendLine("MAT " + NewMat + " _GreenHighlight=" + m.GetColor("_GreenHighlight"));
|
||||
|
||||
var scene = UnityEditor.SceneManagement.EditorSceneManager.OpenScene(ScenePath,
|
||||
UnityEditor.SceneManagement.OpenSceneMode.Single);
|
||||
var t = UnityEngine.Object.FindFirstObjectByType<UnityEngine.Terrain>();
|
||||
if (t == null) return sb + "NO TERRAIN";
|
||||
t.materialTemplate = m;
|
||||
UnityEditor.EditorUtility.SetDirty(t);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(scene);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(scene, ScenePath);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
sb.AppendLine("Terrain.materialTemplate = " + t.materialTemplate.name + " (shader " + t.materialTemplate.shader.name + ")");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>실측 결과 되돌리기 — ToonTerrain 은 터레인 스플랫을 쓰지 않는다(Probe3 실측:
|
||||
/// _RedHighlight 만 화면에 나오고 _GreenHighlight 는 어디에도 안 나온다). 흙 채널 변형은 의미가 없으므로
|
||||
/// 데모 원본 Terrain.mat 로 되돌리고 만들었던 변형 머티리얼은 지운다 = 데모와 편차 0.</summary>
|
||||
public static string Revert()
|
||||
{
|
||||
var scene = UnityEditor.SceneManagement.EditorSceneManager.OpenScene(ScenePath,
|
||||
UnityEditor.SceneManagement.OpenSceneMode.Single);
|
||||
var t = UnityEngine.Object.FindFirstObjectByType<UnityEngine.Terrain>();
|
||||
if (t == null) return "NO TERRAIN";
|
||||
t.materialTemplate = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Material>(SrcMat);
|
||||
UnityEditor.EditorUtility.SetDirty(t);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(scene);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(scene, ScenePath);
|
||||
UnityEditor.AssetDatabase.DeleteAsset(NewMat);
|
||||
UnityEditor.AssetDatabase.DeleteAsset(MatDir);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
UnityEditor.AssetDatabase.Refresh();
|
||||
return "Terrain.materialTemplate = " + t.materialTemplate.name + " (원본) · 변형 머티리얼 삭제";
|
||||
}
|
||||
|
||||
/// <summary>캐릭터 실측 — 무기 제외 몸 높이 · 전체 바운즈 · 바인드포즈 기준 높이.</summary>
|
||||
public static string MeasurePc()
|
||||
{
|
||||
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(ScenePath,
|
||||
UnityEditor.SceneManagement.OpenSceneMode.Single);
|
||||
var pc = UnityEngine.GameObject.Find("PC_LH_M05");
|
||||
if (pc == null) return "PC NOT FOUND";
|
||||
var all = new UnityEngine.Bounds(); var body = new UnityEngine.Bounds();
|
||||
bool fa = true, fb = true;
|
||||
foreach (var r in pc.GetComponentsInChildren<UnityEngine.Renderer>(true))
|
||||
{
|
||||
if (fa) { all = r.bounds; fa = false; } else all.Encapsulate(r.bounds);
|
||||
bool weapon = false;
|
||||
foreach (var mm in r.sharedMaterials)
|
||||
if (mm != null && mm.name.ToLower().Contains("sword")) weapon = true;
|
||||
if (weapon) continue;
|
||||
if (fb) { body = r.bounds; fb = false; } else body.Encapsulate(r.bounds);
|
||||
}
|
||||
// 바인드 포즈(원 프리팹) 기준 높이 — 인게임 기준값과 대조용
|
||||
var src = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.GameObject>("Assets/Res_Addr/PC/LH_M05.prefab");
|
||||
var tmp = (UnityEngine.GameObject)UnityEditor.PrefabUtility.InstantiatePrefab(src);
|
||||
tmp.transform.position = UnityEngine.Vector3.zero;
|
||||
tmp.transform.localScale = UnityEngine.Vector3.one * (0.7f * 1.5038f);
|
||||
var bp = new UnityEngine.Bounds(); bool fc = true;
|
||||
foreach (var r in tmp.GetComponentsInChildren<UnityEngine.Renderer>(true))
|
||||
{ if (fc) { bp = r.bounds; fc = false; } else bp.Encapsulate(r.bounds); }
|
||||
UnityEngine.Object.DestroyImmediate(tmp);
|
||||
return string.Format(
|
||||
"PC scale={0:F5} · 바인드포즈 바운즈 높이={1:F4} m · 씬(Idle 포즈) 몸(무기 제외)={2:F4} m · 전체(무기 포함)={3:F4} m · 발끝 y={4:F4}",
|
||||
0.7f * 1.5038f, bp.size.y, body.size.y, all.size.y, body.min.y);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// ToonTerrain 이 터레인 스플랫(_Control) 을 실제로 쓰는지 최종 판정.
|
||||
// R=마젠타 · G=시안 으로 동시에 바꾼 뒤 아레나 카메라(각도 43.61°)와 탑다운 둘 다 찍는다.
|
||||
public static class WL814q_Probe3
|
||||
{
|
||||
const string ScenePath = "Assets/WL/Look/Arena/Scenes/WL_ArenaProto.unity";
|
||||
const string NewMat = "Assets/WL/Look/Arena/Materials/WL_ArenaTerrain.mat";
|
||||
|
||||
static UnityEngine.Texture2D Shot(UnityEngine.Camera cam, int w, int h)
|
||||
{
|
||||
var rt = new UnityEngine.RenderTexture(w, h, 24, UnityEngine.RenderTextureFormat.ARGB32,
|
||||
UnityEngine.RenderTextureReadWrite.sRGB);
|
||||
rt.Create(); cam.targetTexture = rt; cam.Render();
|
||||
var old = UnityEngine.RenderTexture.active; UnityEngine.RenderTexture.active = rt;
|
||||
var tex = new UnityEngine.Texture2D(w, h, UnityEngine.TextureFormat.RGB24, false);
|
||||
tex.ReadPixels(new UnityEngine.Rect(0, 0, w, h), 0, 0); tex.Apply();
|
||||
UnityEngine.RenderTexture.active = old; cam.targetTexture = null;
|
||||
rt.Release(); UnityEngine.Object.DestroyImmediate(rt);
|
||||
return tex;
|
||||
}
|
||||
|
||||
static string Px(UnityEngine.Texture2D t, int x, int y)
|
||||
{
|
||||
var c = t.GetPixel(x, y);
|
||||
return string.Format("({0},{1},{2})", (int)(c.r * 255), (int)(c.g * 255), (int)(c.b * 255));
|
||||
}
|
||||
|
||||
public static string Run()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
var m = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Material>(NewMat);
|
||||
var red = m.GetColor("_RedHighlight"); var grn = m.GetColor("_GreenHighlight");
|
||||
m.SetColor("_RedHighlight", new UnityEngine.Color(1f, 0f, 1f, 0f)); // 마젠타
|
||||
m.SetColor("_GreenHighlight", new UnityEngine.Color(0f, 1f, 1f, 0f)); // 시안
|
||||
UnityEditor.EditorUtility.SetDirty(m); UnityEditor.AssetDatabase.SaveAssets();
|
||||
|
||||
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(ScenePath,
|
||||
UnityEditor.SceneManagement.OpenSceneMode.Single);
|
||||
UnityEngine.Camera cam = null;
|
||||
foreach (var c in UnityEngine.Object.FindObjectsByType<UnityEngine.Camera>(UnityEngine.FindObjectsSortMode.None))
|
||||
if (c.gameObject.name == "Main Camera") cam = c;
|
||||
for (int i = 0; i < 3; i++) UnityEngine.Object.DestroyImmediate(Shot(cam, 64, 64));
|
||||
|
||||
var a = Shot(cam, 540, 960); // 아레나 도트A 각도 · 화면 전부가 반경 5 m 안쪽(스플랫상 흙 1.0)
|
||||
sb.AppendLine("arena-cam(ortho3.4) 지면: " + Px(a, 120, 620) + " " + Px(a, 430, 200) + " " + Px(a, 270, 350));
|
||||
UnityEngine.Object.DestroyImmediate(a);
|
||||
|
||||
cam.orthographic = true; cam.orthographicSize = 22f;
|
||||
cam.transform.position = new UnityEngine.Vector3(0f, 30f, 0f);
|
||||
cam.transform.rotation = UnityEngine.Quaternion.Euler(90f, 0f, 0f);
|
||||
var b = Shot(cam, 540, 960);
|
||||
// (270,480)=중앙(캐릭터가 있으니 살짝 비켜서 샘플) · 안쪽 r≈4 m · 바깥 r≈20 m
|
||||
sb.AppendLine("top-down 중앙옆(r~2m): " + Px(b, 300, 480) + " r~5m: " + Px(b, 340, 560)
|
||||
+ " r~20m: " + Px(b, 60, 100) + " " + Px(b, 500, 880));
|
||||
UnityEngine.Object.DestroyImmediate(b);
|
||||
|
||||
m.SetColor("_RedHighlight", red); m.SetColor("_GreenHighlight", grn);
|
||||
UnityEditor.EditorUtility.SetDirty(m); UnityEditor.AssetDatabase.SaveAssets();
|
||||
sb.AppendLine("restored R=" + m.GetColor("_RedHighlight") + " G=" + m.GetColor("_GreenHighlight"));
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
Reference in New Issue