using UnityEngine; namespace Vanguard.App { public enum SceneTheme { Login, Lobby, Collection, DeckBuilder, Battle, } /// /// Простой 3D-фон для экранов: камера, свет, пол и тематические /// примитивы. Это заготовка под будущие модели и арт; UI остаётся /// отдельным Canvas-слоем. /// public static class SceneEnvironment { private const string RootName = "Vanguard 3D Environment"; public static void Build(SceneTheme theme) { if (GameObject.Find(RootName) != null) return; var root = new GameObject(RootName); var palette = GetPalette(theme); SetCamera(theme, palette); SetLight(theme, palette); RenderSettings.ambientLight = palette.Ambient; RenderSettings.fog = true; RenderSettings.fogMode = FogMode.Exponential; RenderSettings.fogColor = palette.Background; RenderSettings.fogDensity = 0.012f; CreateFloor(root.transform, palette); Decorate(theme, root.transform, palette); } private static void SetCamera(SceneTheme theme, ScenePalette palette) { var camera = Camera.main; if (camera == null) { var go = new GameObject("Main Camera"); go.tag = "MainCamera"; camera = go.AddComponent(); } camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = palette.Background; camera.fieldOfView = 52f; camera.transform.position = theme switch { SceneTheme.Battle => new Vector3(0f, 7.5f, -13f), SceneTheme.Login => new Vector3(0f, 2.4f, -9.5f), _ => new Vector3(0f, 3.2f, -10f), }; camera.transform.rotation = theme == SceneTheme.Battle ? Quaternion.Euler(28f, 0f, 0f) : Quaternion.Euler(8f, 0f, 0f); } private static void SetLight(SceneTheme theme, ScenePalette palette) { var light = Object.FindAnyObjectByType(); if (light == null) { var go = new GameObject("Directional Light"); light = go.AddComponent(); light.type = LightType.Directional; } light.color = palette.Light; light.intensity = theme == SceneTheme.Battle ? 1.15f : 0.9f; light.transform.rotation = Quaternion.Euler(48f, -32f, 0f); light.shadows = LightShadows.Soft; if (theme == SceneTheme.Login) { PointLight("Neon Blue", new Vector3(-6f, 2.2f, 0f), new Color(0.16f, 0.42f, 1f), 2.4f, 11f); PointLight("Neon Magenta", new Vector3(6f, 2.2f, 0f), new Color(0.72f, 0.18f, 0.95f), 1.8f, 10f); } } private static void PointLight(string name, Vector3 position, Color color, float intensity, float range) { var go = new GameObject(name); var light = go.AddComponent(); light.type = LightType.Point; light.color = color; light.intensity = intensity; light.range = range; light.shadows = LightShadows.None; go.transform.position = position; } private static void CreateFloor(Transform root, ScenePalette palette) { var floor = GameObject.CreatePrimitive(PrimitiveType.Plane); floor.name = "Floor"; floor.transform.SetParent(root, false); floor.transform.localScale = new Vector3(4f, 1f, 4f); floor.transform.position = new Vector3(0f, -0.02f, 2f); Paint(floor, palette.Floor, 0f); } private static void Decorate(SceneTheme theme, Transform root, ScenePalette palette) { switch (theme) { case SceneTheme.Login: Cube(root, "Column L", new Vector3(-5.5f, 2.4f, 2f), new Vector3(1f, 5f, 1f), palette.Structure); Cube(root, "Column R", new Vector3(5.5f, 2.4f, 2f), new Vector3(1f, 5f, 1f), palette.Structure); Cube(root, "Neon L", new Vector3(-4.95f, 2.4f, 2f), new Vector3(0.08f, 4.4f, 0.08f), palette.Accent, 2.2f); Cube(root, "Neon R", new Vector3(4.95f, 2.4f, 2f), new Vector3(0.08f, 4.4f, 0.08f), palette.Accent, 2.2f); Cube(root, "Backdrop", new Vector3(0f, 3.2f, 8f), new Vector3(16f, 7f, 0.4f), palette.Structure); Cube(root, "Emblem", new Vector3(0f, 3.4f, 7.7f), new Vector3(2.4f, 2.4f, 0.2f), palette.Accent, 1.6f); // Карточный стол и несколько карт — нижний план, форма остаётся по центру. Cube(root, "Card Table", new Vector3(0f, -0.55f, 1.5f), new Vector3(11f, 0.5f, 5.5f), palette.Structure); Cube(root, "Table Neon", new Vector3(0f, -0.28f, 1.5f), new Vector3(10.4f, 0.03f, 0.08f), palette.Accent, 1.8f); Cube(root, "Card A", new Vector3(-3.4f, -0.22f, 2.2f), new Vector3(1.35f, 0.05f, 2.0f), new Color(0.10f, 0.18f, 0.38f), 0.6f); Cube(root, "Card B", new Vector3(-1.8f, -0.18f, 2.7f), new Vector3(1.35f, 0.05f, 2.0f), new Color(0.30f, 0.08f, 0.16f), 0.5f); Cube(root, "Card C", new Vector3(3.0f, -0.18f, 2.5f), new Vector3(1.35f, 0.05f, 2.0f), new Color(0.08f, 0.22f, 0.28f), 0.5f); Cube(root, "Card D", new Vector3(4.4f, -0.22f, 2.0f), new Vector3(1.35f, 0.05f, 2.0f), new Color(0.22f, 0.16f, 0.36f), 0.6f); // Парящие карты по краям — рамка вокруг центральной панели. Cube(root, "Float L", new Vector3(-7.2f, 2.9f, 1.0f), new Vector3(1.5f, 0.06f, 2.2f), new Color(0.10f, 0.16f, 0.34f), 0.8f); Cube(root, "Float R", new Vector3(7.2f, 2.4f, 1.2f), new Vector3(1.5f, 0.06f, 2.2f), new Color(0.28f, 0.08f, 0.18f), 0.8f); break; case SceneTheme.Lobby: for (var i = -1; i <= 1; i += 2) { Cube(root, "Pillar " + i, new Vector3(i * 7f, 2.5f, 3f), new Vector3(1.2f, 5f, 1.2f), palette.Structure); Cube(root, "Table " + i, new Vector3(i * 3.6f, 0.55f, 0.5f), new Vector3(3f, 1f, 3f), palette.Structure); } Cube(root, "Back Wall", new Vector3(0f, 3f, 9f), new Vector3(18f, 6f, 0.5f), palette.Structure); Cube(root, "Lobby Light", new Vector3(0f, 5.2f, 4f), new Vector3(6f, 0.2f, 1f), palette.Accent, 1.8f); break; case SceneTheme.Collection: for (var i = -2; i <= 2; i++) { Cube(root, "Shelf " + i, new Vector3(i * 3.2f, 1.6f, 6.5f), new Vector3(2.2f, 3.2f, 0.5f), palette.Structure); Cube(root, "Shelf Glow " + i, new Vector3(i * 3.2f, 3.35f, 6.2f), new Vector3(2.2f, 0.1f, 0.5f), palette.Accent, 1.2f); } Cube(root, "Table", new Vector3(0f, 0.4f, 1.5f), new Vector3(7f, 0.8f, 4f), palette.Structure); break; case SceneTheme.DeckBuilder: Cube(root, "Table", new Vector3(0f, 0.5f, 2f), new Vector3(11f, 1f, 6f), palette.Structure); Cube(root, "Deck Stack", new Vector3(-3.8f, 1.3f, 3.2f), new Vector3(1.5f, 1.4f, 2.2f), palette.Accent, 0.8f); Cube(root, "Mat", new Vector3(1.5f, 1.06f, 3f), new Vector3(5f, 0.08f, 3.5f), palette.Floor); break; case SceneTheme.Battle: Cube(root, "Battle Table", new Vector3(0f, 0.2f, 1.5f), new Vector3(13f, 0.4f, 7f), palette.Structure); Cube(root, "Center Line", new Vector3(0f, 0.44f, 1.5f), new Vector3(13f, 0.04f, 0.12f), palette.Accent, 1.2f); for (var i = 0; i < 5; i++) { var x = (i - 2) * 2.2f; Cube(root, "Zone " + i, new Vector3(x, 0.44f, 3.1f), new Vector3(1.8f, 0.04f, 2.2f), palette.Zone, 0.5f); Cube(root, "Enemy Zone " + i, new Vector3(x, 0.44f, -0.1f), new Vector3(1.8f, 0.04f, 2.2f), palette.EnemyZone, 0.5f); } break; } } private static void Cube( Transform parent, string name, Vector3 position, Vector3 scale, Color color, float emission = 0f) { var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.name = name; cube.transform.SetParent(parent, false); cube.transform.position = position; cube.transform.localScale = scale; Paint(cube, color, emission); } private static void Paint(GameObject target, Color color, float emission) { var renderer = target.GetComponent(); if (renderer == null) return; var shader = Shader.Find("Universal Render Pipeline/Lit"); if (shader == null) shader = Shader.Find("Standard"); var material = new Material(shader); if (material.HasProperty("_BaseColor")) material.SetColor("_BaseColor", color); else if (material.HasProperty("_Color")) material.color = color; if (emission > 0f) { material.EnableKeyword("_EMISSION"); material.SetColor("_EmissionColor", color * emission); } renderer.material = material; } private static ScenePalette GetPalette(SceneTheme theme) { switch (theme) { case SceneTheme.Login: return new ScenePalette( new Color(0.015f, 0.02f, 0.045f), new Color(0.035f, 0.045f, 0.075f), new Color(0.10f, 0.12f, 0.18f), new Color(0.20f, 0.42f, 0.95f), new Color(0.75f, 0.82f, 1f), new Color(0.04f, 0.05f, 0.09f), new Color(0.10f, 0.20f, 0.40f), new Color(0.40f, 0.12f, 0.10f)); case SceneTheme.Battle: return new ScenePalette( new Color(0.035f, 0.025f, 0.03f), new Color(0.08f, 0.06f, 0.07f), new Color(0.18f, 0.12f, 0.12f), new Color(0.85f, 0.55f, 0.24f), new Color(1f, 0.88f, 0.66f), new Color(0.05f, 0.08f, 0.14f), new Color(0.10f, 0.22f, 0.42f), new Color(0.42f, 0.10f, 0.10f)); default: return new ScenePalette( new Color(0.02f, 0.03f, 0.055f), new Color(0.06f, 0.075f, 0.11f), new Color(0.12f, 0.15f, 0.20f), new Color(0.30f, 0.55f, 0.85f), new Color(0.82f, 0.88f, 1f), new Color(0.08f, 0.11f, 0.17f), new Color(0.16f, 0.30f, 0.52f), new Color(0.38f, 0.12f, 0.12f)); } } private sealed class ScenePalette { public ScenePalette( Color background, Color floor, Color structure, Color accent, Color light, Color ambient, Color zone, Color enemyZone) { Background = background; Floor = floor; Structure = structure; Accent = accent; Light = light; Ambient = ambient; Zone = zone; EnemyZone = enemyZone; } public Color Background { get; } public Color Floor { get; } public Color Structure { get; } public Color Accent { get; } public Color Light { get; } public Color Ambient { get; } public Color Zone { get; } public Color EnemyZone { get; } } } }