/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * Licensed under the Oculus SDK License Agreement (the "License"); * you may not use the Oculus SDK except in compliance with the License, * which is provided at the time of installation or download, or which * otherwise accompanies this software in either electronic or hard copy form. * * You may obtain a copy of the License at * * https://developer.oculus.com/licenses/oculussdk/ * * Unless required by applicable law or agreed to in writing, the Oculus SDK * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.Linq; using UnityEngine.Serialization; /// /// Represents a prefab that overrides the or /// based on a semantic . /// [System.Serializable] public class OVRScenePrefabOverride : ISerializationCallbackReceiver { /// /// The prefab to instantiate instead of the default one specified in the . /// [FormerlySerializedAs("prefab")] public OVRSceneAnchor Prefab; /// /// The classification label that must be associated with a scene entity in order to instantiate . /// [FormerlySerializedAs("classificationLabel")] public string ClassificationLabel = ""; // We use a custom property drawer to allow the user to select a label among a set of options. // Because the prefabOverrides is an array, and we want each entry to have their own // classification, we need to store an index. That cannot be stored in the custom property drawer // as it would be shared among all entries. We store it here instead. However, to ensure that // this value does not break over time, we update it after de-serialization based on the // classification label and the available classification options. [FormerlySerializedAs("editorClassificationIndex")] [SerializeField] private int _editorClassificationIndex; void ISerializationCallbackReceiver.OnBeforeSerialize() { } void ISerializationCallbackReceiver.OnAfterDeserialize() { if (ClassificationLabel != "") { int IndexOf(string label, IEnumerable collection) { var index = 0; foreach (var item in collection) { if (item == label) { return index; } index++; } return -1; } // We do this ever time we deserialize in case the classification options have been updated // This ensures that the label displayed _editorClassificationIndex = IndexOf(ClassificationLabel, OVRSceneManager.Classification.List); if (_editorClassificationIndex < 0) { Debug.LogError($"[{nameof(OVRScenePrefabOverride)}] OnAfterDeserialize() " + ClassificationLabel + " not found. The Classification list in OVRSceneManager has likely changed"); } } else { // No classification was selected, so we can just assign a default // This typically happens this object was just created _editorClassificationIndex = 0; } } } #if UNITY_EDITOR [CustomPropertyDrawer(typeof(OVRScenePrefabOverride))] internal class OVRSceneManagerEditor : PropertyDrawer { private static readonly string[] ClassificationList = OVRSceneManager.Classification.List.ToArray(); public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return base.GetPropertyHeight(property, label) * 2.2f; } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty labelProperty = property.FindPropertyRelative(nameof(OVRScenePrefabOverride.ClassificationLabel)); SerializedProperty editorClassificationIndex = property.FindPropertyRelative("_editorClassificationIndex"); SerializedProperty prefab = property.FindPropertyRelative(nameof(OVRScenePrefabOverride.Prefab)); EditorGUI.BeginProperty(position, label, property); float y = position.y; float h = position.height / 2; Rect rect = new Rect(position.x, y, position.width, h); if (editorClassificationIndex.intValue == -1) { var list = new List { labelProperty.stringValue + " (invalid)" }; list.AddRange(OVRSceneManager.Classification.List); editorClassificationIndex.intValue = EditorGUI.Popup(rect, 0, list.ToArray())-1; } else { editorClassificationIndex.intValue = EditorGUI.Popup( rect, editorClassificationIndex.intValue, ClassificationList); } if (editorClassificationIndex.intValue >= 0 && editorClassificationIndex.intValue < ClassificationList.Length) { labelProperty.stringValue = OVRSceneManager.Classification.List[editorClassificationIndex.intValue]; } EditorGUI.ObjectField(new Rect(position.x, y + EditorGUI.GetPropertyHeight(labelProperty), position.width, h), prefab); EditorGUI.EndProperty(); } } #endif