using UnityEngine; using UnityEditor; using UnityEditor.SceneManagement; using Cinemachine; using TMPro; #if UNITY_EDITOR public class WaitingSceneTemplate : EditorWindow { [UnityEditor.MenuItem("Tools/Create Waiting Scene")] public static void CreateWaitingScene() { // Create a new scene var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); // Create a basic scene setup CreateSceneSetup(); // Save the scene EditorSceneManager.SaveScene(scene, "Assets/Scenes/WaitingScene.unity"); Debug.Log("Waiting Scene created successfully!"); } private static void CreateSceneSetup() { // Create main camera var mainCamera = new GameObject("MainCamera"); var camera = mainCamera.AddComponent(); mainCamera.tag = "MainCamera"; camera.clearFlags = CameraClearFlags.Skybox; mainCamera.transform.position = new Vector3(0, 2, -10); // Create Post-processing layer in project if needed CreateLayerIfNeeded("PostProcessing", 8); // Ensure Ground layer exists CreateLayerIfNeeded("Ground", 9); // Set up cinematic lighting CreateCinematicLighting(); // Set up atmospheric effects AddAtmosphericEffects(); // Set up post-processing CreatePostProcessingVolume(); // Create a dolly track with front viewing positions var dollyTrack = new GameObject("DollyTrack"); var path = dollyTrack.AddComponent(); path.m_Waypoints = new CinemachineSmoothPath.Waypoint[5]; // Set up waypoints for a front-facing path where camera is in front of player // First point - directly in front of player, facing back toward spawn point path.m_Waypoints[0] = new CinemachineSmoothPath.Waypoint { position = new Vector3(0, 1.7f, -15), roll = 0 }; // Second point - farther ahead (closer to beginning) path.m_Waypoints[1] = new CinemachineSmoothPath.Waypoint { position = new Vector3(0, 1.9f, -10), roll = 2 // Slight roll }; // Third point - far ahead (midway to beginning) path.m_Waypoints[2] = new CinemachineSmoothPath.Waypoint { position = new Vector3(0, 2.1f, -5), roll = -2 // Opposite roll }; // Fourth point - close to end (near beginning) path.m_Waypoints[3] = new CinemachineSmoothPath.Waypoint { position = new Vector3(0, 2.3f, -2), roll = 3 // More roll }; // Fifth point - final camera position (at beginning of path) path.m_Waypoints[4] = new CinemachineSmoothPath.Waypoint { position = new Vector3(0, 2.5f, 0), roll = 0 // Level out }; // Create a dolly camera var dollyCamera = new GameObject("DollyCamera"); var virtualCamera = dollyCamera.AddComponent(); virtualCamera.m_Priority = 10; virtualCamera.m_Lens.FieldOfView = 35; // Narrower FOV for more cinematic effect // Add noise for handheld feel var noise = virtualCamera.AddCinemachineComponent(); noise.m_AmplitudeGain = 0.15f; // Subtle shake noise.m_FrequencyGain = 0.3f; // Set up composer for proper framing var composer = virtualCamera.AddCinemachineComponent(); composer.m_TrackedObjectOffset = new Vector3(0, 0.5f, 0); composer.m_LookaheadTime = 0.2f; composer.m_DeadZoneWidth = 0.1f; composer.m_DeadZoneHeight = 0.1f; composer.m_SoftZoneWidth = 0.6f; composer.m_SoftZoneHeight = 0.6f; // Set up transposer for smoother camera movement var transposer = virtualCamera.AddCinemachineComponent(); transposer.m_XDamping = 1f; transposer.m_YDamping = 1f; transposer.m_ZDamping = 1f; // Set slight Dutch angle virtualCamera.m_Lens.Dutch = 2f; // Add dolly cart var dollyCart = new GameObject("DollyCart"); var cart = dollyCart.AddComponent(); cart.m_Path = path; cart.m_Speed = 0f; // Initially stopped - will be controlled by script virtualCamera.transform.SetParent(dollyCart.transform); // Create corridor-style entrance environment CreateEntranceEnvironment(); // Create spawn point - positioned for player to face TOWARD camera (changed direction) var spawnPoint = new GameObject("SpawnPoint"); spawnPoint.transform.position = new Vector3(0, 0, -20); // Keep position but will make player face opposite direction // Create UI canvas var canvas = new GameObject("Canvas", typeof(Canvas), typeof(UnityEngine.UI.CanvasScaler), typeof(UnityEngine.UI.GraphicRaycaster)); var canvasComponent = canvas.GetComponent(); canvasComponent.renderMode = RenderMode.ScreenSpaceOverlay; // Create skip button - properly create UI elements with RectTransform var skipButton = new GameObject("SkipButton", typeof(RectTransform), typeof(UnityEngine.UI.Image)); skipButton.transform.SetParent(canvas.transform, false); var buttonComponent = skipButton.AddComponent(); var buttonRect = skipButton.GetComponent(); buttonRect.anchoredPosition = new Vector2(0, -200); buttonRect.sizeDelta = new Vector2(200, 50); var buttonText = new GameObject("Text", typeof(RectTransform)); buttonText.transform.SetParent(skipButton.transform, false); var text = buttonText.AddComponent(); text.text = "Skip"; text.fontSize = 24; text.alignment = TMPro.TextAlignmentOptions.Center; var textRect = buttonText.GetComponent(); textRect.anchorMin = Vector2.zero; textRect.anchorMax = Vector2.one; textRect.sizeDelta = Vector2.zero; // Create countdown text var countdownText = new GameObject("CountdownText", typeof(RectTransform)); countdownText.transform.SetParent(canvas.transform, false); var countdown = countdownText.AddComponent(); countdown.text = "10"; countdown.fontSize = 36; countdown.alignment = TMPro.TextAlignmentOptions.Center; var countdownRect = countdownText.GetComponent(); countdownRect.anchoredPosition = new Vector2(0, 200); countdownRect.sizeDelta = new Vector2(100, 50); // Create loading overlay var loadingOverlay = new GameObject("LoadingOverlay", typeof(RectTransform), typeof(UnityEngine.UI.Image)); loadingOverlay.transform.SetParent(canvas.transform, false); var loadingImage = loadingOverlay.GetComponent(); loadingImage.color = new Color(0, 0, 0, 0.8f); var loadingRect = loadingOverlay.GetComponent(); loadingRect.anchorMin = Vector2.zero; loadingRect.anchorMax = Vector2.one; loadingRect.sizeDelta = Vector2.zero; loadingOverlay.SetActive(false); // Create waiting scene manager var manager = new GameObject("WaitingSceneManager"); var waitingSceneManager = manager.AddComponent(); waitingSceneManager.spawnPoint = spawnPoint.transform; waitingSceneManager.dollyCart = cart; waitingSceneManager.dollyCamera = virtualCamera; waitingSceneManager.skipButton = buttonComponent; waitingSceneManager.countdownText = countdown; waitingSceneManager.loadingOverlay = loadingOverlay; // Setup cinematic lights reference var lights = GameObject.Find("CinematicLighting")?.GetComponentsInChildren(); if (lights != null && lights.Length > 0) { waitingSceneManager.cinematicLights = lights; } // Setup atmospheric effects reference var atmosphericEffectsObj = GameObject.Find("AtmosphericEffects"); if (atmosphericEffectsObj != null) { // Get all child objects and convert to array int childCount = atmosphericEffectsObj.transform.childCount; var effectsList = new GameObject[childCount]; for (int i = 0; i < childCount; i++) { effectsList[i] = atmosphericEffectsObj.transform.GetChild(i).gameObject; } waitingSceneManager.atmosphericEffects = effectsList; } // Setup audio references from resources waitingSceneManager.dramaticMusic = Resources.Load("Sounds/DramaticEntrance"); waitingSceneManager.crowdCheering = Resources.Load("Sounds/CrowdCheering"); // If sounds aren't found, try to create placeholder sounds if (waitingSceneManager.dramaticMusic == null) { Debug.LogWarning("DramaticEntrance audio clip not found. Create a 'Sounds/DramaticEntrance' audio clip in Resources folder for best experience."); } if (waitingSceneManager.crowdCheering == null) { Debug.LogWarning("CrowdCheering audio clip not found. Create a 'Sounds/CrowdCheering' audio clip in Resources folder for best experience."); } } private static void CreateCinematicLighting() { // Create a lighting rig parent object var lightingRig = new GameObject("CinematicLighting"); // Create three-point lighting system for night-time dramatic effect // 1. Key Light - main illumination from front-right var keyLight = new GameObject("KeyLight"); keyLight.transform.SetParent(lightingRig.transform); var keyLightComponent = keyLight.AddComponent(); keyLightComponent.type = LightType.Spot; keyLightComponent.color = new Color(0.9f, 0.85f, 0.7f); // Warmer for night keyLightComponent.intensity = 2.5f; // Brighter for contrast against dark keyLightComponent.range = 50f; keyLightComponent.spotAngle = 50f; // Narrower for more dramatic shadows keyLightComponent.shadows = LightShadows.Soft; keyLightComponent.shadowStrength = 0.9f; // Stronger shadows keyLight.transform.position = new Vector3(5, 10, -5); keyLight.transform.LookAt(new Vector3(0, 1, -15)); // Look at player's expected walk path // 2. Fill Light - softer light from opposite side to reduce shadows var fillLight = new GameObject("FillLight"); fillLight.transform.SetParent(lightingRig.transform); var fillLightComponent = fillLight.AddComponent(); fillLightComponent.type = LightType.Spot; fillLightComponent.color = new Color(0.5f, 0.6f, 0.9f); // Cool moonlight-like color fillLightComponent.intensity = 0.8f; // Lower intensity than key fillLightComponent.range = 50f; fillLightComponent.spotAngle = 70f; // Wider angle fillLightComponent.shadows = LightShadows.Soft; fillLightComponent.shadowStrength = 0.5f; // Softer shadows fillLight.transform.position = new Vector3(-8, 8, -10); fillLight.transform.LookAt(new Vector3(0, 1, -15)); // 3. Rim Light (Back Light) - creates outline/separation var rimLight = new GameObject("RimLight"); rimLight.transform.SetParent(lightingRig.transform); var rimLightComponent = rimLight.AddComponent(); rimLightComponent.type = LightType.Spot; rimLightComponent.color = new Color(0.7f, 0.8f, 1f); // Blue-tinted moonlight rimLightComponent.intensity = 2.8f; // Brighter to create rim effect rimLightComponent.range = 40f; rimLightComponent.spotAngle = 40f; // Narrower rimLightComponent.shadows = LightShadows.Hard; // Harder shadows for definition rimLightComponent.shadowStrength = 0.8f; rimLight.transform.position = new Vector3(0, 7, 5); // Behind player's walk path rimLight.transform.LookAt(new Vector3(0, 1, -15)); // 4. Dramatic Spotlight - for emphasis var spotLight = new GameObject("DramaticSpotlight"); spotLight.transform.SetParent(lightingRig.transform); var spotLightComponent = spotLight.AddComponent(); spotLightComponent.type = LightType.Spot; spotLightComponent.color = new Color(1f, 0.9f, 0.7f); // Warm dramatic light spotLightComponent.intensity = 3.5f; // Much brighter for night scene spotLightComponent.range = 30f; spotLightComponent.spotAngle = 25f; // Narrower beam for spotlight effect spotLightComponent.shadows = LightShadows.Soft; spotLightComponent.shadowStrength = 0.9f; spotLight.transform.position = new Vector3(0, 15, -15); // Above player's final position spotLight.transform.LookAt(new Vector3(0, 0, -15)); // 5. Ambient Floor Light - subtle uplighting var floorLight = new GameObject("FloorLight"); floorLight.transform.SetParent(lightingRig.transform); var floorLightComponent = floorLight.AddComponent(); floorLightComponent.type = LightType.Point; floorLightComponent.color = new Color(0.2f, 0.3f, 0.6f); // Blue-ish floor bounce floorLightComponent.intensity = 0.7f; // Subtle but visible floorLightComponent.range = 10f; floorLightComponent.shadows = LightShadows.None; // No shadows for ambient floorLight.transform.position = new Vector3(0, 0.1f, -15); // Just above floor // 6. Add accent lights along the path for night-time effect for (int i = -20; i <= 0; i += 10) { // Left accent light var leftAccent = new GameObject($"LeftAccent_{i}"); leftAccent.transform.SetParent(lightingRig.transform); var leftAccentLight = leftAccent.AddComponent(); leftAccentLight.type = LightType.Point; leftAccentLight.color = new Color(0.1f, 0.2f, 0.7f); // Blue night light leftAccentLight.intensity = 1.5f; leftAccentLight.range = 8f; leftAccentLight.shadows = LightShadows.Soft; leftAccent.transform.position = new Vector3(-3, 0.5f, i); // Right accent light var rightAccent = new GameObject($"RightAccent_{i}"); rightAccent.transform.SetParent(lightingRig.transform); var rightAccentLight = rightAccent.AddComponent(); rightAccentLight.type = LightType.Point; rightAccentLight.color = new Color(0.1f, 0.2f, 0.7f); // Blue night light rightAccentLight.intensity = 1.5f; rightAccentLight.range = 8f; rightAccentLight.shadows = LightShadows.Soft; rightAccent.transform.position = new Vector3(3, 0.5f, i); } // Configure scene lighting settings for night-time RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Flat; RenderSettings.ambientLight = new Color(0.05f, 0.05f, 0.1f); // Very dark blue ambient for night RenderSettings.ambientIntensity = 0.2f; // Low ambient intensity RenderSettings.fog = true; RenderSettings.fogColor = new Color(0.02f, 0.02f, 0.05f); // Very dark night fog RenderSettings.fogMode = FogMode.Exponential; RenderSettings.fogDensity = 0.03f; // Slightly thicker fog for atmosphere // Set night skybox if available Shader skyboxShader = Shader.Find("Skybox/Procedural"); if (skyboxShader != null) { Material skyboxMaterial = new Material(skyboxShader); // Darker sky settings skyboxMaterial.SetFloat("_SunSize", 0.05f); skyboxMaterial.SetFloat("_AtmosphereThickness", 0.5f); skyboxMaterial.SetColor("_SkyTint", new Color(0.3f, 0.3f, 0.5f)); skyboxMaterial.SetColor("_GroundColor", new Color(0.1f, 0.1f, 0.1f)); skyboxMaterial.SetFloat("_Exposure", 0.8f); RenderSettings.skybox = skyboxMaterial; } Debug.Log("Created night-time cinematic lighting setup"); } private static void AddAtmosphericEffects() { // Create parent container var atmosphericEffects = new GameObject("AtmosphericEffects"); // 1. Dust Particles var dustParticles = new GameObject("DustParticles"); dustParticles.transform.SetParent(atmosphericEffects.transform); var dustParticleSystem = dustParticles.AddComponent(); // Configure dust particle system var dustMain = dustParticleSystem.main; dustMain.duration = 5.0f; dustMain.loop = true; dustMain.startLifetime = 8.0f; dustMain.startSpeed = 0.1f; dustMain.startSize = 0.05f; dustMain.maxParticles = 1000; dustMain.simulationSpace = ParticleSystemSimulationSpace.World; // Set a default color that works without relying on materials dustMain.startColor = new ParticleSystem.MinMaxGradient( new Color(0.8f, 0.8f, 0.9f, 0.2f), new Color(0.9f, 0.9f, 1f, 0.05f) ); var dustEmission = dustParticleSystem.emission; dustEmission.rateOverTime = 30; var dustShape = dustParticleSystem.shape; dustShape.shapeType = ParticleSystemShapeType.Box; dustShape.scale = new Vector3(10, 5, 30); dustShape.position = new Vector3(0, 2.5f, -10); // Add renderer with material that works in all pipelines var dustRenderer = dustParticles.GetComponent(); if (dustRenderer != null) { dustRenderer.renderMode = ParticleSystemRenderMode.Billboard; dustRenderer.material = GetParticleMaterial(new Color(1f, 1f, 1f, 0.5f)); } dustParticles.transform.position = new Vector3(0, 0, -10); // 2. Light Rays var lightRays = new GameObject("LightRays"); lightRays.transform.SetParent(atmosphericEffects.transform); var lightRayParticleSystem = lightRays.AddComponent(); // Configure light ray particle system var lightRayMain = lightRayParticleSystem.main; lightRayMain.duration = 5.0f; lightRayMain.loop = true; lightRayMain.startLifetime = 5.0f; lightRayMain.startSpeed = 0.0f; lightRayMain.startSize = 0.5f; lightRayMain.startColor = new Color(1f, 0.95f, 0.8f, 0.2f); // Warm light rays lightRayMain.maxParticles = 20; var lightRayEmission = lightRayParticleSystem.emission; lightRayEmission.rateOverTime = 2; var lightRayShape = lightRayParticleSystem.shape; lightRayShape.shapeType = ParticleSystemShapeType.Cone; lightRayShape.angle = 20; // Add renderer with material that works in all pipelines var lightRayRenderer = lightRays.GetComponent(); if (lightRayRenderer != null) { lightRayRenderer.renderMode = ParticleSystemRenderMode.Billboard; lightRayRenderer.material = GetParticleMaterial(new Color(1f, 0.95f, 0.8f, 0.3f)); } lightRays.transform.position = new Vector3(5, 10, -5); lightRays.transform.rotation = Quaternion.Euler(45, -30, 0); // 3. Fog Volume var fogVolume = new GameObject("FogVolume"); fogVolume.transform.SetParent(atmosphericEffects.transform); var fogParticleSystem = fogVolume.AddComponent(); // Configure fog particle system var fogMain = fogParticleSystem.main; fogMain.duration = 5.0f; fogMain.loop = true; fogMain.startLifetime = 10.0f; fogMain.startSpeed = 0.05f; fogMain.startSize = 2.0f; fogMain.startColor = new Color(0.1f, 0.1f, 0.2f, 0.1f); // Darker for night-time fog fogMain.maxParticles = 50; var fogEmission = fogParticleSystem.emission; fogEmission.rateOverTime = 5; var fogShape = fogParticleSystem.shape; fogShape.shapeType = ParticleSystemShapeType.Box; fogShape.scale = new Vector3(10, 0.5f, 30); // Add renderer with material that works in all pipelines var fogRenderer = fogVolume.GetComponent(); if (fogRenderer != null) { fogRenderer.renderMode = ParticleSystemRenderMode.Billboard; fogRenderer.material = GetParticleMaterial(new Color(0.1f, 0.1f, 0.2f, 0.1f)); } fogVolume.transform.position = new Vector3(0, 0.25f, -10); Debug.Log("Created atmospheric effects with compatible materials"); } private static Material GetParticleMaterial(Color color) { Material material = null; // Try to find a suitable particle shader first Shader particleShader = Shader.Find("Universal Render Pipeline/Particles/Unlit"); if (particleShader == null) particleShader = Shader.Find("Particles/Standard Unlit"); if (particleShader == null) particleShader = Shader.Find("Mobile/Particles/Additive"); if (particleShader == null) particleShader = Shader.Find("Particles/Additive"); if (particleShader == null) particleShader = Shader.Find("Universal Render Pipeline/Particles/Unlit"); // Fallback to a basic shader if (particleShader == null) particleShader = Shader.Find("Unlit/Transparent"); if (particleShader == null) particleShader = Shader.Find("Sprites/Default"); // Last resort - try to use any available shader if (particleShader == null && Shader.Find("Standard") != null) particleShader = Shader.Find("Standard"); if (particleShader != null) { material = new Material(particleShader); material.color = color; } else { // Create a default unlit material if all else fails material = new Material(Shader.Find("Hidden/InternalErrorShader")) { color = color }; Debug.LogWarning("Could not find suitable particle shader. Using fallback material."); } return material; } private static void CreateEntranceEnvironment() { var entranceEnvironment = new GameObject("EntranceEnvironment"); // Create floor/ground - keep this but make it simpler var ground = GameObject.CreatePrimitive(PrimitiveType.Plane); ground.name = "Ground"; ground.transform.SetParent(entranceEnvironment.transform); ground.transform.position = Vector3.zero; ground.transform.localScale = new Vector3(10, 1, 10); // Add a more interesting material to the ground with proper shader detection var groundMaterial = GetMaterial(new Color(0.15f, 0.15f, 0.2f)); // Darker floor for night scene if (groundMaterial != null && ground.GetComponent()) { ground.GetComponent().material = groundMaterial; } // Ensure ground is in the correct layer int groundLayerIndex = LayerMask.NameToLayer("Ground"); ground.layer = groundLayerIndex != -1 ? groundLayerIndex : 0; // Create a path without side walls var entrancePath = GameObject.CreatePrimitive(PrimitiveType.Cube); entrancePath.name = "EntrancePath"; entrancePath.transform.SetParent(entranceEnvironment.transform); entrancePath.transform.position = new Vector3(0, -0.05f, -10); entrancePath.transform.localScale = new Vector3(6, 0.1f, 30); // Add material to the entrance path var pathMaterial = GetMaterial(new Color(0.2f, 0.2f, 0.25f)); // Slightly brighter than ground if (pathMaterial != null && entrancePath.GetComponent()) { entrancePath.GetComponent().material = pathMaterial; entrancePath.GetComponent().receiveShadows = true; } // Ensure entrance path is in Ground layer entrancePath.layer = groundLayerIndex != -1 ? groundLayerIndex : 0; // Create subtle markers along the path without obstructing walls for (int i = -25; i <= -5; i += 5) { // Create subtle floor markers instead of pillars var leftMarker = GameObject.CreatePrimitive(PrimitiveType.Cube); leftMarker.name = $"LeftMarker_{i}"; leftMarker.transform.SetParent(entranceEnvironment.transform); leftMarker.transform.position = new Vector3(-2.5f, 0.05f, i); leftMarker.transform.localScale = new Vector3(0.5f, 0.02f, 0.5f); // Very thin var rightMarker = GameObject.CreatePrimitive(PrimitiveType.Cube); rightMarker.name = $"RightMarker_{i}"; rightMarker.transform.SetParent(entranceEnvironment.transform); rightMarker.transform.position = new Vector3(2.5f, 0.05f, i); rightMarker.transform.localScale = new Vector3(0.5f, 0.02f, 0.5f); // Very thin // Add subtle glow material var markerMaterial = GetMaterial(new Color(0.3f, 0.4f, 0.9f)); if (markerMaterial != null) { if (leftMarker.GetComponent()) { leftMarker.GetComponent().material = markerMaterial; leftMarker.GetComponent().receiveShadows = true; } if (rightMarker.GetComponent()) { rightMarker.GetComponent().material = markerMaterial; rightMarker.GetComponent().receiveShadows = true; } } } // Create a subtle end marker (instead of banner) var endMarker = GameObject.CreatePrimitive(PrimitiveType.Cylinder); endMarker.name = "EndMarker"; endMarker.transform.SetParent(entranceEnvironment.transform); endMarker.transform.position = new Vector3(0, 0.05f, 0); endMarker.transform.localScale = new Vector3(3f, 0.02f, 3f); endMarker.transform.rotation = Quaternion.Euler(0, 0, 0); var endMarkerMaterial = GetMaterial(new Color(0.7f, 0.3f, 0.3f)); if (endMarkerMaterial != null && endMarker.GetComponent()) { endMarker.GetComponent().material = endMarkerMaterial; } Debug.Log("Created minimalist entrance environment without walls"); } // Helper method to get appropriate material based on current render pipeline private static Material GetMaterial(Color color, float smoothness = 0.3f) { Material material = null; // Try URP shader first Shader urpShader = Shader.Find("Universal Render Pipeline/Lit"); if (urpShader != null) { material = new Material(urpShader); material.color = color; // URP specific properties material.SetFloat("_Smoothness", smoothness); } // Try HDRP shader else if (Shader.Find("HDRP/Lit") != null) { material = new Material(Shader.Find("HDRP/Lit")); material.color = color; // HDRP specific properties material.SetFloat("_Smoothness", smoothness); } // Try legacy Standard shader else if (Shader.Find("Standard") != null) { material = new Material(Shader.Find("Standard")); material.color = color; material.SetFloat("_Glossiness", smoothness); } // Fallback to built-in Diffuse shader which exists in all Unity versions else if (Shader.Find("Diffuse") != null) { material = new Material(Shader.Find("Diffuse")); material.color = color; } // Last resort fallback - Unlit color else { material = new Material(Shader.Find("Unlit/Color")); material.color = color; } return material; } // Create post-processing volume for cinematic look private static void CreatePostProcessingVolume() { // Create post-processing volume var ppVolumeObject = new GameObject("Post Process Volume"); var postProcessVolume = ppVolumeObject.AddComponent(); ppVolumeObject.layer = LayerMask.NameToLayer("PostProcessing"); // If post-processing layer doesn't exist, use Default if (ppVolumeObject.layer == -1) { ppVolumeObject.layer = 0; } postProcessVolume.isGlobal = true; postProcessVolume.priority = 1; // Create a new profile var profile = ScriptableObject.CreateInstance(); postProcessVolume.profile = profile; // Add post-processing layer to main camera var mainCamera = GameObject.FindGameObjectWithTag("MainCamera"); if (mainCamera != null) { var ppLayer = mainCamera.AddComponent(); ppLayer.volumeLayer = 1 << 0; // Default layer ppLayer.antialiasingMode = UnityEngine.Rendering.PostProcessing.PostProcessLayer.Antialiasing.FastApproximateAntialiasing; } } // Helper method to create a layer if it doesn't exist private static void CreateLayerIfNeeded(string layerName, int layerIndex) { #if UNITY_EDITOR // Open tag manager SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]); SerializedProperty layersProp = tagManager.FindProperty("layers"); // Check if layer already exists bool exists = false; for (int i = 0; i < layersProp.arraySize; i++) { SerializedProperty layerProp = layersProp.GetArrayElementAtIndex(i); if (layerProp.stringValue == layerName) { exists = true; break; } } // If layer doesn't exist and layer index is valid, add it if (!exists && layerIndex >= 8 && layerIndex <= 31) { layersProp.GetArrayElementAtIndex(layerIndex).stringValue = layerName; tagManager.ApplyModifiedProperties(); Debug.Log($"Layer '{layerName}' created at index {layerIndex}"); } #endif } } #endif