VR4Medical/ICI/Library/PackageCache/com.unity.xr.openxr@3903c1059bcf/Editor/OpenXRPackageSettings.cs
2025-07-29 13:45:50 +03:00

203 lines
7.1 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor.XR.OpenXR.Features;
using UnityEditor.Build;
using UnityEditor.Experimental;
using UnityEngine;
using UnityEngine.XR.Management;
using UnityEngine.XR.OpenXR;
using UnityEngine.XR.OpenXR.Features;
namespace UnityEditor.XR.OpenXR
{
[XRConfigurationData("OpenXR", Constants.k_SettingsKey)]
internal class OpenXRPackageSettings : ScriptableObject, ISerializationCallbackReceiver, IPackageSettings
{
[SerializeField]
List<BuildTargetGroup> Keys = new List<BuildTargetGroup>();
[SerializeField]
List<OpenXRSettings> Values = new List<OpenXRSettings>();
Dictionary<BuildTargetGroup, OpenXRSettings> Settings = new Dictionary<BuildTargetGroup, OpenXRSettings>();
public static OpenXRPackageSettings Instance
{
get
{
OpenXRPackageSettings ret = null;
EditorBuildSettings.TryGetConfigObject(Constants.k_SettingsKey, out ret);
if (ret == null)
{
string path = OpenXRPackageSettingsAssetPath();
if (!path.Equals(String.Empty))
{
ret = AssetDatabase.LoadAssetAtPath(path, typeof(OpenXRPackageSettings)) as OpenXRPackageSettings;
if (ret != null)
{
EditorBuildSettings.AddConfigObject(Constants.k_SettingsKey, ret, true);
}
// Can't modify EditorBuildSettings once a build has already started - it won't get picked up
// Not sure how to gracefully fix this, for now fail the build so there are now surprises.
if (BuildPipeline.isBuildingPlayer)
throw new BuildFailedException(
"OpenXR Settings found in project but not yet loaded. Please build again.");
}
}
return ret;
}
}
public static OpenXRPackageSettings GetOrCreateInstance()
{
if (Instance != null)
return Instance;
OpenXRPackageSettings settings = ScriptableObject.CreateInstance<OpenXRPackageSettings>();
if (settings != null)
{
string path = OpenXRPackageSettingsAssetPath();
if (!string.IsNullOrEmpty(path))
{
AssetDatabase.CreateAsset(settings, path);
EditorBuildSettings.AddConfigObject(Constants.k_SettingsKey, settings, true);
AssetDatabase.SaveAssets();
}
}
return settings;
}
internal static readonly string s_PackageSettingsAssetName = "OpenXR Package Settings.asset";
internal static readonly string[] s_PackageSettingsDefaultSettingsPath = { "XR", "Settings" };
string IPackageSettings.PackageSettingsAssetPath()
{
return OpenXRPackageSettingsAssetPath();
}
internal static string OpenXRPackageSettingsAssetPath()
{
return Path.Combine(GetAssetPathForComponents(s_PackageSettingsDefaultSettingsPath), s_PackageSettingsAssetName);
}
internal static string GetAssetPathForComponents(string[] pathComponents, string root = "Assets")
{
if (pathComponents.Length <= 0)
return null;
string path = root;
foreach (var pc in pathComponents)
{
string subFolder = Path.Combine(path, pc);
bool shouldCreate = true;
foreach (var f in AssetDatabase.GetSubFolders(path))
{
if (String.Compare(Path.GetFullPath(f), Path.GetFullPath(subFolder), true) == 0)
{
shouldCreate = false;
break;
}
}
if (shouldCreate)
AssetDatabase.CreateFolder(path, pc);
path = subFolder;
}
return path;
}
public string GetActiveLoaderLibraryPath()
{
return OpenXRChooseRuntimeLibraries.GetLoaderLibraryPath();
}
void IPackageSettings.RefreshFeatureSets()
{
OpenXRFeatureSetManager.InitializeFeatureSets();
}
private bool IsValidBuildTargetGroup(BuildTargetGroup buildTargetGroup) =>
buildTargetGroup == BuildTargetGroup.Standalone ||
Enum.GetValues(typeof(BuildTarget)).Cast<BuildTarget>().Any(bt =>
{
var group = BuildPipeline.GetBuildTargetGroup(bt);
return group == buildTargetGroup && BuildPipeline.IsBuildTargetSupported(group, bt);
});
public OpenXRSettings GetSettingsForBuildTargetGroup(BuildTargetGroup buildTargetGroup)
{
OpenXRSettings ret = null;
Settings.TryGetValue(buildTargetGroup, out ret);
if (ret == null)
{
if (!IsValidBuildTargetGroup(buildTargetGroup))
return null;
ret = ScriptableObject.CreateInstance<OpenXRSettings>();
if (Settings.ContainsKey(buildTargetGroup))
{
Settings[buildTargetGroup] = ret;
}
else
{
Settings.Add(buildTargetGroup, ret);
}
ret.name = buildTargetGroup.ToString();
AssetDatabase.AddObjectToAsset(ret, this);
}
return ret;
}
/// <summary>Pre-serialization action</summary>
public void OnBeforeSerialize()
{
Keys.Clear();
Values.Clear();
foreach (var kv in Settings)
{
Keys.Add(kv.Key);
Values.Add(kv.Value);
}
}
/// <summary>Post-deserialization action</summary>
public void OnAfterDeserialize()
{
Settings = new Dictionary<BuildTargetGroup, OpenXRSettings>();
for (int i = 0; i < Math.Min(Keys.Count, Values.Count); i++)
{
Settings.Add(Keys[i], Values[i]);
}
}
/// <summary>
/// Return all features of the given type from all available build target groups.
/// </summary>
/// <typeparam name="T">Feature type to retrieve</typeparam>
/// <returns>All features and their build target group that match the given feature type.</returns>
public IEnumerable<(BuildTargetGroup buildTargetGroup, T feature)> GetFeatures<T>() where T : OpenXRFeature
{
foreach (var kv in Settings)
{
if (kv.Value.features == null)
continue;
foreach (var feature in kv.Value.features)
{
if (feature is T featureT)
yield return (kv.Key, featureT);
}
}
}
}
}