Files
Bachelor-Arbeit-Adrian-Haefner/Library/PackageCache/com.unity.xr.arfoundation@ef86c118adc4/Editor/Simulation/XREnvironmentViewUtilities.cs
adriadri6972 d3d9c5f833 upload project
2025-07-31 15:21:08 +02:00

291 lines
11 KiB
C#

using System;
using UnityEditor.SceneManagement;
using UnityEditor.UIElements;
using UnityEditor.XR.Management;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.XR.Simulation;
namespace UnityEditor.XR.Simulation
{
[InitializeOnLoad]
static class XREnvironmentViewUtilities
{
static bool s_HasEnvironmentSettings;
static BaseSimulationSceneManager s_SimulationSceneManager;
static SimulationRenderSettings s_SimulationRenderSettings;
// Used to lock out the use of temp render settings and lighting when switching scenes.
static bool s_RenderingOverrideEnabled;
static bool s_LightingOverrideActive;
internal static SimulationRenderSettings simulationRenderSettings => s_SimulationRenderSettings;
internal static bool lightingOverrideActive => s_LightingOverrideActive;
internal static bool renderingOverrideEnabled
{
get => s_RenderingOverrideEnabled;
set => s_RenderingOverrideEnabled = value;
}
static XREnvironmentViewUtilities()
{
s_SimulationRenderSettings = new SimulationRenderSettings();
EditorApplication.playModeStateChanged += PlayModeStateChanged;
CameraTextureProvider.preRenderCamera += PreRenderCameraTextureProvider;
CameraTextureProvider.postRenderCamera += PostRenderCameraTextureProvider;
XREnvironmentViewCamera.preRender += PreRenderEnvironmentViewCamera;
XREnvironmentViewCamera.postRender += PostRenderEnvironmentViewCamera;
// Turn off rendering while assembly reloading
AssemblyReloadEvents.beforeAssemblyReload += BeforeAssemblyReload;
SimulationEditorUtilities.CheckIsSimulationSubsystemEnabled();
BaseSimulationSceneManager.environmentTeardownStarted += StartTearDownEnvironment;
// Do this last since attaching to the event also calls it if initialized
BaseSimulationSceneManager.environmentSetupFinished += FinishSetupEnvironment;
}
static void PlayModeStateChanged(PlayModeStateChange mode)
{
var environmentView = XREnvironmentViewManager.instance;
switch (mode)
{
case PlayModeStateChange.EnteredEditMode:
environmentView.OnEnable();
break;
case PlayModeStateChange.EnteredPlayMode:
s_SimulationRenderSettings.UseSceneRenderSettings();
break;
case PlayModeStateChange.ExitingPlayMode:
PostRenderCameraTextureProvider(null);
break;
}
}
static void FinishSetupEnvironment()
{
s_SimulationSceneManager = Application.isPlaying ?
SimulationSessionSubsystem.simulationSceneManager :
XREnvironmentViewManager.instance.activeSceneManager;
s_HasEnvironmentSettings = s_SimulationSceneManager.simulationEnvironment != null;
s_RenderingOverrideEnabled = true;
}
static void StartTearDownEnvironment()
{
RestoreBaseLighting();
// Stop using the environment render settings before tearing down the environment
s_RenderingOverrideEnabled = false;
s_SimulationSceneManager = null;
s_HasEnvironmentSettings = false;
}
static void PreRenderCameraTextureProvider(Camera camera)
{
if (!Application.isPlaying ||!s_HasEnvironmentSettings || s_SimulationRenderSettings == null)
return;
SetOverrideLighting();
}
static void PostRenderCameraTextureProvider(Camera camera)
{
if (!Application.isPlaying)
return;
RestoreBaseLighting();
}
static void PreRenderEnvironmentViewCamera(Camera camera)
{
if (!s_RenderingOverrideEnabled)
return;
// Due to the way XREnvironmentViewCamera is copied, passing the camera in the callback is the wrong camera.
// But scene view camera is already the current camera when we reach this step.
if (!XREnvironmentViewManager.instance.environmentCameras.Contains(Camera.current))
return;
if (!s_HasEnvironmentSettings || s_SimulationRenderSettings == null)
return;
SetOverrideLighting();
}
static void PostRenderEnvironmentViewCamera(Camera camera)
{
if (!s_RenderingOverrideEnabled)
return;
// Due to the way XREnvironmentViewCamera is copied, passing the camera in the callback is the wrong camera.
// But scene view camera is already the current camera when we reach this step.
if (!XREnvironmentViewManager.instance.environmentCameras.Contains(Camera.current))
return;
RestoreBaseLighting();
}
static void SetOverrideLighting()
{
if (!s_RenderingOverrideEnabled || s_SimulationSceneManager == null)
return;
// Do not set scene manager override lighting in prefab stage
if (!s_SimulationSceneManager.environmentScene.IsValid()
|| PrefabStageUtility.GetCurrentPrefabStage() != null)
return;
if (!s_LightingOverrideActive)
s_SimulationRenderSettings.UseSceneRenderSettings();
Unsupported.SetOverrideLightingSettings(s_SimulationSceneManager.environmentScene);
var simulationEnvironment = s_SimulationSceneManager.simulationEnvironment;
if (simulationEnvironment != null)
simulationEnvironment.renderSettings.ApplyTempRenderSettings();
s_LightingOverrideActive = true;
}
internal static void RestoreBaseLighting()
{
if (!s_RenderingOverrideEnabled)
return;
if (s_LightingOverrideActive)
{
s_LightingOverrideActive = false;
Unsupported.RestoreOverrideLightingSettings();
s_SimulationRenderSettings.ApplyTempRenderSettings();
}
}
/// <summary>
/// Track the changes in XR plugin management for the XR Simulation loader being enabled or disabled.
/// </summary>
/// <returns>The hidden visual element that is tracking changes in the xr loader.</returns>
internal static VisualElement TrackStandAloneXRSettingsChange()
{
var trackerElement = new VisualElement();
var property = GetLoadersArrayProperty();
if (property == null)
return null;
property.Next(true);
trackerElement.TrackPropertyValue(property, _ => SetupListTracker(trackerElement) );
return trackerElement;
}
/// <summary>
/// Creates elements to track changes in every loader in the loaders list.
/// </summary>
/// <param name="trackerElement">Parent tracker visual element.</param>
static void SetupListTracker(VisualElement trackerElement)
{
var property = GetLoadersArrayProperty();
if (property == null)
return;
var endProperty = property.GetEndProperty();
property.NextVisible(true); // Expand the first child.
var childIndex = 0;
// Iterate each property under the array and populate the container with preview elements
do
{
// Stop if we've reached the end of the array
if (SerializedProperty.EqualContents(property, endProperty))
break;
// Skip the array size property
if (property.propertyType == SerializedPropertyType.ArraySize)
continue;
VisualElement element;
if (childIndex < trackerElement.childCount)
{
element = trackerElement[childIndex];
element.Unbind();
}
else
{
element = new VisualElement();
trackerElement.Add(element);
}
element.TrackPropertyValue(property, _ => SimulationEditorUtilities.CheckIsSimulationSubsystemEnabled());
++childIndex;
}
while (property.NextVisible(false)); // Never expand children.
// Remove excess elements if the array is now smaller
while (childIndex < trackerElement.childCount)
{
trackerElement.RemoveAt(trackerElement.childCount - 1);
}
SimulationEditorUtilities.CheckIsSimulationSubsystemEnabled();
}
static SerializedProperty GetLoadersArrayProperty()
{
var standaloneSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(BuildTargetGroup.Standalone);
if (standaloneSettings == null)
return null;
var standAloneSettingsSerializedObject = new SerializedObject(standaloneSettings);
var managerInstanceProp = standAloneSettingsSerializedObject.FindProperty("m_LoaderManagerInstance");
var managerInstanceSerializedObject = new SerializedObject(managerInstanceProp.objectReferenceValue);
return managerInstanceSerializedObject.FindProperty("m_Loaders.Array");
}
internal static bool IsBaseSceneView(object obj)
{
if (obj is SceneView sceneView)
return !sceneView.GetType().IsSubclassOf(typeof(SceneView));
return false;
}
static void BeforeAssemblyReload()
{
RestoreBaseLighting();
s_RenderingOverrideEnabled = false;
s_SimulationSceneManager = null;
s_HasEnvironmentSettings = false;
}
/// <summary>
/// Used to toggle all the XR Environment Overlays to create the hidden settings tracking element if the
/// XR Manager Settings were not created before opening the Overlay.
/// </summary>
internal static void ToggleXREnvironmentOverlays()
{
foreach (var sceneViewObj in SceneView.sceneViews)
{
if (sceneViewObj is SceneView sceneView)
{
if (sceneView.TryGetOverlay(XREnvironmentToolbarOverlay.overlayId, out var environmentOverlay))
{
if (environmentOverlay.displayed)
{
environmentOverlay.displayed = false;
EditorApplication.delayCall += () => environmentOverlay.displayed = true;
}
}
}
}
}
}
}