예제 #1
0
        void ISerializationCallbackReceiver.OnBeforeSerialize()
        {
            for (int i = 0; i < pointerOptions.Length; i++)
            {
                ref PointerOption    pointerOption = ref pointerOptions[i];
                IMixedRealityPointer pointer       = pointerOption.PointerPrefab != null?pointerOption.PointerPrefab.GetComponent <IMixedRealityPointer>() : null;

                if (pointer.IsNull() ||
                    (pointer.PrioritizedLayerMasksOverride != null &&
                     pointer.PrioritizedLayerMasksOverride.Length > 0 &&
                     pointerOption.PrioritizedLayerMasks != null &&
                     pointerOption.PrioritizedLayerMasks.SequenceEqual(pointer.PrioritizedLayerMasksOverride)) ||
                    (pointingRaycastLayerMasks != null &&
                     pointingRaycastLayerMasks.Length > 0 &&
                     pointerOption.PrioritizedLayerMasks != null &&
                     pointerOption.PrioritizedLayerMasks.SequenceEqual(pointingRaycastLayerMasks)))
                {
                    continue;
                }

                // If the prefab has new LayerMasks, sync with prioritizedLayerMasks
                int pointerPrioritizedLayerMasksOverrideCount = pointer.PrioritizedLayerMasksOverride?.Length ?? 0;
                if (pointerPrioritizedLayerMasksOverrideCount != 0)
                {
                    if (pointerOption.PrioritizedLayerMasks?.Length != pointerPrioritizedLayerMasksOverrideCount)
                    {
                        pointerOption.PrioritizedLayerMasks = new LayerMask[pointerPrioritizedLayerMasksOverrideCount];
                    }
                    Array.Copy(pointer.PrioritizedLayerMasksOverride, pointerOption.PrioritizedLayerMasks, pointerPrioritizedLayerMasksOverrideCount);
                }
                // If the prefab doesn't have any LayerMasks, initialize with the global default
                else
                {
                    int pointingRaycastLayerMasksCount = pointingRaycastLayerMasks.Length;
                    if (pointerOption.PrioritizedLayerMasks?.Length != pointingRaycastLayerMasksCount)
                    {
                        pointerOption.PrioritizedLayerMasks = new LayerMask[pointingRaycastLayerMasksCount];
                    }
                    Array.Copy(pointingRaycastLayerMasks, pointerOption.PrioritizedLayerMasks, pointingRaycastLayerMasksCount);
                }
            }
        private void RenderPointerList(SerializedProperty list)
        {
            if (InspectorUIUtility.RenderIndentedButton(AddButtonContent, EditorStyles.miniButton))
            {
                pointerOptions.arraySize += 1;

                var newPointerOption = list.GetArrayElementAtIndex(list.arraySize - 1);
                var controllerType   = newPointerOption.FindPropertyRelative("controllerType");
                var handedness       = newPointerOption.FindPropertyRelative("handedness");
                var prefab           = newPointerOption.FindPropertyRelative("pointerPrefab");
                var raycastLayerMask = newPointerOption.FindPropertyRelative("prioritizedLayerMasks");

                // Reset new entry
                controllerType.intValue     = 0;
                handedness.intValue         = 0;
                prefab.objectReferenceValue = null;
                raycastLayerMask.arraySize  = 0;
            }

            if (list == null || list.arraySize == 0)
            {
                EditorGUILayout.HelpBox("Create a new Pointer Option entry.", MessageType.Warning);
                return;
            }

            bool anyPrefabChanged = false;

            for (int i = 0; i < list.arraySize; i++)
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    Color prevColor = GUI.color;

                    var pointerOption         = list.GetArrayElementAtIndex(i);
                    var controllerType        = pointerOption.FindPropertyRelative("controllerType");
                    var handedness            = pointerOption.FindPropertyRelative("handedness");
                    var prefab                = pointerOption.FindPropertyRelative("pointerPrefab");
                    var prioritizedLayerMasks = pointerOption.FindPropertyRelative("prioritizedLayerMasks");

                    GameObject           pointerPrefab = prefab.objectReferenceValue as GameObject;
                    IMixedRealityPointer pointer       = pointerPrefab != null?pointerPrefab.GetComponent <IMixedRealityPointer>() : null;

                    // Display an error if the prefab doesn't have a IMixedRealityPointer Component
                    if (pointer.IsNull())
                    {
                        InspectorUIUtility.DrawError($"The prefab associated with this pointer option needs an {typeof(IMixedRealityPointer).Name} component");
                        GUI.color = MixedRealityInspectorUtility.ErrorColor;
                    }

                    using (new EditorGUILayout.HorizontalScope())
                    {
                        EditorGUILayout.PropertyField(prefab);
                        if (GUILayout.Button(MinusButtonContent, EditorStyles.miniButtonRight, GUILayout.Width(24f)))
                        {
                            list.DeleteArrayElementAtIndex(i);
                            break;
                        }
                    }

                    EditorGUILayout.PropertyField(controllerType, ControllerTypeContent);
                    EditorGUILayout.PropertyField(handedness);

                    // Ultimately sync the pointer prefab's value with the pointer option's
                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.PropertyField(prioritizedLayerMasks, PointerRaycastLayerMaskContent, true);
                    if (EditorGUI.EndChangeCheck() && pointer.IsNotNull())
                    {
                        Undo.RecordObject(pointerPrefab, "Sync Pointer Prefab");

                        int prioritizedLayerMasksCount = prioritizedLayerMasks.arraySize;
                        if (pointer.PrioritizedLayerMasksOverride?.Length != prioritizedLayerMasksCount)
                        {
                            pointer.PrioritizedLayerMasksOverride = new LayerMask[prioritizedLayerMasksCount];
                        }

                        for (int j = 0; j < prioritizedLayerMasksCount; j++)
                        {
                            pointer.PrioritizedLayerMasksOverride[j] = prioritizedLayerMasks.GetArrayElementAtIndex(j).intValue;
                        }

                        PrefabUtility.RecordPrefabInstancePropertyModifications(pointerPrefab);
                        EditorUtility.SetDirty(pointerPrefab);
                        anyPrefabChanged = true;
                    }

                    GUI.color = prevColor;
                }
                EditorGUILayout.Space();
            }

            if (anyPrefabChanged)
            {
                AssetDatabase.SaveAssets();
            }
        }