Initialer Upload neues Unity-Projekt

This commit is contained in:
Daniel Ocks
2025-07-21 09:11:14 +02:00
commit eeca72985b
14558 changed files with 1508140 additions and 0 deletions

View File

@ -0,0 +1,23 @@
/*
* 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 System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("EditModeTests")]

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: da51b98f15f03d446acef754ccab494d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,54 @@
/*
* 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.
*/
#if OVR_UNITY_ASSET_STORE
#if USING_XR_MANAGEMENT && (USING_XR_SDK_OCULUS || USING_XR_SDK_OPENXR)
#define USING_XR_SDK
#endif
#if UNITY_2020_1_OR_NEWER
#define REQUIRES_XR_SDK
#endif
using System.Diagnostics;
using UnityEngine;
using UnityEditor;
// TODO: rename to MetaXRSimulatorDownloader after UPM migration
public class MetaXRSimulatorEnabler : MonoBehaviour
{
#if !USING_META_XR_SIMULATOR
const string kDownloadSimulator = "Oculus/Download Meta XR Simulator";
[MenuItem(kDownloadSimulator, false, 10000)]
private static void DownloadSimulator()
{
if (EditorUtility.DisplayDialog("Meta XR Simulator", "Download Meta XR Simulator from Oculus server as an UPM tarball, which can be installed through Package Manager.", "Download", "Cancel"))
{
string downloadUrl = "https://npm.developer.oculus.com/-/web/detail/com.meta.xr.simulator";
UnityEngine.Debug.LogFormat("Open Meta XR Simulator URL: {0}", downloadUrl);
Application.OpenURL(downloadUrl);
}
}
#endif
}
#endif // #if OVR_UNITY_ASSET_STORE

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e6431dd3b7073564ca2280d089483532
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,206 @@
/*
* 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 System.Collections.Generic;
using System;
using System.ComponentModel;
using System.Linq;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.Assertions;
using Component = UnityEngine.Component;
/// <summary>
/// Custom Editor for <see cref="OVRCustomFace">
/// </summary>
/// <remarks>
/// Custom Editor for <see cref="OVRCustomFace"> that supports:
/// - attempting to find an <see cref="OVRFaceExpressions"/>in the parent hierarchy to match to if none is chosen
/// - supporting string matching to attempt to automatically match <see cref="OVRFaceExpressions.FaceExpression"/> to blend shapes on the shared mesh
/// The string matching algorithm will tokenize the blend shape names and the <see cref="OVRFaceExpressions.FaceExpression"/> names and for each
/// blend shape find the <see cref="OVRFaceExpressions.FaceExpression"/> with the most total characters in matching tokens.
/// To match tokens it currently uses case invariant matching.
/// The tokenization is based on some common string seperation characters and seperation by camel case.
/// </remarks>
[CustomEditor(typeof(OVRCustomFace))]
public class OVRCustomFaceEditor : Editor
{
private SerializedProperty _expressionsProp;
private SerializedProperty _mappings;
private SerializedProperty _strengthMultiplier;
private SerializedProperty _allowDuplicateMapping;
private bool _showBlendshapes = true;
protected virtual void OnEnable()
{
_expressionsProp = serializedObject.FindProperty(nameof(OVRCustomFace._faceExpressions));
_mappings = serializedObject.FindProperty(nameof(OVRCustomFace._mappings));
_strengthMultiplier = serializedObject.FindProperty(nameof(OVRCustomFace._blendShapeStrengthMultiplier));
_allowDuplicateMapping = serializedObject.FindProperty(nameof(OVRCustomFace._allowDuplicateMapping));
}
public override void OnInspectorGUI()
{
var face = (OVRCustomFace)target;
serializedObject.Update();
if (_expressionsProp.objectReferenceValue == null)
{
_expressionsProp.objectReferenceValue = face.SearchFaceExpressions();
}
if (!IsFaceExpressionsConfigured(face))
{
if (OVREditorUIElements.RenderWarningWithButton(
"OVRFaceExpressions is required.", "Configure OVRFaceExpressions"))
{
FixFaceExpressions(face);
}
}
EditorGUILayout.PropertyField(_expressionsProp, new GUIContent(nameof(OVRFaceExpressions)));
EditorGUILayout.PropertyField(_strengthMultiplier, new GUIContent("Blend Shape Strength Multiplier"));
//need to pass out some property to find the component from
SkinnedMeshRenderer renderer = GetSkinnedMeshRenderer(_expressionsProp);
if (renderer == null || renderer.sharedMesh == null)
{
if (_mappings.arraySize > 0)
{
_mappings.ClearArray();
}
serializedObject.ApplyModifiedProperties();
return;
}
if (_mappings.arraySize != renderer.sharedMesh.blendShapeCount)
{
_mappings.ClearArray();
_mappings.arraySize = renderer.sharedMesh.blendShapeCount;
for (int i = 0; i < renderer.sharedMesh.blendShapeCount; ++i)
{
_mappings.GetArrayElementAtIndex(i).intValue = (int)OVRFaceExpressions.FaceExpression.Invalid;
}
}
EditorGUILayout.Space();
var enumValues = Enum.GetNames(typeof(OVRCustomFace.RetargetingType));
face.retargetingType = (OVRCustomFace.RetargetingType)
EditorGUILayout.Popup("Custom face structure", (int)face.retargetingType, enumValues);
if (face.retargetingType == OVRCustomFace.RetargetingType.OculusFace
|| face.retargetingType == OVRCustomFace.RetargetingType.Custom
)
{
_showBlendshapes = EditorGUILayout.BeginFoldoutHeaderGroup(_showBlendshapes, "Blendshapes");
if (_showBlendshapes)
{
if (GUILayout.Button("Auto Generate Mapping"))
{
face.AutoMapBlendshapes();
Refresh(face);
}
if (GUILayout.Button("Clear Mapping"))
{
face.ClearBlendshapes();
Refresh(face);
}
EditorGUILayout.Space();
for (int i = 0; i < renderer.sharedMesh.blendShapeCount; ++i)
{
EditorGUILayout.PropertyField(_mappings.GetArrayElementAtIndex(i),
new GUIContent(renderer.sharedMesh.GetBlendShapeName(i)));
}
}
}
EditorGUILayout.EndFoldoutHeaderGroup();
EditorGUILayout.PropertyField(_allowDuplicateMapping,
new GUIContent("Allow duplicate mapping"));
serializedObject.ApplyModifiedProperties();
static void Refresh(OVRCustomFace face)
{
EditorUtility.SetDirty(face);
EditorSceneManager.MarkSceneDirty(face.gameObject.scene);
}
}
internal static bool IsFaceExpressionsConfigured(OVRFace face)
{
return face._faceExpressions != null;
}
internal static void FixFaceExpressions(OVRFace face)
{
Undo.IncrementCurrentGroup();
var gameObject = face.gameObject;
var faceExpressions = face.SearchFaceExpressions();
if (!faceExpressions)
{
faceExpressions = gameObject.AddComponent<OVRFaceExpressions>();
Undo.RegisterCreatedObjectUndo(faceExpressions, "Create OVRFaceExpressions component");
}
Undo.RecordObject(face, "Linked OVRFaceExpression");
face._faceExpressions = faceExpressions;
EditorUtility.SetDirty(face);
EditorSceneManager.MarkSceneDirty(gameObject.scene);
Undo.SetCurrentGroupName("Configure OVRFaceExpressions for OVRCustomFace");
}
private static SkinnedMeshRenderer GetSkinnedMeshRenderer(SerializedProperty property)
{
GameObject targetObject = GetGameObject(property);
if (!targetObject)
return null;
return targetObject.GetComponent<SkinnedMeshRenderer>();
}
private static GameObject GetGameObject(SerializedProperty property)
{
Component targetComponent = property.serializedObject.targetObject as Component;
if (targetComponent && targetComponent.gameObject)
{
return targetComponent.gameObject;
}
return null;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a8f1a97fd76f665479039628101a634f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,285 @@
/*
* 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 System;
using System.ComponentModel;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
[CustomEditor(typeof(OVRCustomSkeleton))]
public class OVRCustomSkeletonEditor : OVRSkeletonEditor
{
public override void OnInspectorGUI()
{
var skeleton = (OVRCustomSkeleton)target;
base.OnInspectorGUI();
DrawBonesMapping(skeleton);
}
private static void DrawBonesMapping(OVRCustomSkeleton skeleton)
{
if (GUILayout.Button($"Auto Map Bones"))
{
skeleton.AutoMapBones(skeleton.retargetingType);
EditorUtility.SetDirty(skeleton);
EditorSceneManager.MarkSceneDirty(skeleton.gameObject.scene);
}
EditorGUILayout.LabelField("Bones", EditorStyles.boldLabel);
var start = skeleton.GetCurrentStartBoneId();
var end = skeleton.GetCurrentEndBoneId();
if (skeleton.IsValidBone(start) && skeleton.IsValidBone(end))
{
for (var i = (int)start; i < (int)end; ++i)
{
var boneName = OVRSkeleton.BoneLabelFromBoneId(skeleton.GetSkeletonType(), (OVRSkeleton.BoneId)i);
EditorGUI.BeginChangeCheck();
var val =
EditorGUILayout.ObjectField(boneName, skeleton.CustomBones[i], typeof(Transform), true);
if (EditorGUI.EndChangeCheck())
{
skeleton.CustomBones[i] = (Transform)val;
EditorUtility.SetDirty(skeleton);
}
}
}
}
}
/// <summary>
/// Extensions class for the editor methods of <see cref="OVRCustomSkeleton"/>.
/// </summary>
public static class OVRCustomSkeletonEditorExtensions
{
/// <summary>
/// This method tries to retarget the skeleton structure present in the current <see cref="GameObject"/> to the one supported by the body tracking system.
/// </summary>
/// <param name="customSkeleton" cref="OVRCustomSkeleton">The custom skeleton to run this method on</param>
/// <param name="type" cref="OVRCustomSkeleton.RetargetingType">The skeleton structure to auto map from</param>
public static void AutoMapBones(this OVRCustomSkeleton customSkeleton, OVRCustomSkeleton.RetargetingType type)
{
try
{
switch (type)
{
case OVRCustomSkeleton.RetargetingType.OculusSkeleton:
customSkeleton.AutoMapBonesFromOculusSkeleton();
break;
default:
throw new InvalidEnumArgumentException($"Invalid {nameof(OVRCustomSkeleton.RetargetingType)}");
}
}
catch (Exception e)
{
EditorUtility.DisplayDialog($"Auto Map Bones Error", e.Message, "Ok");
}
}
public static void TryAutoMapBonesByName(this OVRCustomSkeleton customSkeleton)
{
customSkeleton.AutoMapBonesFromOculusSkeleton();
}
internal static void AutoMapBonesFromOculusSkeleton(this OVRCustomSkeleton customSkeleton)
{
var start = customSkeleton.GetCurrentStartBoneId();
var end = customSkeleton.GetCurrentEndBoneId();
var skeletonType = customSkeleton.GetSkeletonType();
if (customSkeleton.IsValidBone(start) && customSkeleton.IsValidBone(end))
{
for (var bi = (int)start; bi < (int)end; ++bi)
{
string fbxBoneName = FbxBoneNameFromBoneId(skeletonType, (OVRSkeleton.BoneId)bi);
Transform t = customSkeleton.transform.FindChildRecursive(fbxBoneName);
if (t == null && skeletonType == OVRSkeleton.SkeletonType.Body)
{
var legacyBoneName = fbxBoneName
.Replace("Little", "Pinky")
.Replace("Metacarpal", "Meta");
t = customSkeleton.transform.FindChildRecursive(legacyBoneName);
}
if (t != null)
{
customSkeleton.CustomBones[bi] = t;
}
}
}
}
internal static bool ClearBonesMapping(this OVRCustomSkeleton skeleton)
{
var start = skeleton.GetCurrentStartBoneId();
var end = skeleton.GetCurrentEndBoneId();
var cleared = false;
if (!skeleton.IsValidBone(start) || !skeleton.IsValidBone(end))
{
return false;
}
for (var i = (int)start; i < (int)end; ++i)
{
if (skeleton.CustomBones[i] != null)
{
skeleton.CustomBones[i] = null;
cleared = true;
}
}
return cleared;
}
private static string FbxBoneNameFromBoneId(OVRSkeleton.SkeletonType skeletonType, OVRSkeleton.BoneId bi)
{
if (skeletonType == OVRSkeleton.SkeletonType.Body)
{
return FBXBodyBoneNames[(int)bi];
}
else
{
if (bi >= OVRSkeleton.BoneId.Hand_ThumbTip && bi <= OVRSkeleton.BoneId.Hand_PinkyTip)
{
return FBXHandSidePrefix[(int)skeletonType] +
FBXHandFingerNames[(int)bi - (int)OVRSkeleton.BoneId.Hand_ThumbTip] +
"_finger_tip_marker";
}
else
{
return FBXHandBonePrefix + FBXHandSidePrefix[(int)skeletonType] + FBXHandBoneNames[(int)bi];
}
}
}
private static readonly string[] FBXBodyBoneNames =
{
"Root",
"Hips",
"SpineLower",
"SpineMiddle",
"SpineUpper",
"Chest",
"Neck",
"Head",
"LeftShoulder",
"LeftScapula",
"LeftArmUpper",
"LeftArmLower",
"LeftHandWristTwist",
"RightShoulder",
"RightScapula",
"RightArmUpper",
"RightArmLower",
"RightHandWristTwist",
"LeftHandPalm",
"LeftHandWrist",
"LeftHandThumbMetacarpal",
"LeftHandThumbProximal",
"LeftHandThumbDistal",
"LeftHandThumbTip",
"LeftHandIndexMetacarpal",
"LeftHandIndexProximal",
"LeftHandIndexIntermediate",
"LeftHandIndexDistal",
"LeftHandIndexTip",
"LeftHandMiddleMetacarpal",
"LeftHandMiddleProximal",
"LeftHandMiddleIntermediate",
"LeftHandMiddleDistal",
"LeftHandMiddleTip",
"LeftHandRingMetacarpal",
"LeftHandRingProximal",
"LeftHandRingIntermediate",
"LeftHandRingDistal",
"LeftHandRingTip",
"LeftHandLittleMetacarpal",
"LeftHandLittleProximal",
"LeftHandLittleIntermediate",
"LeftHandLittleDistal",
"LeftHandLittleTip",
"RightHandPalm",
"RightHandWrist",
"RightHandThumbMetacarpal",
"RightHandThumbProximal",
"RightHandThumbDistal",
"RightHandThumbTip",
"RightHandIndexMetacarpal",
"RightHandIndexProximal",
"RightHandIndexIntermediate",
"RightHandIndexDistal",
"RightHandIndexTip",
"RightHandMiddleMetacarpal",
"RightHandMiddleProximal",
"RightHandMiddleIntermediate",
"RightHandMiddleDistal",
"RightHandMiddleTip",
"RightHandRingMetacarpal",
"RightHandRingProximal",
"RightHandRingIntermediate",
"RightHandRingDistal",
"RightHandRingTip",
"RightHandLittleMetacarpal",
"RightHandLittleProximal",
"RightHandLittleIntermediate",
"RightHandLittleDistal",
"RightHandLittleTip"
};
private static readonly string[] FBXHandSidePrefix = { "l_", "r_" };
private const string FBXHandBonePrefix = "b_";
private static readonly string[] FBXHandBoneNames =
{
"wrist",
"forearm_stub",
"thumb0",
"thumb1",
"thumb2",
"thumb3",
"index1",
"index2",
"index3",
"middle1",
"middle2",
"middle3",
"ring1",
"ring2",
"ring3",
"pinky0",
"pinky1",
"pinky2",
"pinky3"
};
private static readonly string[] FBXHandFingerNames =
{
"thumb",
"index",
"middle",
"ring",
"pinky"
};
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 48b4582957a398741abd6d10bcb62042
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,59 @@
/*
* 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 UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;
internal class OVREditorUIElements
{
internal static bool RenderWarningWithButton(string labelString, string buttonString)
{
Assert.IsNotNull(labelString);
Assert.IsNotNull(buttonString);
bool isButtonClicked;
GUIContent Warning = EditorGUIUtility.IconContent("console.warnicon@2x");
var alignByCenter = new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter };
using (var z = new EditorGUILayout.VerticalScope("HelpBox"))
{
EditorGUI.LabelField(z.rect, Warning, EditorStyles.helpBox);
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
var horizontalSpace =
EditorGUIUtility.standardVerticalSpacing * 3 +
EditorGUIUtility.singleLineHeight * 2 + 5;
GUILayout.BeginHorizontal();
GUILayout.Space(horizontalSpace);
GUILayout.Label(labelString, alignByCenter);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Space(horizontalSpace);
isButtonClicked = GUILayout.Button(buttonString);
GUILayout.EndHorizontal();
GUILayout.Space(5);
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
}
return isButtonClicked;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2975e40846d349a688592b73d09cb809
timeCreated: 1678595602

View File

@ -0,0 +1,280 @@
/*
* 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.Diagnostics;
public static class OVREditorUtil
{
private static GUIContent tooltipLink = new GUIContent("[?]");
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupBoolField(Object target, string name, ref bool member, ref bool modified,
string docLink = "")
{
SetupBoolField(target, new GUIContent(name), ref member, ref modified, docLink);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupBoolField(Object target, GUIContent name, ref bool member, ref bool modified,
string docLink = "")
{
EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
bool value = EditorGUILayout.Toggle(name, member);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
member = value;
modified = true;
}
if (!string.IsNullOrEmpty(docLink))
{
DisplayDocLink(docLink);
}
EditorGUILayout.EndHorizontal();
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupIntField(Object target, string name, ref int member, ref bool modified)
{
SetupIntField(target, new GUIContent(name), ref member, ref modified);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupIntField(Object target, GUIContent name, ref int member, ref bool modified)
{
EditorGUI.BeginChangeCheck();
int value = EditorGUILayout.IntField(name, member);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
member = value;
modified = true;
}
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupFloatField(Object target, string name, ref float member, ref bool modified)
{
SetupFloatField(target, new GUIContent(name), ref member, ref modified);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupFloatField(Object target, GUIContent name, ref float member, ref bool modified)
{
EditorGUI.BeginChangeCheck();
float value = EditorGUILayout.FloatField(name, member);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
member = value;
modified = true;
}
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupDoubleField(Object target, string name, ref double member, ref bool modified)
{
SetupDoubleField(target, new GUIContent(name), ref member, ref modified);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupDoubleField(Object target, GUIContent name, ref double member, ref bool modified)
{
EditorGUI.BeginChangeCheck();
double value = EditorGUILayout.DoubleField(name, member);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
member = value;
modified = true;
}
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupColorField(Object target, string name, ref Color member, ref bool modified)
{
SetupColorField(target, new GUIContent(name), ref member, ref modified);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupColorField(Object target, GUIContent name, ref Color member, ref bool modified)
{
EditorGUI.BeginChangeCheck();
Color value = EditorGUILayout.ColorField(name, member);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
member = value;
modified = true;
}
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupLayerMaskField(Object target, string name, ref LayerMask layerMask,
string[] layerMaskOptions, ref bool modified)
{
SetupLayerMaskField(target, new GUIContent(name), ref layerMask, layerMaskOptions, ref modified);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupLayerMaskField(Object target, GUIContent name, ref LayerMask layerMask,
string[] layerMaskOptions, ref bool modified)
{
EditorGUI.BeginChangeCheck();
int value = EditorGUILayout.MaskField(name, layerMask, layerMaskOptions);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
layerMask = value;
}
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupEnumField<T>(Object target, string name, ref T member, ref bool modified,
string docLink = "") where T : struct
{
SetupEnumField(target, new GUIContent(name), ref member, ref modified, docLink);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupEnumField<T>(Object target, GUIContent name, ref T member, ref bool modified,
string docLink = "") where T : struct
{
GUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
T value = (T)(object)EditorGUILayout.EnumPopup(name, member as System.Enum);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
member = value;
modified = true;
}
if (!string.IsNullOrEmpty(docLink))
{
DisplayDocLink(docLink);
}
GUILayout.EndHorizontal();
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupInputField(Object target, string name, ref string member, ref bool modified,
string docLink = "")
{
SetupInputField(target, new GUIContent(name), ref member, ref modified, docLink);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupInputField(Object target, GUIContent name, ref string member, ref bool modified,
string docLink = "")
{
GUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
string value = EditorGUILayout.TextField(name, member);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
member = value;
modified = true;
}
if (!string.IsNullOrEmpty(docLink))
{
DisplayDocLink(docLink);
}
GUILayout.EndHorizontal();
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupTexture2DField(Object target, string name, ref Texture2D member, ref bool modified)
{
SetupTexture2DField(target, new GUIContent(name), ref member, ref modified);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupTexture2DField(Object target, GUIContent name, ref Texture2D member, ref bool modified,
string docLink = "")
{
EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
Texture2D value = (Texture2D)EditorGUILayout.ObjectField(name, member, typeof(Texture2D), false);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
member = value;
modified = true;
}
if (!string.IsNullOrEmpty(docLink))
{
DisplayDocLink(docLink);
}
EditorGUILayout.EndHorizontal();
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupPopupField(Object target, string name, ref int selectedIndex, GUIContent[] options,
ref bool modified)
{
SetupPopupField(target, new GUIContent(name), ref selectedIndex, options, ref modified);
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void SetupPopupField(Object target, GUIContent name, ref int selectedIndex, GUIContent[] options,
ref bool modified)
{
EditorGUI.BeginChangeCheck();
var value = EditorGUILayout.Popup(name, selectedIndex, options);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Changed " + name.text);
selectedIndex = value;
modified = true;
}
}
[Conditional("UNITY_EDITOR_WIN"), Conditional("UNITY_STANDALONE_WIN"), Conditional("UNITY_ANDROID")]
public static void DisplayDocLink(string docLink)
{
#if UNITY_2021_1_OR_NEWER
if (EditorGUILayout.LinkButton(tooltipLink))
{
Application.OpenURL(docLink);
}
#else
if (GUILayout.Button(tooltipLink, GUILayout.ExpandWidth(false)))
{
Application.OpenURL(docLink);
}
#endif
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 00e66be22bd6053489650de094c5efa8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,262 @@
/*
* 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;
[CustomEditor(typeof(OVRManager))]
public class OVRManagerEditor : Editor
{
private SerializedProperty _requestBodyTrackingPermissionOnStartup;
private SerializedProperty _requestFaceTrackingPermissionOnStartup;
private SerializedProperty _requestEyeTrackingPermissionOnStartup;
private SerializedProperty _requestScenePermissionOnStartup;
private bool _expandPermissionsRequest;
void OnEnable()
{
_requestBodyTrackingPermissionOnStartup =
serializedObject.FindProperty(nameof(OVRManager.requestBodyTrackingPermissionOnStartup));
_requestFaceTrackingPermissionOnStartup =
serializedObject.FindProperty(nameof(OVRManager.requestFaceTrackingPermissionOnStartup));
_requestEyeTrackingPermissionOnStartup =
serializedObject.FindProperty(nameof(OVRManager.requestEyeTrackingPermissionOnStartup));
_requestScenePermissionOnStartup =
serializedObject.FindProperty(nameof(OVRManager.requestScenePermissionOnStartup));
}
public override void OnInspectorGUI()
{
serializedObject.ApplyModifiedProperties();
OVRRuntimeSettings runtimeSettings = OVRRuntimeSettings.GetRuntimeSettings();
OVRProjectConfig projectConfig = OVRProjectConfig.GetProjectConfig();
#if UNITY_ANDROID
OVRProjectConfigEditor.DrawTargetDeviceInspector(projectConfig);
EditorGUILayout.Space();
#endif
DrawDefaultInspector();
bool modified = false;
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_ANDROID
OVRManager manager = (OVRManager)target;
EditorGUILayout.Space();
EditorGUILayout.LabelField("Display", EditorStyles.boldLabel);
OVRManager.ColorSpace colorGamut = runtimeSettings.colorSpace;
OVREditorUtil.SetupEnumField(target, new GUIContent("Color Gamut",
"The target color gamut when displayed on the HMD"), ref colorGamut, ref modified,
"https://developer.oculus.com/documentation/unity/unity-color-space/");
manager.colorGamut = colorGamut;
if (modified)
{
runtimeSettings.colorSpace = colorGamut;
OVRRuntimeSettings.CommitRuntimeSettings(runtimeSettings);
}
#endif
EditorGUILayout.Space();
OVRProjectConfigEditor.DrawProjectConfigInspector(projectConfig);
#if UNITY_ANDROID
EditorGUILayout.Space();
EditorGUILayout.LabelField("Mixed Reality Capture for Quest", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
OVREditorUtil.SetupEnumField(target, "ActivationMode", ref manager.mrcActivationMode, ref modified);
EditorGUI.indentLevel--;
#endif
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
manager.expandMixedRealityCapturePropertySheet =
EditorGUILayout.BeginFoldoutHeaderGroup(manager.expandMixedRealityCapturePropertySheet,
"Mixed Reality Capture");
OVREditorUtil.DisplayDocLink("https://developer.oculus.com/documentation/unity/unity-mrc/");
EditorGUILayout.EndHorizontal();
if (manager.expandMixedRealityCapturePropertySheet)
{
string[] layerMaskOptions = new string[32];
for (int i = 0; i < 32; ++i)
{
layerMaskOptions[i] = LayerMask.LayerToName(i);
if (layerMaskOptions[i].Length == 0)
{
layerMaskOptions[i] = "<Layer " + i.ToString() + ">";
}
}
EditorGUI.indentLevel++;
OVREditorUtil.SetupBoolField(target, "Enable MixedRealityCapture", ref manager.enableMixedReality,
ref modified);
OVREditorUtil.SetupEnumField(target, "Composition Method", ref manager.compositionMethod, ref modified);
OVREditorUtil.SetupLayerMaskField(target, "Extra Hidden Layers", ref manager.extraHiddenLayers,
layerMaskOptions, ref modified);
OVREditorUtil.SetupLayerMaskField(target, "Extra Visible Layers", ref manager.extraVisibleLayers,
layerMaskOptions, ref modified);
OVREditorUtil.SetupBoolField(target, "Dynamic Culling Mask", ref manager.dynamicCullingMask, ref modified);
// CompositionMethod.External is the only composition method that is available.
// All other deprecated composition methods should fallback to the path below.
{
// CompositionMethod.External
EditorGUILayout.Space();
EditorGUILayout.LabelField("External Composition", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
OVREditorUtil.SetupColorField(target, "Backdrop Color (Target, Rift)",
ref manager.externalCompositionBackdropColorRift, ref modified);
OVREditorUtil.SetupColorField(target, "Backdrop Color (Target, Quest)",
ref manager.externalCompositionBackdropColorQuest, ref modified);
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
#endif
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_ANDROID
// Multimodal hands and controllers section
#if UNITY_ANDROID
bool launchMultimodalHandsControllersOnStartup =
projectConfig.multimodalHandsControllersSupport != OVRProjectConfig.MultimodalHandsControllersSupport.Disabled;
EditorGUI.BeginDisabledGroup(!launchMultimodalHandsControllersOnStartup);
GUIContent enableConcurrentHandsAndControllersOnStartup = new GUIContent("Launch concurrent hands and controllers mode on startup",
"Launches concurrent hands and controllers on startup for the scene. Concurrent Hands and Controllers Capability must be enabled in the project settings.");
#else
GUIContent enableConcurrentHandsAndControllersOnStartup = new GUIContent("Enable concurrent hands and controllers mode on startup",
"Launches concurrent hands and controllers on startup for the scene.");
#endif
EditorGUILayout.Space();
EditorGUILayout.LabelField("Concurrent hands and controllers", EditorStyles.boldLabel);
#if UNITY_ANDROID
if (!launchMultimodalHandsControllersOnStartup)
{
EditorGUILayout.LabelField(
"Requires Concurrent Hands and Controllers Capability to be enabled in the General section of the Quest features.",
EditorStyles.wordWrappedLabel);
}
#endif
OVREditorUtil.SetupBoolField(target, enableConcurrentHandsAndControllersOnStartup,
ref manager.launchMultimodalHandsControllersOnStartup,
ref modified);
#if UNITY_ANDROID
EditorGUI.EndDisabledGroup();
#endif
#endif
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_ANDROID
// Insight Passthrough section
#if UNITY_ANDROID
bool passthroughCapabilityEnabled =
projectConfig.insightPassthroughSupport != OVRProjectConfig.FeatureSupport.None;
EditorGUI.BeginDisabledGroup(!passthroughCapabilityEnabled);
GUIContent enablePassthroughContent = new GUIContent("Enable Passthrough",
"Enables passthrough functionality for the scene. Can be toggled at runtime. Passthrough Capability must be enabled in the project settings.");
#else
GUIContent enablePassthroughContent = new GUIContent("Enable Passthrough",
"Enables passthrough functionality for the scene. Can be toggled at runtime.");
#endif
EditorGUILayout.Space();
EditorGUILayout.LabelField("Insight Passthrough", EditorStyles.boldLabel);
#if UNITY_ANDROID
if (!passthroughCapabilityEnabled)
{
EditorGUILayout.LabelField(
"Requires Passthrough Capability to be enabled in the General section of the Quest features.",
EditorStyles.wordWrappedLabel);
}
#endif
OVREditorUtil.SetupBoolField(target, enablePassthroughContent, ref manager.isInsightPassthroughEnabled,
ref modified);
#if UNITY_ANDROID
EditorGUI.EndDisabledGroup();
#endif
#endif
#region PermissionRequests
EditorGUILayout.Space();
_expandPermissionsRequest =
EditorGUILayout.BeginFoldoutHeaderGroup(_expandPermissionsRequest, "Permission Requests On Startup");
if (_expandPermissionsRequest)
{
void AddPermissionGroup(bool featureEnabled, string permissionName, SerializedProperty property)
{
using (new EditorGUI.DisabledScope(!featureEnabled))
{
if (!featureEnabled)
{
EditorGUILayout.LabelField(
$"Requires {permissionName} Capability to be enabled in the Quest features section.",
EditorStyles.wordWrappedLabel);
}
var label = new GUIContent(permissionName,
$"Requests {permissionName} permission on start up. {permissionName} Capability must be enabled in the project settings.");
EditorGUILayout.PropertyField(property, label);
}
}
AddPermissionGroup(projectConfig.bodyTrackingSupport != OVRProjectConfig.FeatureSupport.None,
"Body Tracking", _requestBodyTrackingPermissionOnStartup);
AddPermissionGroup(projectConfig.faceTrackingSupport != OVRProjectConfig.FeatureSupport.None,
"Face Tracking", _requestFaceTrackingPermissionOnStartup);
AddPermissionGroup(projectConfig.eyeTrackingSupport != OVRProjectConfig.FeatureSupport.None, "Eye Tracking",
_requestEyeTrackingPermissionOnStartup);
AddPermissionGroup(projectConfig.sceneSupport != OVRProjectConfig.FeatureSupport.None, "Scene",
_requestScenePermissionOnStartup);
}
EditorGUILayout.EndFoldoutHeaderGroup();
#endregion
if (modified)
{
EditorUtility.SetDirty(target);
}
serializedObject.ApplyModifiedProperties();
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_ANDROID
#if !OCULUS_XR_3_3_0_OR_NEWER || UNITY_2020
if (manager.enableDynamicResolution && !PlayerSettings.GetUseDefaultGraphicsAPIs(BuildTarget.Android))
{
UnityEngine.Rendering.GraphicsDeviceType[] apis = PlayerSettings.GetGraphicsAPIs(BuildTarget.Android);
if (apis.Length >= 1 && apis[0] == UnityEngine.Rendering.GraphicsDeviceType.Vulkan)
{
Debug.LogError("Vulkan Dynamic Resolution is not supported on your current build version. Ensure you are on Unity 2021+ with Oculus XR plugin v3.3.0+");
manager.enableDynamicResolution = false;
}
}
#endif
#endif
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9b07d18088099f94fa00fc15e64b2b17
timeCreated: 1502747851
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,216 @@
/*
* 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 System;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
internal static class OVRMovementTool
{
private const string k_SetupCharacterForBodyTrackingMovementToolsMenuStr =
"GameObject/Movement/Setup Character for Body Tracking/";
private const string oculusSkeletonFormat = "Format: Oculus Skeleton";
[MenuItem(k_SetupCharacterForBodyTrackingMovementToolsMenuStr + oculusSkeletonFormat, true)]
private static bool ValidateSetupCharacterForOculusSkeletonBodyTracking()
{
return Selection.activeGameObject != null;
}
[MenuItem(k_SetupCharacterForBodyTrackingMovementToolsMenuStr + oculusSkeletonFormat)]
private static void SetupCharacterForOculusSkeletonBodyTracking()
{
SetUpCharacterForBodyTracking(OVRCustomSkeleton.RetargetingType.OculusSkeleton);
}
private static void SetUpCharacterForBodyTracking(OVRCustomSkeleton.RetargetingType retargetingType)
{
Undo.IncrementCurrentGroup();
var gameObject = Selection.activeGameObject;
var body = gameObject.GetComponentInParent<OVRBody>();
if (!body)
{
body = gameObject.AddComponent<OVRBody>();
Undo.RegisterCreatedObjectUndo(body, "Create OVRBody component");
}
var skeleton = gameObject.GetComponent<OVRCustomSkeleton>();
if (!skeleton)
{
skeleton = gameObject.AddComponent<OVRCustomSkeleton>();
Undo.RegisterCreatedObjectUndo(skeleton, "Create OVRCustomSkeleton component");
}
Undo.RegisterFullObjectHierarchyUndo(skeleton, "Auto-map OVRCustomSkeleton bones");
skeleton.SetSkeletonType(OVRSkeleton.SkeletonType.Body);
skeleton.retargetingType = retargetingType;
skeleton.AutoMapBones(retargetingType);
EditorUtility.SetDirty(skeleton);
EditorSceneManager.MarkSceneDirty(skeleton.gameObject.scene);
var projectConfig = OVRProjectConfig.CachedProjectConfig;
projectConfig.bodyTrackingSupport = OVRProjectConfig.FeatureSupport.Supported;
OVRProjectConfig.CommitProjectConfig(projectConfig);
var ovrManager = OVRProjectSetupUtils.FindComponentInScene<OVRManager>();
if (ovrManager != null)
{
ovrManager.requestBodyTrackingPermissionOnStartup = true;
EditorUtility.SetDirty(ovrManager);
}
Undo.SetCurrentGroupName($"Setup Character for {retargetingType} Body Tracking");
}
private const string unityHumanoidFormat = "Format: Unity Humanoid";
[MenuItem(k_SetupCharacterForBodyTrackingMovementToolsMenuStr + unityHumanoidFormat, true)]
private static bool ValidateSetupCharacterForUnityHumanoidBodyTracking()
{
return Selection.activeGameObject != null;
}
[MenuItem(k_SetupCharacterForBodyTrackingMovementToolsMenuStr + unityHumanoidFormat)]
private static void SetupCharacterForUnityHumanoidBodyTracking()
{
try
{
OVRUnityHumanoidSkeletonRetargeter
.ValidateGameObjectForUnityHumanoidRetargeting(Selection.activeGameObject);
}
catch (InvalidOperationException e)
{
EditorUtility.DisplayDialog("Character Setup Error", e.Message, "Ok");
return;
}
SetUpCharacterForUnityHumanoidRetargeting();
}
private static void SetUpCharacterForUnityHumanoidRetargeting()
{
Undo.IncrementCurrentGroup();
var gameObject = Selection.activeGameObject;
var body = gameObject.GetComponent<OVRBody>();
if (!body)
{
body = gameObject.AddComponent<OVRBody>();
Undo.RegisterCreatedObjectUndo(body, "Create OVRBody component");
}
var skeleton = gameObject.GetComponent<OVRUnityHumanoidSkeletonRetargeter>();
if (!skeleton)
{
skeleton = gameObject.AddComponent<OVRUnityHumanoidSkeletonRetargeter>();
Undo.RegisterCreatedObjectUndo(skeleton, "Create OVRCustomSkeleton component");
}
Undo.RegisterFullObjectHierarchyUndo(skeleton, "Auto-map OVRCustomSkeleton bones");
EditorUtility.SetDirty(skeleton);
EditorSceneManager.MarkSceneDirty(skeleton.gameObject.scene);
Undo.SetCurrentGroupName($"Setup Character for Unity Humanoid Retargeting");
}
private const string k_SetupCharacterForFaceTrackingMovementToolsMenuStr =
"GameObject/Movement/Setup Character for Face Tracking/";
private const string oculusFaceFormat = "Format: Oculus Face";
[MenuItem(k_SetupCharacterForFaceTrackingMovementToolsMenuStr + oculusFaceFormat, true)]
private static bool ValidateSetupCharacterForOculusFaceTracking()
{
return Selection.activeGameObject != null;
}
[MenuItem(k_SetupCharacterForFaceTrackingMovementToolsMenuStr + oculusFaceFormat)]
private static void SetupCharacterForOculusFaceTracking()
{
try
{
ValidateGameObjectFaceRetargeting(Selection.activeGameObject);
}
catch (InvalidOperationException e)
{
EditorUtility.DisplayDialog("Character Setup Error", e.Message, "Ok");
return;
}
SetUpCharacterForFaceTracking(OVRCustomFace.RetargetingType.OculusFace);
}
public static void ValidateGameObjectFaceRetargeting(GameObject go)
{
var renderer = go.GetComponent<SkinnedMeshRenderer>();
if (renderer == null || renderer.sharedMesh == null || renderer.sharedMesh.blendShapeCount == 0)
{
throw new InvalidOperationException(
$"Retargeting to Oculus Face requires an {nameof(SkinnedMeshRenderer)} component with a mesh that contains blendshapes.");
}
}
private static void SetUpCharacterForFaceTracking(OVRCustomFace.RetargetingType retargetingType)
{
Undo.IncrementCurrentGroup();
var gameObject = Selection.activeGameObject;
var faceExpressions = gameObject.GetComponentInParent<OVRFaceExpressions>();
if (!faceExpressions)
{
faceExpressions = gameObject.AddComponent<OVRFaceExpressions>();
Undo.RegisterCreatedObjectUndo(faceExpressions, "Create OVRFaceExpressions component");
}
var face = gameObject.GetComponent<OVRCustomFace>();
if (!face)
{
face = gameObject.AddComponent<OVRCustomFace>();
face._faceExpressions = faceExpressions;
Undo.RegisterCreatedObjectUndo(face, "Create OVRCustomFace component");
}
Undo.RegisterFullObjectHierarchyUndo(face, "Auto-map OVRCustomFace blendshapes");
face.retargetingType = retargetingType;
face.AutoMapBlendshapes();
EditorUtility.SetDirty(face);
EditorSceneManager.MarkSceneDirty(face.gameObject.scene);
var projectConfig = OVRProjectConfig.CachedProjectConfig;
projectConfig.faceTrackingSupport = OVRProjectConfig.FeatureSupport.Supported;
OVRProjectConfig.CommitProjectConfig(projectConfig);
var ovrManager = OVRProjectSetupUtils.FindComponentInScene<OVRManager>();
if (ovrManager != null)
{
ovrManager.requestFaceTrackingPermissionOnStartup = true;
EditorUtility.SetDirty(ovrManager);
}
Undo.SetCurrentGroupName($"Setup Character for {retargetingType} Face Tracking");
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 285832bbc0585ef40ba90095a03c9449
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,141 @@
/************************************************************************************
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Your use of this SDK or tool is subject to the Oculus SDK License Agreement, available at
https://developer.oculus.com/licenses/oculussdk/
Unless required by applicable law or agreed to in writing, the Utilities 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.
************************************************************************************/
Shader "Unlit/OVROverlayDestRectEditor"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_PaddingAndSize("Padding And Size", Vector) = (4, 4, 128, 128)
_SrcRect("SrcRect", Vector) = (0,0,1,1)
_DestRect ("DestRect", Vector) = (0,0,1,1)
_DragColor ("DragColor", Color) = (1,0,0,1)
_BackgroundColor("Background Color", Color) = (0.278, 0.278, 0.278, 1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 dragLeftRight : TEXCOORD1;
float4 dragTopBottom : TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _PaddingAndSize;
float4 _SrcRect;
float4 _DestRect;
float4 _DragColor;
float4 _BackgroundColor;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// Add padding
o.uv = (o.uv - 0.5) * (_PaddingAndSize.xy + _PaddingAndSize.zw) / _PaddingAndSize.zw + 0.5;
// left
o.dragLeftRight.x = _DestRect.x;
o.dragLeftRight.y = _DestRect.y + _DestRect.w * 0.5;
// right
o.dragLeftRight.z = _DestRect.x + _DestRect.z;
o.dragLeftRight.w = _DestRect.y + _DestRect.w * 0.5;
// top
o.dragTopBottom.x = _DestRect.x + _DestRect.z * 0.5;
o.dragTopBottom.y = _DestRect.y;
// bottom
o.dragTopBottom.z = _DestRect.x + _DestRect.z * 0.5;
o.dragTopBottom.w = _DestRect.y + _DestRect.w;
return o;
}
float onDrag(const float2 uv, const float2 xy)
{
const float2 handleSize = (_PaddingAndSize.xy / 2.0 + 1.0) / _PaddingAndSize.zw;
const float2 offset = abs(uv - xy);
return offset.x <= handleSize.x && offset.y <= handleSize.y;
}
float onLine(const float2 uv, const float4 rect)
{
return
(abs(uv.x - rect.x) < (1 / _PaddingAndSize.z) && uv.y >= rect.y && uv.y <= rect.y + rect.w) ||
(abs(uv.x - rect.x - rect.z) < (1 / _PaddingAndSize.z) && uv.y >= rect.y && uv.y <= rect.y + rect.w) ||
(abs(uv.y - rect.y) < (1 / _PaddingAndSize.w) && uv.x >= rect.x && uv.x <= rect.x + rect.z) ||
(abs(uv.y - rect.y - rect.w) < (1 / _PaddingAndSize.w) && uv.x >= rect.x && uv.x <= rect.x + rect.z);
}
float checkerboard(const float2 uv)
{
const float2 xy = floor(uv * (_PaddingAndSize.xy + _PaddingAndSize.zw) / 8 - _PaddingAndSize.xy / 8);
return xy.x + xy.y - 2.0 * floor((xy.x + xy.y) / 2.0);
}
fixed4 frag (v2f i) : SV_Target
{
const float2 uv = (i.uv - _DestRect.xy) / _DestRect.zw;
const float2 texcoord = uv * _SrcRect.zw + _SrcRect.xy;
// sample the texture
fixed4 col = tex2D(_MainTex, texcoord);
if (uv.x < 0 || uv.x > 1 || uv.y < 0 || uv.y > 1)
{
col.a = 0;
}
col.rgb = lerp(0.41 - 0.13 * checkerboard(i.uv), col.rgb, col.a);
if (i.uv.x < 0 || i.uv.x > 1 || i.uv.y < 0 || i.uv.y > 1)
{
col = _BackgroundColor;
}
// now draw clipping objects
const float drag = onLine(i.uv, _DestRect) ||
onDrag(uv, i.dragLeftRight.xy) ||
onDrag(uv, i.dragLeftRight.zw) ||
onDrag(uv, i.dragTopBottom.xy) ||
onDrag(uv, i.dragTopBottom.zw);
return lerp(col, _DragColor, drag);
}
ENDCG
}
}
}

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 7c52c9bacdbb59f4a973dd1849d03106
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fde3aeb28643f6c48a48f926ac7207e0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,132 @@
/************************************************************************************
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Your use of this SDK or tool is subject to the Oculus SDK License Agreement, available at
https://developer.oculus.com/licenses/oculussdk/
Unless required by applicable law or agreed to in writing, the Utilities 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.
************************************************************************************/
Shader "Unlit/OVROverlaySrcRectEditor"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_PaddingAndSize("Padding And Size", Vector) = (4, 4, 128, 128)
_SrcRect ("SrcRect", Vector) = (0,0,1,1)
_DragColor ("DragColor", Color) = (1, 0, 0, 1)
_BackgroundColor("Background Color", Color) = (0.278, 0.278, 0.278, 1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 dragLeftRight : TEXCOORD1;
float4 dragTopBottom : TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _PaddingAndSize;
float4 _SrcRect;
float4 _DragColor;
float4 _BackgroundColor;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// Add padding
o.uv = (o.uv - 0.5) * (_PaddingAndSize.xy + _PaddingAndSize.zw) / _PaddingAndSize.zw + 0.5;
// left
o.dragLeftRight.x = _SrcRect.x;
o.dragLeftRight.y = _SrcRect.y + _SrcRect.w * 0.5;
// right
o.dragLeftRight.z = _SrcRect.x + _SrcRect.z;
o.dragLeftRight.w = _SrcRect.y + _SrcRect.w * 0.5;
// top
o.dragTopBottom.x = _SrcRect.x + _SrcRect.z * 0.5;
o.dragTopBottom.y = _SrcRect.y;
// bottom
o.dragTopBottom.z = _SrcRect.x + _SrcRect.z * 0.5;
o.dragTopBottom.w = _SrcRect.y + _SrcRect.w;
return o;
}
float onDrag(const float2 uv, const float2 xy)
{
const float2 handleSize = (_PaddingAndSize.xy / 2.0 + 1.0) / _PaddingAndSize.zw;
const float2 offset = abs(uv - xy);
return offset.x <= handleSize.x && offset.y <= handleSize.y;
}
float onLine(const float2 uv, const float4 rect)
{
return
(abs(uv.x - rect.x) < (1 / _PaddingAndSize.z) && uv.y >= rect.y && uv.y <= rect.y + rect.w) ||
(abs(uv.x - rect.x - rect.z) < (1 / _PaddingAndSize.z) && uv.y >= rect.y && uv.y <= rect.y + rect.w) ||
(abs(uv.y - rect.y) < (1 / _PaddingAndSize.w) && uv.x >= rect.x && uv.x <= rect.x + rect.z) ||
(abs(uv.y - rect.y - rect.w) < (1 / _PaddingAndSize.w) && uv.x >= rect.x && uv.x <= rect.x + rect.z);
}
float checkerboard(const float2 uv)
{
const float2 xy = floor(uv * (_PaddingAndSize.xy + _PaddingAndSize.zw) / 8 - _PaddingAndSize.xy / 8);
return xy.x + xy.y - 2.0 * floor((xy.x + xy.y) / 2.0);
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
col.rgb = lerp(0.41 - 0.13 * checkerboard(i.uv), col.rgb, col.a);
if (i.uv.x < 0 || i.uv.x > 1 || i.uv.y < 0 || i.uv.y > 1)
{
col = _BackgroundColor;
}
const float2 uv = i.uv;
// now draw clipping objects
const float drag = onLine(uv, _SrcRect) ||
onDrag(uv, i.dragLeftRight.xy) ||
onDrag(uv, i.dragLeftRight.zw) ||
onDrag(uv, i.dragTopBottom.xy) ||
onDrag(uv, i.dragTopBottom.zw);
return lerp(col, _DragColor, drag);
}
ENDCG
}
}
}

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 589b36d0aa66c7349bcff8750b670434
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,324 @@
/*
* 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 System;
using UnityEditor;
using UnityEngine;
using ColorMapEditorType = OVRPassthroughLayer.ColorMapEditorType;
[CustomPropertyDrawer(typeof(OVRPassthroughLayer.SerializedSurfaceGeometry))]
class SerializedSurfaceGeometryPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// Find the SerializedProperties by name
var meshFilterProperty =
property.FindPropertyRelative(nameof(OVRPassthroughLayer.SerializedSurfaceGeometry.meshFilter));
var updateTransformProperty =
property.FindPropertyRelative(nameof(OVRPassthroughLayer.SerializedSurfaceGeometry.updateTransform));
var propertyHeight = position.height / 2;
using (new EditorGUI.PropertyScope(position, label, property))
{
var surfaceGeometryPropertyPosition = new Rect(position.x, position.y, position.width, propertyHeight);
EditorGUI.PropertyField(surfaceGeometryPropertyPosition, meshFilterProperty,
new GUIContent("Surface Geometry", "The GameObject from which to generate surface geometry."));
var heightOffset = EditorGUI.GetPropertyHeight(updateTransformProperty) +
EditorGUIUtility.standardVerticalSpacing;
var updateTransformPosition =
new Rect(position.x, position.y + heightOffset, position.width, propertyHeight);
EditorGUI.PropertyField(updateTransformPosition, updateTransformProperty, new GUIContent("Update Transform",
"When enabled, updates the mesh's transform every frame. Use this if the GameObject is dynamic."));
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return base.GetPropertyHeight(property, label) * 2.2f;
}
}
[CustomEditor(typeof(OVRPassthroughLayer))]
public class OVRPassthroughLayerEditor : Editor
{
private readonly static string[] _colorMapNames =
{
"None",
"Color Adjustment",
"Grayscale",
"Grayscale to Color",
"Color LUT",
"Blended Color LUTs",
"Custom"
};
private readonly static string[] _selectableColorMapNames =
{
_colorMapNames[0],
_colorMapNames[1],
_colorMapNames[2],
_colorMapNames[3],
_colorMapNames[4],
_colorMapNames[5]
};
private ColorMapEditorType[] _colorMapTypes =
{
ColorMapEditorType.None,
ColorMapEditorType.ColorAdjustment,
ColorMapEditorType.Grayscale,
ColorMapEditorType.GrayscaleToColor,
ColorMapEditorType.ColorLut,
ColorMapEditorType.InterpolatedColorLut,
ColorMapEditorType.Custom
};
private SerializedProperty _projectionSurfaces;
private SerializedProperty _propProjectionSurfaceType;
private SerializedProperty _propOverlayType;
private SerializedProperty _propCompositionDepth;
private SerializedProperty _propTextureOpacity;
private SerializedProperty _propEdgeRenderingEnabled;
private SerializedProperty _propEdgeColor;
private SerializedProperty _propColorMapEditorContrast;
private SerializedProperty _propColorMapEditorBrightness;
private SerializedProperty _propColorMapEditorPosterize;
private SerializedProperty _propColorMapEditorGradient;
private SerializedProperty _propColorMapEditorSaturation;
private SerializedProperty _propColorLutSourceTexture;
private SerializedProperty _propColorLutTargetTexture;
private SerializedProperty _propLutWeight;
private SerializedProperty _propFlipLutY;
void OnEnable()
{
_projectionSurfaces = serializedObject.FindProperty(nameof(OVRPassthroughLayer.serializedSurfaceGeometry));
_propProjectionSurfaceType = serializedObject.FindProperty(nameof(OVRPassthroughLayer.projectionSurfaceType));
_propOverlayType = serializedObject.FindProperty(nameof(OVRPassthroughLayer.overlayType));
_propCompositionDepth = serializedObject.FindProperty(nameof(OVRPassthroughLayer.compositionDepth));
_propTextureOpacity = serializedObject.FindProperty(nameof(OVRPassthroughLayer.textureOpacity_));
_propEdgeRenderingEnabled = serializedObject.FindProperty(nameof(OVRPassthroughLayer.edgeRenderingEnabled_));
_propEdgeColor = serializedObject.FindProperty(nameof(OVRPassthroughLayer.edgeColor_));
_propColorMapEditorContrast = serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorContrast));
_propColorMapEditorBrightness =
serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorBrightness));
_propColorMapEditorPosterize =
serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorPosterize));
_propColorMapEditorSaturation =
serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorSaturation));
_propColorMapEditorGradient = serializedObject.FindProperty(nameof(OVRPassthroughLayer.colorMapEditorGradient));
_propColorLutSourceTexture = serializedObject.FindProperty(nameof(OVRPassthroughLayer._colorLutSourceTexture));
_propColorLutTargetTexture = serializedObject.FindProperty(nameof(OVRPassthroughLayer._colorLutTargetTexture));
_propLutWeight = serializedObject.FindProperty(nameof(OVRPassthroughLayer._lutWeight));
_propFlipLutY = serializedObject.FindProperty(nameof(OVRPassthroughLayer._flipLutY));
}
public override void OnInspectorGUI()
{
OVRPassthroughLayer layer = (OVRPassthroughLayer)target;
serializedObject.Update();
EditorGUILayout.PropertyField(_propProjectionSurfaceType,
new GUIContent("Projection Surface", "The type of projection surface for this Passthrough layer"));
if (layer.projectionSurfaceType == OVRPassthroughLayer.ProjectionSurfaceType.UserDefined)
{
EditorGUILayout.PropertyField(_projectionSurfaces, new GUIContent("Projection Surfaces"));
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Compositing", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(_propOverlayType,
new GUIContent("Placement", "Whether this overlay should layer behind the scene or in front of it"));
EditorGUILayout.PropertyField(_propCompositionDepth,
new GUIContent("Composition Depth",
"Depth value used to sort layers in the scene, smaller value appears in front"));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Style", EditorStyles.boldLabel);
EditorGUILayout.Slider(_propTextureOpacity, 0, 1f, new GUIContent("Opacity"));
EditorGUILayout.Space();
EditorGUILayout.PropertyField(_propEdgeRenderingEnabled,
new GUIContent("Edge Rendering", "Highlight salient edges in the camera images in a specific color"));
EditorGUILayout.PropertyField(_propEdgeColor, new GUIContent("Edge Color"));
if (serializedObject.ApplyModifiedProperties())
{
layer.SetStyleDirty();
}
layer.textureOpacity = _propTextureOpacity.floatValue;
layer.edgeRenderingEnabled = _propEdgeRenderingEnabled.boolValue;
layer.edgeColor = _propEdgeColor.colorValue;
EditorGUILayout.Space();
// Custom popup for color map type to control order, names, and visibility of types
int colorMapTypeIndex = Array.IndexOf(_colorMapTypes, layer.colorMapEditorType);
if (colorMapTypeIndex == -1)
{
Debug.LogWarning("Invalid color map type encountered");
colorMapTypeIndex = 0;
}
// Dropdown list contains "Custom" only if it is currently selected.
string[] colorMapNames = layer.colorMapEditorType == ColorMapEditorType.Custom
? _colorMapNames
: _selectableColorMapNames;
GUIContent[] colorMapLabels = new GUIContent[colorMapNames.Length];
for (int i = 0; i < colorMapNames.Length; i++)
colorMapLabels[i] = new GUIContent(colorMapNames[i]);
bool modified = false;
OVREditorUtil.SetupPopupField(target,
new GUIContent("Color Control", "The type of color controls applied to this layer"), ref colorMapTypeIndex,
colorMapLabels,
ref modified);
layer.colorMapEditorType = _colorMapTypes[colorMapTypeIndex];
if (layer.colorMapEditorType == ColorMapEditorType.Grayscale
|| layer.colorMapEditorType == ColorMapEditorType.GrayscaleToColor
|| layer.colorMapEditorType == ColorMapEditorType.ColorAdjustment)
{
EditorGUILayout.PropertyField(_propColorMapEditorContrast, new GUIContent("Contrast"));
EditorGUILayout.PropertyField(_propColorMapEditorBrightness, new GUIContent("Brightness"));
}
if (layer.colorMapEditorType == ColorMapEditorType.Grayscale
|| layer.colorMapEditorType == ColorMapEditorType.GrayscaleToColor)
{
EditorGUILayout.PropertyField(_propColorMapEditorPosterize, new GUIContent("Posterize"));
}
if (layer.colorMapEditorType == ColorMapEditorType.ColorAdjustment)
{
EditorGUILayout.PropertyField(_propColorMapEditorSaturation, new GUIContent("Saturation"));
}
if (layer.colorMapEditorType == ColorMapEditorType.GrayscaleToColor)
{
EditorGUILayout.PropertyField(_propColorMapEditorGradient, new GUIContent("Colorize"));
}
if (layer.colorMapEditorType == ColorMapEditorType.ColorLut
|| layer.colorMapEditorType == ColorMapEditorType.InterpolatedColorLut)
{
var sourceLutLabel = layer.colorMapEditorType == ColorMapEditorType.ColorLut
? "LUT"
: "Source LUT";
EditorGUILayout.PropertyField(_propColorLutSourceTexture, new GUIContent(sourceLutLabel));
PerformLutTextureCheck((Texture2D)_propColorLutSourceTexture.objectReferenceValue);
if (layer.colorMapEditorType == ColorMapEditorType.InterpolatedColorLut)
{
EditorGUILayout.PropertyField(_propColorLutTargetTexture, new GUIContent("Target LUT"));
PerformLutTextureCheck((Texture2D)_propColorLutTargetTexture.objectReferenceValue);
}
var flipLutYTooltip = "Flip LUT textures along the vertical axis on load. This is needed for LUT " +
"images which have color (0, 0, 0) in the top-left corner. Some color grading systems, " +
"e.g. Unity post-processing, have color (0, 0, 0) in the bottom-left corner, " +
"in which case flipping is not needed.";
EditorGUILayout.PropertyField(_propFlipLutY, new GUIContent("Flip Vertically", flipLutYTooltip));
var weightTooltip = layer.colorMapEditorType == ColorMapEditorType.ColorLut
? "Blend between the original colors and the specified LUT. A value of 0 leaves the colors unchanged, a value of 1 fully applies the LUT."
: "Blend between the source and the target LUT. A value of 0 fully applies the source LUT and a value of 1 fully applies the target LUT.";
EditorGUILayout.PropertyField(_propLutWeight, new GUIContent("Blend", weightTooltip));
}
serializedObject.ApplyModifiedProperties();
}
private void PerformLutTextureCheck(Texture2D texture)
{
if (texture != null)
{
if (!OVRPassthroughColorLut.IsTextureSupported(texture, out var message))
{
EditorGUILayout.HelpBox(message, MessageType.Error);
}
CheckLutImportSettings(texture);
}
}
private void CheckLutImportSettings(Texture lut)
{
if (lut != null)
{
var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(lut)) as TextureImporter;
// Fails when using an internal texture as you can't change import settings on
// builtin resources, thus the check for null
if (importer != null)
{
bool isReadable = importer.isReadable == true;
bool isUncompressed = importer.textureCompression == TextureImporterCompression.Uncompressed;
bool valid = isReadable && isUncompressed;
if (!valid)
{
string warningMessage = ""
+ (isReadable ? "" : "Texture is not readable. ")
+ (isUncompressed ? "" : "Texture is compressed.");
DrawFixMeBox(warningMessage, () => SetLutImportSettings(importer));
}
}
}
}
private void SetLutImportSettings(TextureImporter importer)
{
importer.isReadable = true;
importer.textureCompression = TextureImporterCompression.Uncompressed;
importer.SaveAndReimport();
AssetDatabase.Refresh();
}
private void DrawFixMeBox(string text, Action action)
{
EditorGUILayout.HelpBox(text, MessageType.Warning);
GUILayout.Space(-32);
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (GUILayout.Button("Fix", GUILayout.Width(60)))
action();
GUILayout.Space(8);
}
GUILayout.Space(11);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f49479bb47dde564680a2a5bdf5a6dfe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,41 @@
/*
* 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.
*/
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using Assets.OVR.Scripts;
public class OVRProfilerDeprecated : EditorWindow
{
[MenuItem("Oculus/Tools/(Deprecated) OVR Profiler", false, 200000)]
static void Init()
{
Debug.LogWarning("OVR Profiler has been replaced by OVR Performance Lint Tool");
// Get existing open window or if none, make a new one:
EditorWindow.GetWindow(typeof(OVRLint));
OVRPlugin.SendEvent("perf_lint", "activated");
OVRLint.RunCheck();
}
}
#endif

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad582af7c1f87bf4b99ef951b26ec465
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,399 @@
/*
* 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 System;
using Oculus.VR.Editor;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(OVRProjectConfig))]
public class OVRProjectConfigEditor : Editor
{
override public void OnInspectorGUI()
{
OVRProjectConfig projectConfig = (OVRProjectConfig)target;
DrawTargetDeviceInspector(projectConfig);
EditorGUILayout.Space();
DrawProjectConfigInspector(projectConfig);
}
public static void DrawTargetDeviceInspector(OVRProjectConfig projectConfig)
{
// Target Devices
EditorGUILayout.LabelField("Target Devices", EditorStyles.boldLabel);
bool useOculusXRSettings = false;
#if PRIORITIZE_OCULUS_XR_SETTINGS
EditorGUILayout.LabelField("Configure Target Devices in Oculus XR Plugin Settings:", GUILayout.Width(320));
if (GUILayout.Button("Open Settings"))
SettingsService.OpenProjectSettings("Project/XR Plug-in Management/Oculus");
#if !USING_QUEST_PRO_COMPATIBLE_OCULUS_XR_PLUGIN_VERSION
++EditorGUI.indentLevel;
EditorGUILayout.LabelField("Note: The currently installed Oculus XR Plugin version does not support "
+ "configuring Quest Pro as a target device. Please install a compatible version:"
+ "\n2.2.0-preview.1 or newer\n3.2.1 or newer", EditorStyles.wordWrappedMiniLabel);
--EditorGUI.indentLevel;
#endif
useOculusXRSettings = true;
#endif
if (!useOculusXRSettings)
{
bool hasModified = false;
foreach (OVRProjectConfig.DeviceType deviceType in System.Enum.GetValues(
typeof(OVRProjectConfig.DeviceType)))
{
bool oldSupportsDevice = projectConfig.targetDeviceTypes.Contains(deviceType);
bool newSupportsDevice = oldSupportsDevice;
if (deviceType == OVRProjectConfig.DeviceType.Quest)
{
continue;
}
OVREditorUtil.SetupBoolField(projectConfig, ObjectNames.NicifyVariableName(deviceType.ToString()),
ref newSupportsDevice, ref hasModified);
if (newSupportsDevice && !oldSupportsDevice)
{
projectConfig.targetDeviceTypes.Add(deviceType);
}
else if (oldSupportsDevice && !newSupportsDevice)
{
projectConfig.targetDeviceTypes.Remove(deviceType);
}
}
if (hasModified)
{
OVRProjectConfig.CommitProjectConfig(projectConfig);
}
}
}
enum eProjectConfigTab
{
General = 0,
BuildSettings,
Security,
Experimental,
}
static eProjectConfigTab selectedTab = 0;
static string[] projectConfigTabStrs = null;
public static void DrawProjectConfigInspector(OVRProjectConfig projectConfig)
{
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.LabelField("Quest Features", EditorStyles.boldLabel);
if (EditorUserBuildSettings.activeBuildTarget != UnityEditor.BuildTarget.Android)
{
EditorGUILayout.LabelField(
$"Your current platform is \"{EditorUserBuildSettings.activeBuildTarget}\". These settings only apply if your active platform is \"Android\".",
EditorStyles.wordWrappedMiniLabel);
}
if (projectConfigTabStrs == null)
{
projectConfigTabStrs = Enum.GetNames(typeof(eProjectConfigTab));
for (int i = 0; i < projectConfigTabStrs.Length; ++i)
projectConfigTabStrs[i] = ObjectNames.NicifyVariableName(projectConfigTabStrs[i]);
}
selectedTab =
(eProjectConfigTab)GUILayout.SelectionGrid((int)selectedTab, projectConfigTabStrs, 3, GUI.skin.button);
EditorGUILayout.Space(5);
bool hasModified = false;
switch (selectedTab)
{
case eProjectConfigTab.General:
// Show overlay support option
using (new EditorGUI.DisabledScope(true))
{
EditorGUILayout.Toggle(new GUIContent("Focus Aware (Required)",
"If checked, the new overlay will be displayed when the user presses the home button. The game will not be paused, but will now receive InputFocusLost and InputFocusAcquired events."),
true);
}
// Hand Tracking Support
OVREditorUtil.SetupEnumField(projectConfig, "Hand Tracking Support",
ref projectConfig.handTrackingSupport, ref hasModified);
OVREditorUtil.SetupEnumField(projectConfig, new GUIContent("Hand Tracking Frequency",
"Note that a higher tracking frequency will reserve some performance headroom from the application's budget."),
ref projectConfig.handTrackingFrequency, ref hasModified,
"https://developer.oculus.com/documentation/unity/unity-handtracking/#enable-hand-tracking");
OVREditorUtil.SetupEnumField(projectConfig, "Hand Tracking Version",
ref projectConfig.handTrackingVersion, ref hasModified);
// Concurrent hands and controllers support
OVREditorUtil.SetupEnumField(projectConfig, new GUIContent("Concurrent Hands/Controllers Support",
"Allows the application to use concurrent hands and controllers functionality. This option must be enabled at build time."),
ref projectConfig.multimodalHandsControllersSupport, ref hasModified);
// Enable Render Model Support
bool renderModelSupportAvailable = OVRPluginInfo.IsOVRPluginOpenXRActivated();
EditorGUI.BeginDisabledGroup(!renderModelSupportAvailable);
if (!renderModelSupportAvailable)
{
projectConfig.renderModelSupport = OVRProjectConfig.RenderModelSupport.Disabled;
}
OVREditorUtil.SetupEnumField(projectConfig, new GUIContent("Render Model Support",
"If enabled, the application will be able to load render models from the runtime."),
ref projectConfig.renderModelSupport, ref hasModified);
if (hasModified && projectConfig.renderModelSupport == OVRProjectConfig.RenderModelSupport.Disabled)
{
if (projectConfig.trackedKeyboardSupport != OVRProjectConfig.TrackedKeyboardSupport.None)
{
Debug.LogWarning("Tracked Keyboard support disabled. Requires Render Model Support");
projectConfig.trackedKeyboardSupport = OVRProjectConfig.TrackedKeyboardSupport.None;
}
if (projectConfig.virtualKeyboardSupport != OVRProjectConfig.FeatureSupport.None)
{
Debug.LogWarning("Virtual Keyboard support disabled. Requires Render Model Support");
projectConfig.virtualKeyboardSupport = OVRProjectConfig.FeatureSupport.None;
}
}
EditorGUI.EndDisabledGroup();
// System Keyboard Support
OVREditorUtil.SetupBoolField(projectConfig, new GUIContent("Requires System Keyboard",
"If checked, the Oculus System keyboard will be enabled for Unity input fields and any calls to open/close the Unity TouchScreenKeyboard."),
ref projectConfig.requiresSystemKeyboard, ref hasModified);
// Tracked Keyboard Support
bool trackedKeyboardSupportAvailable = OVRPluginInfo.IsOVRPluginOpenXRActivated();
using (new EditorGUI.DisabledGroupScope(!trackedKeyboardSupportAvailable))
{
if (!trackedKeyboardSupportAvailable)
{
projectConfig.trackedKeyboardSupport = OVRProjectConfig.TrackedKeyboardSupport.None;
}
OVREditorUtil.SetupEnumField(projectConfig, new GUIContent("Tracked Keyboard Support",
"Show user's physical keyboard in correct position in VR."),
ref projectConfig.trackedKeyboardSupport, ref hasModified);
}
// Virtual Keyboard Support
bool virtualKeyboardSupportAvailable = OVRPluginInfo.IsOVRPluginOpenXRActivated();
using (new EditorGUI.DisabledGroupScope(!virtualKeyboardSupportAvailable))
{
if (!virtualKeyboardSupportAvailable)
{
projectConfig.virtualKeyboardSupport = OVRProjectConfig.FeatureSupport.None;
}
OVREditorUtil.SetupEnumField(projectConfig, new GUIContent("Virtual Keyboard Support",
"Provides a consistent typing experience across Meta Quest VR applications."),
ref projectConfig.virtualKeyboardSupport, ref hasModified);
if (projectConfig.requiresSystemKeyboard)
{
EditorGUILayout.HelpBox(
"Using the System Keyboard with Virtual Keyboard is not recommended.",
MessageType.Warning);
}
}
// Anchor Support - linked to Shared Spatial Anchors and Scene
var anchorSupportRequired = projectConfig.sharedAnchorSupport != OVRProjectConfig.FeatureSupport.None;
var anchorSupportTooltip = "Anchor Support is required for Shared Spatial Anchor Support.";
anchorSupportRequired = anchorSupportRequired ||
projectConfig.sceneSupport != OVRProjectConfig.FeatureSupport.None;
anchorSupportTooltip =
"Anchor Support is required for Shared Spatial Anchor Support and/or Scene Support.";
using (new EditorGUI.DisabledScope(anchorSupportRequired))
{
var tooltip = anchorSupportRequired ? anchorSupportTooltip : "";
OVREditorUtil.SetupEnumField(projectConfig, new GUIContent("Anchor Support", tooltip),
ref projectConfig.anchorSupport, ref hasModified);
}
OVREditorUtil.SetupEnumField(projectConfig,
new GUIContent("Shared Spatial Anchor Support",
"Enables support for sharing spatial anchors with other users. This requires Anchor Support to be enabled."),
ref projectConfig.sharedAnchorSupport, ref hasModified);
if (projectConfig.sharedAnchorSupport != OVRProjectConfig.FeatureSupport.None &&
projectConfig.anchorSupport != OVRProjectConfig.AnchorSupport.Enabled)
{
projectConfig.anchorSupport = OVRProjectConfig.AnchorSupport.Enabled;
hasModified = true;
}
// Scene Support
var sceneTooltip =
"Enable support for scene understanding. This requires Anchor Support to be enabled.";
OVREditorUtil.SetupEnumField(projectConfig, new GUIContent("Scene Support", sceneTooltip),
ref projectConfig.sceneSupport, ref hasModified);
// enable anchor support if scene requires it
if (projectConfig.sceneSupport != OVRProjectConfig.FeatureSupport.None &&
projectConfig.anchorSupport != OVRProjectConfig.AnchorSupport.Enabled)
{
projectConfig.anchorSupport = OVRProjectConfig.AnchorSupport.Enabled;
hasModified = true;
}
// Body Tracking Support
OVREditorUtil.SetupEnumField(projectConfig, "Body Tracking Support",
ref projectConfig.bodyTrackingSupport, ref hasModified);
// Face Tracking Support
OVREditorUtil.SetupEnumField(projectConfig, "Face Tracking Support",
ref projectConfig.faceTrackingSupport, ref hasModified);
// Eye Tracking Support
OVREditorUtil.SetupEnumField(projectConfig, "Eye Tracking Support",
ref projectConfig.eyeTrackingSupport, ref hasModified);
if (hasModified && projectConfig.trackedKeyboardSupport != OVRProjectConfig.TrackedKeyboardSupport.None)
{
projectConfig.renderModelSupport = OVRProjectConfig.RenderModelSupport.Enabled;
}
if (hasModified && projectConfig.virtualKeyboardSupport != OVRProjectConfig.FeatureSupport.None)
{
projectConfig.renderModelSupport = OVRProjectConfig.RenderModelSupport.Enabled;
}
if (!OVRPluginInfo.IsOVRPluginOpenXRActivated())
{
EditorGUILayout.HelpBox(
"The OpenXR backend must be enabled in the Oculus menu to use the Render Model and Tracked Keyboard features.",
MessageType.Info);
}
if (projectConfig.trackedKeyboardSupport != OVRProjectConfig.TrackedKeyboardSupport.None &&
projectConfig.renderModelSupport == OVRProjectConfig.RenderModelSupport.Disabled)
{
EditorGUILayout.HelpBox(
"Render model support is required to load keyboard models from the runtime.",
MessageType.Error);
}
if (projectConfig.virtualKeyboardSupport != OVRProjectConfig.FeatureSupport.None &&
projectConfig.renderModelSupport == OVRProjectConfig.RenderModelSupport.Disabled)
{
EditorGUILayout.HelpBox(
"Render model support is required to load virtual keyboard models from the runtime.",
MessageType.Error);
}
// System Splash Screen
bool splashScreenTextureModified = false;
OVREditorUtil.SetupTexture2DField(projectConfig, new GUIContent("System Splash Screen",
"If set, the Splash Screen will be presented by the Operating System as a high quality composition layer at launch time."),
ref projectConfig.systemSplashScreen, ref splashScreenTextureModified,
"https://developer.oculus.com/documentation/unity/unity-splash-screen/");
if (splashScreenTextureModified)
{
projectConfig.systemSplashScreen = OVRSystemSplashScreenEditor.ProcessTexture(projectConfig.systemSplashScreen);
hasModified = true;
}
// System Splash Screen: "Mono", "Stereo"
OVREditorUtil.SetupEnumField(
projectConfig,
new GUIContent("System Splash Screen Type", "\"Mono\": Texture will be rendered to both eyes.\n\"Stereo\": Texture will be split and rendered to each eye."),
ref projectConfig.systemSplashScreenType,
ref hasModified
);
if (projectConfig.systemSplashScreenType ==
OVRProjectConfig.SystemSplashScreenType.Stereo)
{
EditorGUILayout.HelpBox(
"For stereoscopic splash screen, the image needs to be double-wide with left-to-right texture pair.",
MessageType.Info);
}
// Allow optional 3-dof head-tracking
OVREditorUtil.SetupBoolField(projectConfig, new GUIContent("Allow Optional 3DoF Head Tracking",
"If checked, application can work in both 6DoF and 3DoF modes. It's highly recommended to keep it unchecked unless your project strongly needs the 3DoF head tracking."),
ref projectConfig.allowOptional3DofHeadTracking, ref hasModified);
// Passthrough support
OVREditorUtil.SetupEnumField(projectConfig, new GUIContent("Passthrough Support",
"Allows the application to use passthrough functionality. This option must be enabled at build time, otherwise initializing passthrough and creating passthrough layers in application scenes will fail."),
ref projectConfig._insightPassthroughSupport, ref hasModified);
// Processor favor (cpu/gpu level trading)
OVREditorUtil.SetupEnumField(projectConfig, new GUIContent("Processor Favor",
"If selected, will increase the frequency of one processor at the expense of decreasing the frequency of the other on supported devices"),
ref projectConfig._processorFavor, ref hasModified);
break;
case eProjectConfigTab.BuildSettings:
OVREditorUtil.SetupBoolField(projectConfig, new GUIContent("Skip Unneeded Shaders",
"If checked, prevent building shaders that are not used by default to reduce time spent when building."),
ref projectConfig.skipUnneededShaders, ref hasModified,
"https://developer.oculus.com/documentation/unity/unity-strip-shaders/");
break;
case eProjectConfigTab.Security:
OVREditorUtil.SetupBoolField(projectConfig, "Disable Backups", ref projectConfig.disableBackups,
ref hasModified,
"https://developer.android.com/guide/topics/data/autobackup#EnablingAutoBackup");
OVREditorUtil.SetupBoolField(projectConfig, "Enable NSC Configuration",
ref projectConfig.enableNSCConfig, ref hasModified,
"https://developer.android.com/training/articles/security-config");
EditorGUI.BeginDisabledGroup(!projectConfig.enableNSCConfig);
++EditorGUI.indentLevel;
OVREditorUtil.SetupInputField(projectConfig, "Custom Security XML Path",
ref projectConfig.securityXmlPath, ref hasModified);
--EditorGUI.indentLevel;
EditorGUI.EndDisabledGroup();
break;
case eProjectConfigTab.Experimental:
// Experimental Features Enabled
OVREditorUtil.SetupBoolField(projectConfig, new GUIContent("Experimental Features Enabled",
"If checked, this application can use experimental features. Note that such features are for developer use only. This option must be disabled when submitting to the Oculus Store."),
ref projectConfig.experimentalFeaturesEnabled, ref hasModified);
break;
}
EditorGUILayout.EndVertical();
// apply any pending changes to project config
if (hasModified)
{
OVRProjectConfig.CommitProjectConfig(projectConfig);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 950d95332920b814ea41df294856f96a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,99 @@
/*
* 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 System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
[InitializeOnLoad]
internal static class OVRProjectSetupMovementSDKConfigurationTasks
{
private const OVRProjectSetup.TaskGroup Group = OVRProjectSetup.TaskGroup.Features;
static OVRProjectSetupMovementSDKConfigurationTasks()
{
CheckBodyTrackingTasks();
CheckFaceTrackingTasks();
}
private static void CheckBodyTrackingTasks()
{
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Required,
group: Group,
isDone: buildTargetGroup => FindMisconfiguredOVRSkeletonInstances().Count == 0,
message: "When using OVRSkeleton components it's required to have OVRBody data provider next to it",
fix: buildTargetGroup =>
{
var skeletons = FindMisconfiguredOVRSkeletonInstances();
foreach (var skeleton in skeletons)
{
OVRSkeletonEditor.FixOVRBodyConfiguration(skeleton);
}
},
fixMessage: $"Create OVRBody components where they are required"
);
}
private static void CheckFaceTrackingTasks()
{
OVRProjectSetup.AddTask(
level: OVRProjectSetup.TaskLevel.Required,
group: Group,
isDone: buildTargetGroup => FindMisconfiguredOVRCustomFaceInstances().Count == 0,
message:
"When using OVRCustomFace components it's required to have OVRFaceExpressions data provider next to it",
fix: buildTargetGroup =>
{
var faces = FindMisconfiguredOVRCustomFaceInstances();
foreach (var face in faces)
{
OVRCustomFaceEditor.FixFaceExpressions(face);
}
},
fixMessage: $"Crete OVRFaceExpressions components where they are required"
);
}
private static List<OVRSkeleton> FindMisconfiguredOVRSkeletonInstances() => FindComponentsInScene<OVRSkeleton>()
.FindAll(s => !OVRSkeletonEditor.IsSkeletonProperlyConfigured(s))
.ToList();
private static List<OVRCustomFace> FindMisconfiguredOVRCustomFaceInstances() =>
FindComponentsInScene<OVRCustomFace>()
.FindAll(s => !OVRCustomFaceEditor.IsFaceExpressionsConfigured(s))
.ToList();
private static List<T> FindComponentsInScene<T>() where T : MonoBehaviour
{
List<T> results = new List<T>();
var scene = SceneManager.GetActiveScene();
var rootGameObjects = scene.GetRootGameObjects();
foreach (var root in rootGameObjects)
{
results.AddRange(root.GetComponentsInChildren<T>());
}
return results;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e810009fa55c47e4817f0f1ee23eb0c5
timeCreated: 1678653329

View File

@ -0,0 +1,65 @@
/*
* 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 UnityEditor;
[CustomEditor(typeof(OVRSceneManager))]
internal class OVRSceneManagerEditor : Editor
{
private SerializedProperty _planePrefab;
private SerializedProperty _volumePrefab;
private SerializedProperty _prefabOverrides;
private SerializedProperty _verboseLogging;
private SerializedProperty _maxSceneAnchorUpdatesPerFrame;
private SerializedProperty _initialAnchorParent;
private SerializedProperty _activeRoomsOnly;
private bool _showAdvanced;
private void OnEnable()
{
_planePrefab = serializedObject.FindProperty(nameof(OVRSceneManager.PlanePrefab));
_volumePrefab = serializedObject.FindProperty(nameof(OVRSceneManager.VolumePrefab));
_prefabOverrides = serializedObject.FindProperty(nameof(OVRSceneManager.PrefabOverrides));
_verboseLogging = serializedObject.FindProperty(nameof(OVRSceneManager.VerboseLogging));
_maxSceneAnchorUpdatesPerFrame =
serializedObject.FindProperty(nameof(OVRSceneManager.MaxSceneAnchorUpdatesPerFrame));
_activeRoomsOnly = serializedObject.FindProperty(nameof(OVRSceneManager.ActiveRoomsOnly));
_initialAnchorParent = serializedObject.FindProperty(nameof(OVRSceneManager._initialAnchorParent));
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(_planePrefab);
EditorGUILayout.PropertyField(_volumePrefab);
EditorGUILayout.PropertyField(_prefabOverrides);
EditorGUILayout.PropertyField(_activeRoomsOnly);
_showAdvanced = EditorGUILayout.Foldout(_showAdvanced, "Advanced");
if (_showAdvanced)
{
EditorGUILayout.PropertyField(_verboseLogging);
EditorGUILayout.PropertyField(_maxSceneAnchorUpdatesPerFrame);
EditorGUILayout.PropertyField(_initialAnchorParent);
}
serializedObject.ApplyModifiedProperties();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0ac8f8c52ff042318f6a46ff461838a4
timeCreated: 1663870763

View File

@ -0,0 +1,65 @@
/*
* 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 UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
[CustomEditor(typeof(OVRSkeleton))]
public class OVRSkeletonEditor : Editor
{
public override void OnInspectorGUI()
{
var skeleton = (OVRSkeleton)target;
if (skeleton.GetSkeletonType() == OVRSkeleton.SkeletonType.None)
{
EditorGUILayout.HelpBox("Please select a SkeletonType.", MessageType.Warning);
}
if (!IsSkeletonProperlyConfigured(skeleton))
{
if (OVREditorUIElements.RenderWarningWithButton(
"OVRBody is required.", "Add OVRBody component"))
{
FixOVRBodyConfiguration(skeleton);
}
}
DrawDefaultInspector();
}
internal static bool IsSkeletonProperlyConfigured(OVRSkeleton skeleton)
{
return !OVRSkeleton.IsBodySkeleton(skeleton.GetSkeletonType()) ||
skeleton.SearchSkeletonDataProvider() != null;
}
internal static void FixOVRBodyConfiguration(OVRSkeleton skeleton)
{
var gameObject = skeleton.gameObject;
Undo.IncrementCurrentGroup();
var body = gameObject.AddComponent<OVRBody>();
Undo.RegisterCreatedObjectUndo(body, "Add OVRBody component");
EditorUtility.SetDirty(body);
EditorSceneManager.MarkSceneDirty(gameObject.scene);
Undo.SetCurrentGroupName("Add OVRBody component");
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8695749c9d2c4b408eba12edb958ce84
timeCreated: 1678577145

View File

@ -0,0 +1,34 @@
/*
* 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 UnityEditor;
[CustomEditor(typeof(OVRUnityHumanoidSkeletonRetargeter))]
public class OVRUnityHumanoidSkeletonRetargeterEditor : OVRSkeletonEditor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
serializedObject.ApplyModifiedProperties();
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 91cc641bbb7c4eadbfa894cc59e2a3ff
timeCreated: 1678593640

View File

@ -0,0 +1,75 @@
{
"name": "Oculus.VR.Scripts.Editor",
"rootNamespace": "",
"references": [
"Oculus.VR",
"Oculus.VR.Editor",
"Unity.XR.Oculus",
"Unity.XR.OpenXR",
"Unity.XR.OpenXR.Editor",
"Unity.XR.Management",
"Unity.XR.Management.Editor"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.xr.management",
"expression": "",
"define": "USING_XR_MANAGEMENT"
},
{
"name": "com.unity.xr.oculus",
"expression": "",
"define": "USING_XR_SDK_OCULUS"
},
{
"name": "com.unity.xr.openxr",
"expression": "",
"define": "USING_XR_SDK_OPENXR"
},
{
"name": "com.unity.xr.oculus",
"expression": "1.7.0",
"define": "__OVERRIDED__PRIORITIZE_OCULUS_XR_SETTINGS"
},
{
"name": "com.unity.xr.oculus",
"expression": "[2.2-pre,3.0-pre)",
"define": "USING_QUEST_PRO_COMPATIBLE_OCULUS_XR_PLUGIN_VERSION"
},
{
"name": "com.unity.xr.oculus",
"expression": "3.2.1-pre",
"define": "USING_QUEST_PRO_COMPATIBLE_OCULUS_XR_PLUGIN_VERSION"
},
{
"name": "Unity",
"expression": "",
"define": "OVR_UNITY_ASSET_STORE"
},
{
"name": "com.unity.xr.oculus",
"expression": "3.2.1-pre",
"define": "OCULUS_XR_DEPTH_SUBMISSION"
},
{
"name": "com.unity.xr.oculus",
"expression": "3.3.0",
"define": "OCULUS_XR_3_3_0_OR_NEWER"
},
{
"name": "com.meta.xr.simulator",
"expression": "",
"define": "USING_META_XR_SIMULATOR"
}
],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7305c54a43f3814439df347c7519653e
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6e218d62590057045aa69bd80ea3dd65
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ca9218ce934bc274998d7b9899c9bb31
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,32 @@
/*
* 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 UnityEditor;
namespace Meta.XR.Samples.Editor
{
[CustomEditor(typeof(SampleMetadata))]
public class SampleMetadataInspector : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 49ebc9bf791c3b048b0403dd7d9d0eb9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: