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(); } }