/*
* 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