private void RenderEventSettings()
        {
            if (InspectorUIUtility.DrawSectionFoldoutWithKey("Events", ShowEventsPrefKey, MixedRealityStylesUtility.BoldTitleFoldoutStyle))
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("OnClick"), OnClickEventLabel);

                    if (InspectorUIUtility.DrawSectionFoldoutWithKey("Receivers", ShowEventReceiversPrefKey, MixedRealityStylesUtility.TitleFoldoutStyle, false))
                    {
                        SerializedProperty events = serializedObject.FindProperty("Events");
                        for (int i = 0; i < events.arraySize; i++)
                        {
                            SerializedProperty eventItem = events.GetArrayElementAtIndex(i);
                            if (InteractableEventInspector.RenderEvent(eventItem))
                            {
                                events.DeleteArrayElementAtIndex(i);
                                // If removed, skip rendering rest of list till next redraw
                                break;
                            }

                            EditorGUILayout.Space();
                        }

                        if (GUILayout.Button(AddEventReceiverLabel))
                        {
                            AddEvent(events.arraySize);
                        }
                    }
                }
            }
        }
        private void RenderEventSettings()
        {
            if (InspectorUIUtility.DrawSectionFoldoutWithKey("Events", ShowEventsPrefKey, MixedRealityStylesUtility.TitleFoldoutStyle))
            {
                EditorGUILayout.Space();

                SerializedProperty onClick = serializedObject.FindProperty("OnClick");
                EditorGUILayout.PropertyField(onClick, new GUIContent("OnClick"));

                SerializedProperty events = serializedObject.FindProperty("Events");
                for (int i = 0; i < events.arraySize; i++)
                {
                    SerializedProperty eventItem = events.GetArrayElementAtIndex(i);
                    if (InteractableEventInspector.RenderEvent(eventItem))
                    {
                        events.DeleteArrayElementAtIndex(i);
                        // If removed, skip rendering rest of list till next redraw
                        break;
                    }

                    EditorGUILayout.Space();
                }

                if (GUILayout.Button(new GUIContent("Add Event")))
                {
                    AddEvent(events.arraySize);
                }
            }
        }
Example #3
0
        private void DrawAdvancedSettingsSection()
        {
            if (InspectorUIUtility.DrawSectionFoldoutWithKey("Advanced settings", ShowAdvancedPrefKey, MixedRealityStylesUtility.BoldFoldoutStyle))
            {
                using (new EditorGUI.IndentLevelScope(2))
                {
                    EditorGUILayout.PropertyField(maskEditMode);
                    EditorGUILayout.PropertyField(colliderEditMode);
                    EditorGUILayout.Space();

                    EditorGUILayout.PropertyField(canScroll);
                    EditorGUILayout.Space();

                    EditorGUILayout.PropertyField(useCameraPreRender);
                    EditorGUILayout.Space();

                    EditorGUILayout.PropertyField(animationCurve);
                    EditorGUILayout.PropertyField(animationLength);
                    EditorGUILayout.Space();

                    EditorGUILayout.PropertyField(handDeltaScrollThreshold);
                    EditorGUILayout.PropertyField(frontTouchDistance);
                    EditorGUILayout.Space();

                    DrawTouchReleaseThresholdsSection();
                    EditorGUILayout.Space();

                    DrawVelocitySection();
                    EditorGUILayout.Space();

                    DrawDebugSection();
                    EditorGUILayout.Space();
                }
            }
        }
 private void DrawPeformanceSection()
 {
     if (InspectorUIUtility.DrawSectionFoldoutWithKey("Performance Options", ShowPerformanceOptionsPrefKey, MixedRealityStylesUtility.BoldFoldoutStyle))
     {
         EditorGUILayout.PropertyField(disableClippedGameObjects);
         EditorGUILayout.PropertyField(disableClippedRenderers);
     }
 }
Example #5
0
 private void DrawEventsSection()
 {
     if (InspectorUIUtility.DrawSectionFoldoutWithKey("Events", ShowEventsPrefKey, MixedRealityStylesUtility.BoldFoldoutStyle))
     {
         using (new EditorGUI.IndentLevelScope())
         {
             EditorGUILayout.PropertyField(clickEvent);
             EditorGUILayout.PropertyField(touchStartedEvent);
             EditorGUILayout.PropertyField(touchEndedEvent);
             EditorGUILayout.PropertyField(momentumStartedEvent);
             EditorGUILayout.PropertyField(momentumEndedEvent);
             EditorGUILayout.Space();
         }
     }
 }
Example #6
0
        // Render the Advanced Properties under an indented foldout titled Advanced Properties
        private void RenderAdvancedProperties()
        {
            // Render Advanced Settings
            if (InspectorUIUtility.DrawSectionFoldoutWithKey("Advanced Properties", AdvancedPropertiesFoldoutKey, MixedRealityStylesUtility.TitleFoldoutStyle, false))
            {
                using (new EditorGUI.IndentLevelScope())
                {
                    EditorGUILayout.Space();

                    EditorGUILayout.PropertyField(updateLinkedTransformProperty);
                    EditorGUILayout.PropertyField(moveLerpTimeProperty);
                    EditorGUILayout.PropertyField(rotateLerpTimeProperty);
                    EditorGUILayout.PropertyField(scaleLerpTimeProperty);
                    EditorGUILayout.PropertyField(maintainScaleProperty);
                    EditorGUILayout.PropertyField(smoothingProperty);
                    EditorGUILayout.PropertyField(lifetimeProperty);
                    EditorGUILayout.PropertyField(magneticSurfaces, true);
                }
            }
        }
        private void RenderProfileSettings()
        {
            if (profileList.arraySize < 1)
            {
                AddProfile(0);
            }

            if (InspectorUIUtility.DrawSectionFoldoutWithKey("Profiles", ShowProfilesPrefKey, MixedRealityStylesUtility.BoldTitleFoldoutStyle))
            {
                // Render all profile items. Profiles are per GameObject/ThemeContainer
                for (int i = 0; i < profileList.arraySize; i++)
                {
                    using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                    {
                        SerializedProperty profileItem    = profileList.GetArrayElementAtIndex(i);
                        SerializedProperty hostGameObject = profileItem.FindPropertyRelative("Target");

                        using (new EditorGUILayout.HorizontalScope())
                        {
                            EditorGUILayout.PropertyField(hostGameObject, new GUIContent("Target", "Target gameObject for this theme properties to manipulate"));
                            if (InspectorUIUtility.SmallButton(new GUIContent(InspectorUIUtility.Minus, "Remove Profile"), i, RemoveProfile))
                            {
                                // Profile removed via RemoveProfile callback
                                continue;
                            }
                        }

                        if (hostGameObject.objectReferenceValue == null)
                        {
                            InspectorUIUtility.DrawError("Assign a GameObject to apply visual effects");
                            if (GUILayout.Button("Assign Self"))
                            {
                                hostGameObject.objectReferenceValue = instance.gameObject;
                            }
                        }

                        SerializedProperty themes = profileItem.FindPropertyRelative("Themes");
                        ValidateThemesForDimensions(dimensions, themes);

                        // Render all themes for current target
                        for (int t = 0; t < themes.arraySize; t++)
                        {
                            SerializedProperty themeItem  = themes.GetArrayElementAtIndex(t);
                            string             themeLabel = BuildThemeTitle(dimensions.intValue, t);

                            if (themeItem.objectReferenceValue != null)
                            {
                                bool showThemeSettings = false;
                                using (new EditorGUILayout.HorizontalScope())
                                {
                                    string prefKey = themeItem.objectReferenceValue.name + "Profiles" + i + "_Theme" + t + "_Edit";
                                    showThemeSettings = InspectorUIUtility.DrawSectionFoldoutWithKey(themeLabel, prefKey, null, false);
                                    EditorGUILayout.PropertyField(themeItem, new GUIContent(string.Empty, "Theme properties for interaction feedback"));
                                }

                                if (themeItem.objectReferenceValue != null)
                                {
                                    // TODO: Odd bug where themeStates below is null when it shouldn't be. Use instance object as workaround atm
                                    //SerializedProperty themeStates = themeItem.FindPropertyRelative("States");
                                    var themeInstance = themeItem.objectReferenceValue as Theme;
                                    if (statesProperty.objectReferenceValue != themeInstance.States)
                                    {
                                        InspectorUIUtility.DrawWarning($"{themeInstance.name}'s States property does not match Interactable's States property");
                                    }

                                    if (showThemeSettings)
                                    {
                                        using (new EditorGUI.IndentLevelScope())
                                        {
                                            UnityEditor.Editor themeEditor = UnityEditor.Editor.CreateEditor(themeItem.objectReferenceValue);
                                            themeEditor.OnInspectorGUI();
                                        }
                                    }
                                }
                            }
                            else
                            {
                                EditorGUILayout.PropertyField(themeItem, new GUIContent(themeLabel, "Theme properties for interaction feedback"));

                                InspectorUIUtility.DrawError("Assign a Theme to add visual effects");
                                if (GUILayout.Button(CreateThemeLabel))
                                {
                                    themeItem.objectReferenceValue = CreateThemeAsset(hostGameObject.objectReferenceValue.name);
                                    return;
                                }
                            }

                            EditorGUILayout.Space();
                        }
                    }
                }

                if (GUILayout.Button(new GUIContent("Add Profile")))
                {
                    AddProfile(profileList.arraySize);
                }
            }
        }
Example #8
0
        public void RenderThemeDefinitions()
        {
            GUIStyle box = InspectorUIUtility.HelpBox(EditorGUI.indentLevel * ThemeBoxMargin);

            // Loop through all InteractableThemePropertySettings of Theme
            for (int index = 0; index < themeDefinitions.arraySize; index++)
            {
                using (new EditorGUILayout.VerticalScope(box))
                {
                    SerializedProperty themeDefinition = themeDefinitions.GetArrayElementAtIndex(index);
                    SerializedProperty className       = themeDefinition.FindPropertyRelative("ClassName");

                    string themeDefinition_prefKey = theme.name + "_Definitions" + index;
                    bool   show = false;
                    using (new EditorGUILayout.HorizontalScope())
                    {
                        show = InspectorUIUtility.DrawSectionFoldoutWithKey(className.stringValue, themeDefinition_prefKey, MixedRealityStylesUtility.BoldFoldoutStyle);

                        if (RenderDeleteButton(index))
                        {
                            return;
                        }
                    }

                    if (show)
                    {
                        EditorGUILayout.Space();

                        using (new EditorGUI.IndentLevelScope())
                        {
                            EditorGUILayout.LabelField("General Properties", EditorStyles.boldLabel);

                            using (new EditorGUILayout.HorizontalScope())
                            {
                                var themeTypes      = TypeCacheUtility.GetSubClasses <InteractableThemeBase>();
                                var themeClassNames = themeTypes.Select(t => t?.Name).ToArray();
                                int id    = Array.IndexOf(themeClassNames, className.stringValue);
                                int newId = EditorGUILayout.Popup("Theme Runtime", id, themeClassNames);

                                // Some old Themes did not properly save a value here
                                SerializedProperty assemblyQualifiedName = themeDefinition.FindPropertyRelative("AssemblyQualifiedName");
                                if (string.IsNullOrEmpty(assemblyQualifiedName.stringValue) && newId != -1)
                                {
                                    assemblyQualifiedName.stringValue = themeTypes[newId].AssemblyQualifiedName;
                                }

                                // If user changed the theme type for current themeDefinition
                                if (id != newId && newId != -1)
                                {
                                    Type oldType = id != -1 ? themeTypes[id] : null;
                                    Type newType = themeTypes[newId];
                                    ChangeThemeDefinitionType(index, oldType, newType);
                                    return;
                                }
                            }

                            var themeType = theme.Definitions[index].ThemeType;
                            if (themeType != null)
                            {
                                SerializedProperty customProperties = themeDefinition.FindPropertyRelative("customProperties");
                                RenderCustomProperties(customProperties);

                                var themeExample = (InteractableThemeBase)Activator.CreateInstance(themeType);

                                if (themeExample.IsEasingSupported)
                                {
                                    RenderEasingProperties(themeDefinition);
                                }

                                if (themeExample.AreShadersSupported)
                                {
                                    RenderShaderProperties(themeDefinition);
                                }

                                EditorGUILayout.Space();

                                RenderThemeStates(themeDefinition);
                            }
                            else
                            {
                                InspectorUIUtility.DrawError("Theme Runtime Type is not valid");
                            }
                        }
                    }
                }
            }

            // If no theme properties assigned, add a default one
            if (themeDefinitions.arraySize < 1 || GUILayout.Button(AddThemePropertyLabel))
            {
                AddThemeDefinition();
            }
        }
Example #9
0
        private void DrawDebugSection()
        {
            if (InspectorUIUtility.DrawSectionFoldoutWithKey("Debug Options", ShowDebugOptionsPrefKey, MixedRealityStylesUtility.BoldFoldoutStyle))
            {
                using (new EditorGUI.IndentLevelScope())
                {
                    using (var check = new EditorGUI.ChangeCheckScope())
                    {
                        EditorGUILayout.PropertyField(maskEnabled);
                        if (check.changed)
                        {
                            scrollView.MaskEnabled = maskEnabled.boolValue;
                        }
                    }

                    using (new EditorGUI.DisabledGroupScope(EditorApplication.isPlaying))
                    {
                        visibleDebugPlanes = EditorGUILayout.Toggle("Show Threshold Planes", visibleDebugPlanes);
                        EditorGUILayout.Space();
                    }
                }

                using (new EditorGUI.IndentLevelScope())
                {
                    using (new EditorGUI.DisabledGroupScope(!EditorApplication.isPlaying))
                    {
                        if (ShowDebugPagination = EditorGUILayout.Foldout(ShowDebugPagination, new GUIContent("Debug Pagination", "Pagination is only available during playmode."), MixedRealityStylesUtility.BoldFoldoutStyle))
                        {
                            using (new EditorGUI.IndentLevelScope())
                            {
                                animateTransition = EditorGUILayout.Toggle(new GUIContent("Animate", "Toggling will use animation to move scroller to new position."), animateTransition);

                                using (new EditorGUILayout.HorizontalScope())
                                {
                                    debugPaginationMode  = (PaginationMode)EditorGUILayout.EnumPopup(new GUIContent("Pagination Mode"), debugPaginationMode, GUILayout.Width(400.0f));
                                    paginationMoveNumber = EditorGUILayout.IntField(paginationMoveNumber);

                                    if (GUILayout.Button("Move"))
                                    {
                                        switch (debugPaginationMode)
                                        {
                                        case PaginationMode.ByTier:
                                        default:
                                            scrollView.MoveByTiers(paginationMoveNumber, animateTransition);
                                            break;

                                        case PaginationMode.ByPage:
                                            scrollView.MoveByPages(paginationMoveNumber, animateTransition);
                                            break;

                                        case PaginationMode.ToCellIndex:
                                            scrollView.MoveToIndex(paginationMoveNumber, animateTransition);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #10
0
        private void RenderSection(ToolboxCategory bucket)
        {
            using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
            {
                string key = $"MixedRealityToolboxWindow_{bucket.CategoryName}";
                if (InspectorUIUtility.DrawSectionFoldoutWithKey(bucket.CategoryName, key, MixedRealityStylesUtility.BoldTitleFoldoutStyle))
                {
                    InspectorUIUtility.DrawDivider();
                    EditorGUILayout.Space();

                    bool isCategoryNameSearchMatch = IsSearchMatch(bucket.CategoryName, searchString);

                    List <ToolboxItem> validItems = new List <ToolboxItem>();
                    foreach (var item in bucket.Items)
                    {
                        if (item != null && item.Prefab != null &&
                            (isCategoryNameSearchMatch || IsSearchMatch(item, searchString)))
                        {
                            validItems.Add(item);
                        }
                    }

                    bool requiresCanvas = bucket.CategoryName.Contains(RequiresCanvas);
                    if (requiresCanvas)
                    {
                        using (new EditorGUILayout.HorizontalScope())
                        {
                            dropdownIndex = EditorGUILayout.Popup(CanvasDropdownContent, dropdownIndex, dropdownValues);

                            if (GUILayout.Button(RefreshButtonContent, EditorStyles.miniButton, GUILayout.Width(ReloadButtonWidth)))
                            {
                                FindAllMRTKCanvases();
                            }
                        }

                        if (canvasUtilities.Length == 0)
                        {
                            GUIStyle CanvasWarningStyle = new GUIStyle(EditorStyles.textField)
                            {
                                wordWrap = true
                            };
                            GUILayout.TextField("These MRTK components require an MRTK Canvas Utility on one of the Unity UI Canvases in the scene.\nNone were detected. Press refresh if you recently added any.\nTo create a MRTK Canvas: GameObject > UI > Canvas, and under the Canvas component in the inspector, click 'Convert to MRTK Canvas' button.", CanvasWarningStyle);
                        }
                    }

                    EditorGUILayout.Space();

                    // Render grid of toolbox items
                    int itemsPerRow = Mathf.Max((int)(position.width / ToolboxItemWidth), 1);

                    for (int row = 0; row <= validItems.Count / itemsPerRow; row++)
                    {
                        using (new EditorGUILayout.HorizontalScope())
                        {
                            int startIndex = row * itemsPerRow;
                            for (int col = 0; col < itemsPerRow && startIndex + col < validItems.Count; col++)
                            {
                                var item = validItems[startIndex + col];
                                RenderToolboxItem(item, requiresCanvas);
                            }
                        }
                    }
                }
            }
        }
        private void RenderStates()
        {
            // Draw a States title for the State list section
            InspectorUIUtility.DrawTitle(statesLabel);

            for (int i = 0; i < states.arraySize; i++)
            {
                SerializedProperty state      = states.GetArrayElementAtIndex(i);
                SerializedProperty stateName  = state.FindPropertyRelative("stateName");
                SerializedProperty stateValue = state.FindPropertyRelative("stateValue");
                SerializedProperty stateEventConfiguration = state.FindPropertyRelative("eventConfiguration");

                using (new EditorGUILayout.HorizontalScope())
                {
                    string stateFoldoutID = stateName.stringValue + "_" + target.name;

                    Color previousGUIColor = GUI.color;

                    if (inPlayMode)
                    {
                        // If the state is active, then highlight the state container with a new color
                        if (stateValue.intValue == 1)
                        {
                            GUI.color = Color.cyan;
                        }
                    }

                    using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                    {
                        EditorGUILayout.Space();

                        // Draw a foldout for the state configuration
                        if (InspectorUIUtility.DrawSectionFoldoutWithKey(stateName.stringValue, stateFoldoutID, MixedRealityStylesUtility.TitleFoldoutStyle, true))
                        {
                            EditorGUILayout.Space();

                            using (new EditorGUILayout.VerticalScope())
                            {
                                using (new EditorGUI.IndentLevelScope())
                                {
                                    // Show the event configuration for the state
                                    RenderStateEventConfiguration(stateName, stateEventConfiguration);

                                    CheckSpecialCaseStates(stateName.stringValue, stateEventConfiguration);

                                    // When a new core state is added via inspector, the name is initialized to "New Core State" and then changed
                                    // to the name the user selects from the list of CoreInteractionStates
                                    if (stateName.stringValue == newCoreStateName)
                                    {
                                        SetCoreStateType(state, stateName);
                                    }

                                    // When a new state is added via inspector, the name is initialized to "Create Custom State" and then changed
                                    // to the name the user enters a name in the text field and then selects the "Set State Name" button
                                    if (stateName.stringValue == createCustomStateName)
                                    {
                                        SetUserDefinedState(stateName);
                                    }
                                }
                            }
                        }

                        EditorGUILayout.Space();
                    }

                    // Do not draw a remove button during play mode
                    if (!inPlayMode)
                    {
                        if (CanDrawRemoveButton(stateName.stringValue))
                        {
                            // Draw a button with a '-' for state removal
                            if (InspectorUIUtility.SmallButton(RemoveStateButtonLabel))
                            {
                                states.DeleteArrayElementAtIndex(i);
                                break;
                            }
                        }
                    }

                    // Draw the state value in the inspector next to the state during play mode for debugging
                    if (inPlayMode)
                    {
                        using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox, GUILayout.Width(stateValueDisplayWidth)))
                        {
                            EditorGUILayout.Space();
                            EditorGUILayout.LabelField(stateValue.intValue.ToString(), GUILayout.Width(stateValueDisplayContainerWidth));
                            EditorGUILayout.Space();
                        }
                    }

                    GUI.color = previousGUIColor;
                }
            }
        }
        private void RenderStateContainers()
        {
            InspectorUIUtility.DrawTitle("State Animations");

            for (int i = 0; i < stateContainers.arraySize; i++)
            {
                SerializedProperty stateContainer              = stateContainers.GetArrayElementAtIndex(i);
                SerializedProperty stateContainerName          = stateContainer.FindPropertyRelative("stateName");
                SerializedProperty animationTargetsList        = stateContainer.FindPropertyRelative("animationTargets");
                SerializedProperty stateContainerAnimationClip = stateContainer.FindPropertyRelative("animationClip");
                SerializedProperty animationTransitionDuration = stateContainer.FindPropertyRelative("animationTransitionDuration");

                Color previousGUIColor = GUI.color;

                using (new EditorGUILayout.HorizontalScope())
                {
                    string stateFoldoutID = stateContainerName.stringValue + "StateContainer" + "_" + target.name;

                    if (inPlayMode)
                    {
                        BaseInteractiveElement baseInteractiveElement = interactiveElement.objectReferenceValue as BaseInteractiveElement;

                        if (baseInteractiveElement.isActiveAndEnabled)
                        {
                            if (baseInteractiveElement.IsStateActive(stateContainerName.stringValue))
                            {
                                GUI.color = Color.cyan;
                            }
                        }
                    }

                    using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                    {
                        EditorGUILayout.Space();

                        if (InspectorUIUtility.DrawSectionFoldoutWithKey(stateContainerName.stringValue, stateFoldoutID, MixedRealityStylesUtility.TitleFoldoutStyle, false))
                        {
                            using (new EditorGUI.IndentLevelScope())
                            {
                                using (var check = new EditorGUI.ChangeCheckScope())
                                {
                                    EditorGUILayout.PropertyField(stateContainerAnimationClip);
                                    EditorGUILayout.PropertyField(animationTransitionDuration);

                                    if (check.changed)
                                    {
                                        instance.SetAnimationTransitionDuration(stateContainerName.stringValue, animationTransitionDuration.floatValue);
                                        instance.SetAnimationClip(stateContainerName.stringValue, stateContainerAnimationClip.objectReferenceValue as AnimationClip);
                                    }
                                }

                                RenderAnimationTargetList(animationTargetsList, stateContainerName);
                            }
                        }

                        EditorGUILayout.Space();
                    }

                    GUI.color = previousGUIColor;

                    if (!inPlayMode)
                    {
                        if (InspectorUIUtility.SmallButton(RemoveButtonLabel))
                        {
                            instance.RemoveAnimatorState(instance.RootStateMachine, stateContainerName.stringValue);
                            stateContainers.DeleteArrayElementAtIndex(i);
                            break;
                        }
                    }
                }
            }
        }
        private void RenderAnimationTargetList(SerializedProperty animationTargetList, SerializedProperty stateContainerName)
        {
            using (new EditorGUI.IndentLevelScope())
            {
                for (int j = 0; j < animationTargetList.arraySize; j++)
                {
                    SerializedProperty animationTarget        = animationTargetList.GetArrayElementAtIndex(j);
                    SerializedProperty targetObj              = animationTarget.FindPropertyRelative("target");
                    SerializedProperty animatablePropertyList = animationTarget.FindPropertyRelative("stateAnimatableProperties");

                    EditorGUILayout.Space();

                    using (new EditorGUILayout.VerticalScope(GUI.skin.box))
                    {
                        EditorGUILayout.Space();

                        using (new EditorGUILayout.HorizontalScope())
                        {
                            EditorGUILayout.PropertyField(targetObj);

                            if (InspectorUIUtility.SmallButton(RemoveButtonLabel))
                            {
                                // Clear keyframes of a deleted target
                                for (int k = 0; k < animatablePropertyList.arraySize; k++)
                                {
                                    SerializedProperty animatableProperty     = animatablePropertyList.GetArrayElementAtIndex(k);
                                    SerializedProperty animatablePropertyName = animatableProperty.FindPropertyRelative("animatablePropertyName");

                                    if (animatableProperty != null)
                                    {
                                        RemoveKeyFrames(stateContainerName.stringValue, animatablePropertyName.stringValue, j);
                                    }
                                }

                                animationTargetList.DeleteArrayElementAtIndex(j);
                                break;
                            }
                        }

                        using (new EditorGUILayout.VerticalScope())
                        {
                            if (targetObj.objectReferenceValue != null)
                            {
                                InspectorUIUtility.DrawDivider();

                                GameObject targetGameObject = targetObj.objectReferenceValue as GameObject;

                                // Ensure the target game object has a State Visualizer attached or is a child of an
                                // object with State Visualizer attached
                                if (targetGameObject.transform.FindAncestorComponent <StateVisualizer>(true))
                                {
                                    string animatablePropertiesFoldoutID = stateContainerName.stringValue + "AnimatableProperties" + "_" + targetGameObject.name + target.name;

                                    if (InspectorUIUtility.DrawSectionFoldoutWithKey(targetGameObject.name + " Animatable Properties", animatablePropertiesFoldoutID, MixedRealityStylesUtility.BoldFoldoutStyle, false))
                                    {
                                        using (new EditorGUI.IndentLevelScope())
                                        {
                                            RenderAnimatablePropertyList(animatablePropertyList, stateContainerName, j);
                                        }
                                    }
                                }
                                else
                                {
                                    targetObj.objectReferenceValue = null;
                                    Debug.LogError("The target object must be itself or a child object");
                                }
                            }

                            EditorGUILayout.Space();
                        }
                    }
                }

                EditorGUILayout.Space();

                RenderAddTargetButton(animationTargetList);
            }
        }