SW 중심대학 OSS GIT 서버
박건태, 이승준, 고기완, 이준호
새로운 배포
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Runtime.CompilerServices;
using UnityEditor;
using UnityEngine;using UnityEngine.Rendering;using UnityEngine.UIElements;using UnityEngine.Serialization;using UnityEngine.XR.Management;
[assembly: InternalsVisibleTo("Unity.XR.Management.Tests")]namespace UnityEngine.XR.Management{ /// <summary>
/// Class to handle active loader and subsystem management for XR. This class is to be added as a
/// ScriptableObject asset in your project and should only be referenced by the an <see cref="XRGeneralSettings"/>
/// instance for its use.
///
/// Given a list of loaders, it will attempt to load each loader in the given order. The first
/// loader that is successful wins and all remaining loaders are ignored. The loader
/// that succeeds is accessible through the <see cref="activeLoader"/> property on the manager.
///
/// Depending on configuration the <see cref="XRGeneralSettings"/> instance will automatically manage the active loader
/// at correct points in the application lifecycle. The user can override certain points in the active loader lifecycle
/// and manually manage them by toggling the <see cref="XRGeneralSettings.automaticLoading"/> and <see cref="XRGeneralSettings.automaticRunning"/>
/// properties. Disabling <see cref="XRGeneralSettings.automaticLoading"/> implies the the user is responsible for the full lifecycle
/// of the XR session normally handled by the <see cref="XRGeneralSettings"/> instance. Toggling this to false also toggles
/// <see cref="XRGeneralSettings.automaticRunning"/> false.
///
/// Disabling <see cref="XRGeneralSettings.automaticRunning"/> only implies that the user is responsible for starting and stopping
/// the <see cref="activeLoader"/> through the <see cref="StartSubsystems"/> and <see cref="StopSubsystems"/> APIs.
///
/// Automatic lifecycle management is executed as follows
///
/// * OnEnable -> <see cref="InitializeLoader"/>. The loader list will be iterated over and the first successful loader will be set as the active loader.
/// * Start -> <see cref="StartSubsystems"/>. Ask the active loader to start all subsystems.
/// * OnDisable -> <see cref="StopSubsystems"/>. Ask the active loader to stop all subsystems.
/// * OnDestroy -> <see cref="DeinitializeLoader"/>. Deinitialize and remove the active loader.
/// </summary>
public sealed class XRManagerSettings : ScriptableObject { [HideInInspector] bool m_InitializationComplete = false;
#pragma warning disable 414
// This property is only used by the scriptable object editing part of the system and as such no one
// directly references it. Have to manually disable the console warning here so that we can
// get a clean console report.
[HideInInspector] [SerializeField] bool m_RequiresSettingsUpdate = false;#pragma warning restore 414
[SerializeField] [Tooltip("Determines if the XR Manager instance is responsible for creating and destroying the appropriate loader instance.")] [FormerlySerializedAs("AutomaticLoading")] bool m_AutomaticLoading = false;
/// <summary>
/// Get and set Automatic Loading state for this manager. When this is true, the manager will automatically call
/// <see cref="InitializeLoader"/> and <see cref="DeiitializeLoader"/> for you. When false <see cref="automaticRunning"/>
/// is also set to false and remains that way. This means that disabling automatic loading disables all automatic behavior
/// for the manager.
/// </summary>
public bool automaticLoading { get { return m_AutomaticLoading; } set { m_AutomaticLoading = value; } }
[SerializeField] [Tooltip("Determines if the XR Manager instance is responsible for starting and stopping subsystems for the active loader instance.")] [FormerlySerializedAs("AutomaticRunning")] bool m_AutomaticRunning = false;
/// <summary>
/// Get and set automatic running state for this manager. When set to true the manager will call <see cref="StartSubsystems"/>
/// and <see cref="StopSubsystems"/> APIs at appropriate times. When set to false, or when <see cref="automaticLoading"/> is false
/// then it is up to the user of the manager to handle that same functionality.
/// </summary>
public bool automaticRunning { get { return m_AutomaticRunning; } set { m_AutomaticRunning = value; } }
[SerializeField] [Tooltip("List of XR Loader instances arranged in desired load order.")] [FormerlySerializedAs("Loaders")] List<XRLoader> m_Loaders = new List<XRLoader>();
/// <summary>
/// List of loaders currently managed by this XR Manager instance.
/// </summary>
public List<XRLoader> loaders { get { return m_Loaders; }#if UNITY_EDITOR
set { m_Loaders = value; }#endif
}
/// <summary>
/// Read only boolean letting us know if initialization is completed. Because initialization is
/// handled as a Coroutine, people taking advantage of the auto-lifecycle management of XRManager
/// will need to wait for init to complete before checking for an ActiveLoader and calling StartSubsystems.
/// </summary>
public bool isInitializationComplete { get { return m_InitializationComplete; } }
[HideInInspector] static XRLoader s_ActiveLoader = null;
///<summary>
/// Return the current singleton active loader instance.
///
///</summary>
[HideInInspector] public XRLoader activeLoader { get { return s_ActiveLoader; } private set { s_ActiveLoader = value; } }
/// <summary>
/// Return the current active loader, cast to the requested type. Useful shortcut when you need
/// to get the active loader as something less generic than XRLoader.
/// </summary>
///
/// <typeparam name="T">Requested type of the loader</typeparam>
///
/// <returns>The active loader as requested type, or null.</returns>
public T ActiveLoaderAs<T>() where T : XRLoader { return activeLoader as T; }
/// <summary>
/// Iterate over the configured list of loaders and attempt to initialize each one. The first one
/// that succeeds is set as the active loader and initialization immediately terminates.
///
/// When complete <see cref="isInitializationComplete"/> will be set to true. This will mark that it is safe to
/// call other parts of the API. This does not guarantee that init successfully created a loader. For that
/// you need to check that ActiveLoader is not null.
///
/// Note that there can only be one active loader. Any attempt to initialize a new active loader with one
/// already set will cause a warning to be logged and immediate exit of this function.
///
/// This method is synchronous and on return all state should be immediately checkable.
/// </summary>
public void InitializeLoaderSync() { if (activeLoader != null) { Debug.LogWarning( "XR Management has already initialized an active loader in this scene." + "Please make sure to stop all subsystems and deinitialize the active loader before initializing a new one."); return; }
foreach (var loader in loaders) { if (loader != null) { if (CheckGraphicsAPICompatibility(loader) && loader.Initialize()) { activeLoader = loader; m_InitializationComplete = true; return; } } }
activeLoader = null; }
/// <summary>
/// Iterate over the configured list of loaders and attempt to initialize each one. The first one
/// that succeeds is set as the active loader and initialization immediately terminates.
///
/// When complete <see cref="isInitializationComplete"/> will be set to true. This will mark that it is safe to
/// call other parts of the API. This does not guarantee that init successfully created a loader. For that
/// you need to check that ActiveLoader is not null.
///
/// Note that there can only be one active loader. Any attempt to initialize a new active loader with one
/// already set will cause a warning to be logged and immediate exit of this function.
///
/// Iteration is done asynchronously and this method must be called within the context of a Coroutine.
/// </summary>
///
/// <returns>Enumerator marking the next spot to continue execution at.</returns>
public IEnumerator InitializeLoader() { if (activeLoader != null) { Debug.LogWarning( "XR Management has already initialized an active loader in this scene." + "Please make sure to stop all subsystems and deinitialize the active loader before initializing a new one."); yield break; }
foreach (var loader in loaders) { if (loader != null) { if (CheckGraphicsAPICompatibility(loader) && loader.Initialize()) { activeLoader = loader; m_InitializationComplete = true; yield break; } }
yield return null; }
activeLoader = null; }
private bool CheckGraphicsAPICompatibility(XRLoader loader) { GraphicsDeviceType deviceType = SystemInfo.graphicsDeviceType; List<GraphicsDeviceType> supportedDeviceTypes = loader.GetSupportedGraphicsDeviceTypes(false);
// To help with backward compatibility, if the compatibility list is empty we assume that it does not implement the GetSupportedGraphicsDeviceTypes method
// Therefore we revert to the previous behavior of building or starting the loader regardless of gfx api settings.
if (supportedDeviceTypes.Count > 0 && !supportedDeviceTypes.Contains(deviceType)) { Debug.LogWarning(String.Format("The {0} does not support the initialized graphics device, {1}. Please change the preffered Graphics API in PlayerSettings. Attempting to start the next XR loader.", loader.name, deviceType.ToString())); return false; }
return true; }
/// <summary>
/// If there is an active loader, this will request the loader to start all the subsystems that it
/// is managing.
///
/// You must wait for <see cref="isInitializationComplete"/> to be set to true prior to calling this API.
/// </summary>
public void StartSubsystems() { if (!m_InitializationComplete) { Debug.LogWarning( "Call to StartSubsystems without an initialized manager." + "Please make sure wait for initialization to complete before calling this API."); return; }
if (activeLoader != null) { activeLoader.Start(); } }
/// <summary>
/// If there is an active loader, this will request the loader to stop all the subsystems that it
/// is managing.
///
/// You must wait for <see cref="isInitializationComplete"/> to be set to tru prior to calling this API.
/// </summary>
public void StopSubsystems() { if (!m_InitializationComplete) { Debug.LogWarning( "Call to StopSubsystems without an initialized manager." + "Please make sure wait for initialization to complete before calling this API."); return; }
if (activeLoader != null) { activeLoader.Stop(); } }
/// <summary>
/// If there is an active loader, this function will deinitialize it and remove the active loader instance from
/// management. We will automatically call <see cref="StopSubsystems"/> prior to deinitialization to make sure
/// that things are cleaned up appropriately.
///
/// You must wait for <see cref="isInitializationComplete"/> to be set to tru prior to calling this API.
///
/// Upon return <see cref="isInitializationComplete"/> will be rest to false;
/// </summary>
public void DeinitializeLoader() { if (!m_InitializationComplete) { Debug.LogWarning( "Call to DeinitializeLoader without an initialized manager." + "Please make sure wait for initialization to complete before calling this API."); return; }
StopSubsystems(); if (activeLoader != null) { activeLoader.Deinitialize(); activeLoader = null; }
m_InitializationComplete = false; }
// Use this for initialization
void Start() { if (automaticLoading && automaticRunning) { StartSubsystems(); } }
void OnDisable() { if (automaticLoading && automaticRunning) { StopSubsystems(); } }
void OnDestroy() { if (automaticLoading) { DeinitializeLoader(); } } }}
|