/// <summary> /// Adds default inspector property fields under a container VisualElement /// </summary> /// <param name="container">The parent VisualElement</param> /// <param name="serializedObject">The SerializedObject to inspect</param> /// <param name="editor">The editor currently used</param> public static void FillDefaultInspector(VisualElement container, SerializedObject serializedObject, Editor editor) { if (serializedObject == null) { return; } bool isPartOfPrefabInstance = editor != null && GenericInspector.IsAnyMonoBehaviourTargetPartOfPrefabInstance(editor); SerializedProperty property = serializedObject.GetIterator(); if (property.NextVisible(true)) // Expand first child. { do { var field = new PropertyField(property); field.name = "PropertyField:" + property.propertyPath; if (property.propertyPath == "m_Script") { if ((serializedObject.targetObject != null) || isPartOfPrefabInstance) { field.SetEnabled(false); } } container.Add(field); }while (property.NextVisible(false)); } if (serializedObject.targetObject == null) { AddMissingScriptLabel(container, serializedObject, isPartOfPrefabInstance); } }
internal InspectorElement(Editor editor, Mode mode) { AddToClassList(ussClassName); this.mode = mode; this.editor = editor; if (editor.targets.Length == 0) { return; } var targetObject = editor.targets[0]; if (targetObject == null) { if (!GenericInspector.ObjectIsMonoBehaviourOrScriptableObject(targetObject)) { return; } } this.Bind(editor.serializedObject); }
public ReorderableListDrawer(GenericInspector inspector, Object target, SerializedObject serializedObject) : base(inspector, target, serializedObject) { var iterator = SerializedObject.GetIterator(); while (iterator.NextVisible(true)) { if (!iterator.isArray || iterator.propertyType == SerializedPropertyType.String) { continue; } var attribute = iterator.GetAttribute <ReorderableAttribute>(); if (attribute == null || _reorderableLists.ContainsKey(iterator.propertyPath)) { continue; } var icon = !string.IsNullOrEmpty(attribute.ElementIconPath) ? AssetDatabase.GetCachedIcon(attribute.ElementIconPath) : null; var displayType = attribute.SingleLine ? ExtendedReorderableList.ElementDisplayType.SingleLine : ExtendedReorderableList.ElementDisplayType.Auto; var reorderableList = new ExtendedReorderableList(iterator.Copy(), attribute.Add, attribute.Remove, attribute.Draggable, displayType, attribute.ElementNameProperty, attribute.ElementNameOverride, icon, attribute.SceneReferences) { Paginate = attribute.Paginate, PageSize = attribute.PageSize, sortable = attribute.Sortable }; _reorderableLists.Add(iterator.propertyPath, reorderableList); } }
// PRAGMA MARK - Public Interface public static void RegisterPopup(GenericInspector inspector) { if (GameConstants.Instance == null) { Debug.LogWarning("No GameConstants - not registering popup (possible sandbox)!"); return; } var setGameModePopupItems = new List <PopupItemConfig>() { new PopupItemConfig("NO OVERRIDE", () => SetGameModeOverride(null)) }; foreach (var gameMode in GameConstants.Instance.GameModes) { var currentGameMode = gameMode; setGameModePopupItems.Add(new PopupItemConfig(gameMode.DisplayTitle, () => SetGameModeOverride(currentGameMode))); } Func <int> startIndexDelegate = () => { int startIndex = 0; if (overrideGameMode_ != null) { startIndex = Array.IndexOf(GameConstants.Instance.GameModes, overrideGameMode_) + 1; } return(startIndex); }; inspector.RegisterPopup("Override Game Mode", startIndexDelegate, itemConfigs: setGameModePopupItems.ToArray()); }
public ScriptableObjectDrawer(GenericInspector inspector, Object target, SerializedObject serializedObject) : base(inspector, target, serializedObject) { var propertyIterator = serializedObject.GetIterator(); while (propertyIterator.NextVisible(true)) { if (propertyIterator.propertyType != SerializedPropertyType.ObjectReference) { continue; } var propertyType = propertyIterator.GetFieldType(); if (propertyType == null || !propertyType.IsSubclassOf(typeof(ScriptableObject))) { continue; } UnityEditor.Editor scriptableEditor = null; if (propertyIterator.objectReferenceValue != null) { UnityEditor.Editor.CreateCachedEditorWithContext(propertyIterator.objectReferenceValue, serializedObject.targetObject, typeof(GenericInspector), ref scriptableEditor); } _scriptableObjects.Add(propertyIterator.propertyPath, scriptableEditor as GenericInspector); } }
// PRAGMA MARK - Public Interface public void Init(string inspectorName, GenericInspector inspector) { displayTitle_ = inspectorName; activeViewPrefab_ = Resources.Load <GameObject>("GenericInspectorViewPrefab"); priority_ = inspector.Priority; inspector_ = inspector; }
// PRAGMA MARK - Public Interface public void Init(GenericInspector inspector) { CleanupInspector(); inspector_ = inspector; inspector_.OnInspectorDirty += RefreshInspectorFields; RefreshInspectorFields(); }
private void CleanupInspector() { if (inspector_ != null) { inspector_.OnInspectorDirty -= RefreshInspectorFields; inspector_ = null; } }
bool AddMissingScriptLabel(SerializedObject serializedObject) { SerializedProperty scriptProperty = serializedObject.FindProperty("m_Script"); if (scriptProperty != null) { hierarchy.Add(new IMGUIContainer(() => GenericInspector.ShowScriptNotLoadedWarning(scriptProperty))); return(true); } return(false); }
static bool AddMissingScriptLabel(VisualElement container, SerializedObject serializedObject, bool isPartOfPrefabInstance) { SerializedProperty scriptProperty = serializedObject.FindProperty("m_Script"); if (scriptProperty != null) { container.Add(new IMGUIContainer(() => GenericInspector.ShowScriptNotLoadedWarning(scriptProperty, isPartOfPrefabInstance))); return(true); } return(false); }
private VisualElement CreateInspectorElementFromEditor(Editor editor, bool reuseIMGUIContainer = false) { var serializedObject = editor.serializedObject; var target = editor.targets[0]; if (target == null) { if (!GenericInspector.ObjectIsMonoBehaviourOrScriptableObject(target)) { return(null); } } VisualElement inspectorElement = null; if ((mode & Mode.UIECustom) > 0) { inspectorElement = editor.CreateInspectorGUI(); if (inspectorElement != null) { AddToClassList(uIECustomVariantUssClassName); if (editor.UseDefaultMargins()) { AddToClassList(uIEInspectorVariantUssClassName); } inspectorElement.AddToClassList(customInspectorUssClassName); } } if (inspectorElement == null) { inspectorElement = CreateIMGUIInspectorFromEditor(serializedObject, editor, reuseIMGUIContainer); } if (inspectorElement == null && (mode & Mode.UIEDefault) > 0) { inspectorElement = CreateDefaultInspector(serializedObject); } if (inspectorElement == null) { AddToClassList(noInspectorFoundVariantUssClassName); AddToClassList(uIEInspectorVariantUssClassName); inspectorElement = new Label("No inspector found given the current Inspector.Mode."); } return(inspectorElement); }
internal InspectorElement(SerializedObject obj, Mode mode) { AddToClassList(ussClassName); this.mode = mode; if (obj.targetObject == null) { if (!GenericInspector.ObjectIsMonoBehaviourOrScriptableObject(obj.targetObject)) { return; } } this.Bind(obj); }
internal InspectorElement(Object obj, Mode mode) { m_IgnoreOnInspectorGUIErrors = false; AddToClassList(ussClassName); this.mode = mode; if (obj == null) { if (!GenericInspector.ObjectIsMonoBehaviourOrScriptableObject(obj)) { return; } } this.Bind(new SerializedObject(obj)); }
private static void Initialize() { GenericInspector inspector = GenericInspectorRegistry.Get("PHASERBEAK"); inspector.RegisterHeader("Properties"); inspector.RegisterColorField("Background Color", () => GameConstants.Instance.BackgroundColor, (c) => GameConstants.Instance.BackgroundColor = c); inspector.RegisterToggle("Show FPS", () => FPSView.Enabled, (b) => FPSView.Enabled = b); inspector.RegisterToggle("Zoom In On Survivors", () => InGameConstants.ZoomInOnSurvivors, (b) => InGameConstants.ZoomInOnSurvivors = b); inspector.RegisterButton("Reset All The Things", () => { PHASERBEAKDebug.ResetAllThings(); }); inspector.RegisterHeader("Recording Mode Properties"); inspector.RegisterToggle("Recording Mode", () => RecordingMode.Active, (b) => RecordingMode.Active = b); inspector.RegisterToggle("Register Human Players (off for AI only)", () => InGameConstants.RegisterHumanPlayers, (b) => InGameConstants.RegisterHumanPlayers = b); inspector.RegisterToggle("Show Scoring View", () => InGameConstants.ShowScoringView, (b) => InGameConstants.ShowScoringView = b); inspector.RegisterToggle("Show Hints View", () => InGameConstants.ShowHintsView, (b) => InGameConstants.ShowHintsView = b); inspector.RegisterToggle("Show Next Unlock", () => InGameConstants.ShowNextGameModeUnlockView, (b) => InGameConstants.ShowNextGameModeUnlockView = b); inspector.RegisterHeader("Battle"); GameModeOverride.RegisterPopup(inspector); inspector.RegisterButton("Clear Focus (0)", () => BattleCamera.Instance.ClearTransformsOfInterest()); inspector.RegisterButton("Focus On Player 1 (1)", () => BattleCameraDebug.FocusOnPlayer(1)); inspector.RegisterButton("Focus On Player 2 (2)", () => BattleCameraDebug.FocusOnPlayer(2)); inspector.RegisterButton("Focus On Player 3 (3)", () => BattleCameraDebug.FocusOnPlayer(3)); inspector.RegisterButton("Focus On Player 4 (4)", () => BattleCameraDebug.FocusOnPlayer(4)); // TODO (darren): add space inspector.RegisterButton("Fill Pending Scores", () => { Player player = RegisteredPlayers.AllPlayers.FirstOrDefault(); if (player == null) { return; } for (int i = 0; i < GameConstants.Instance.ScoreToWin; i++) { PlayerScores.IncrementPendingScoreFor(player); } }); }
private VisualElement CreateIMGUIInspectorFromEditor(SerializedObject serializedObject, Editor editor, bool reuseIMGUIContainer) { if ((mode & (Mode.IMGUICustom | Mode.IMGUIDefault)) == 0) { return(null); } if ((mode & Mode.IMGUICustom) > 0 && (mode & Mode.IMGUIDefault) == 0 && editor is GenericInspector) { return(null); } if ((mode & Mode.IMGUICustom) == 0 && (mode & Mode.IMGUIDefault) > 0 && !(editor is GenericInspector)) { editor = ScriptableObject.CreateInstance <GenericInspector>(); editor.hideFlags = HideFlags.HideAndDontSave; editor.InternalSetTargets(new[] { serializedObject.targetObject }); } if (editor is GenericInspector) { AddToClassList(iMGUIDefaultVariantUssClassName); if ((mode & Mode.DebugMod) > 0) { AddToClassList(debugVariantUssClassName); editor.inspectorMode = InspectorMode.Debug; } else if ((mode & Mode.DebugInternalMod) > 0) { AddToClassList(debugInternalVariantUssClassName); editor.inspectorMode = InspectorMode.DebugInternal; } } else { AddToClassList(iMGUICustomVariantUssClassName); } IMGUIContainer inspector; // Reusing the existing IMGUIContainer allows us to re-use the existing gui state, when we are drawing the same inspector this will let us keep the same control ids if (reuseIMGUIContainer && m_IMGUIContainer != null) { inspector = m_IMGUIContainer; } else { inspector = new IMGUIContainer(); } m_IgnoreOnInspectorGUIErrors = false; inspector.onGUIHandler = () => { // It's possible to run 2-3 frames after the tracker of this inspector window has // been recreated, and with it the Editor and its SerializedObject. One example of // when this happens is when the Preview window is detached from a *second* instance // of an InspectorWindow and re-attached. // // This is only a problem for the *second* (or third, forth, etc) instance of // the InspectorWindow because only the first instance can use the // ActiveEditorTracker.sharedTracker in InspectorWindow.CreateTracker(). The // other instances have to create a new tracker...each time. // // Not an ideal solution, but basically we temporarily hold the printing to console // for errors for which GUIUtility.ShouldRethrowException(e) returns false. // The errors that may occur during this brief "bad state" are SerializedProperty // errors. If the custom Editor created and remembered references to some // SerializedProperties during its OnEnable(), those references will be invalid // when the tracker is refreshed, until this GUIHandler is reassigned. This fix // just ignores those errors. // // We don't simply early return here because that can break some tests that // rely heavily on yields and timing of UI redraws. Yes.. // // case 1119612 if (editor.m_SerializedObject == null) { editor.Repaint(); m_IgnoreOnInspectorGUIErrors = true; } if ((editor.target == null && !GenericInspector.ObjectIsMonoBehaviourOrScriptableObject(editor.target)) || !editor.serializedObject.isValid) { return; } EditorGUIUtility.ResetGUIState(); using (new EditorGUI.DisabledScope(!editor.IsEnabled())) { var genericEditor = editor as GenericInspector; if (genericEditor != null) { switch (mode) { case Mode.Normal: genericEditor.inspectorMode = InspectorMode.Normal; break; case Mode.Default: genericEditor.inspectorMode = InspectorMode.Debug; break; case Mode.Custom: genericEditor.inspectorMode = InspectorMode.DebugInternal; break; case Mode.IMGUI: break; } } //set the current PropertyHandlerCache to the current editor ScriptAttributeUtility.propertyHandlerCache = editor.propertyHandlerCache; var originalHierarchyMode = EditorGUIUtility.hierarchyMode; EditorGUIUtility.hierarchyMode = true; var originalWideMode = SetWideModeForWidth(inspector); GUIStyle editorWrapper = (editor.UseDefaultMargins() ? EditorStyles.inspectorDefaultMargins : GUIStyle.none); try { GUI.changed = false; using (new InspectorWindowUtils.LayoutGroupChecker()) { EditorGUILayout.BeginVertical(editorWrapper); { // we have no guarantees regarding what happens in the try/catch block below, // so we need to save state here and restore it afterwards, // the natural thing to do would be using SavedGUIState, // but it implicitly resets keyboards bindings and it breaks functionality. // We have identified issues with layout so we just save that for the time being. var layoutCache = new GUILayoutUtility.LayoutCache(GUILayoutUtility.current); try { var rebuildOptimizedGUIBlocks = GetRebuildOptimizedGUIBlocks(editor.target); rebuildOptimizedGUIBlocks |= editor.isInspectorDirty; float height; if (editor.GetOptimizedGUIBlock(rebuildOptimizedGUIBlocks, visible, out height)) { var contentRect = GUILayoutUtility.GetRect(0, visible ? height : 0); // Layout events are ignored in the optimized code path // The exception is when we are drawing a GenericInspector, they always use the optimized path and must therefore run at least one layout calculation in it if (Event.current.type == EventType.Layout && !(editor is GenericInspector)) { return; } InspectorWindowUtils.DrawAddedComponentBackground(contentRect, editor.targets); // Draw content if (visible) { GUI.changed = false; editor.OnOptimizedInspectorGUI(contentRect); } } else { InspectorWindowUtils.DrawAddedComponentBackground(contentRect, editor.targets); editor.OnInspectorGUI(); } } catch (Exception e) { if (GUIUtility.ShouldRethrowException(e)) { throw; } if (!m_IgnoreOnInspectorGUIErrors) { Debug.LogException(e); } } finally { GUILayoutUtility.current = layoutCache; } } EditorGUILayout.EndVertical(); } } finally { if (GUI.changed) { // This forces a relayout of all imguicontainers in this inspector window. // fixes part of case 1148706 var element = inspector.GetFirstAncestorOfType <EditorElement>(); if (element != null) { EditorElement.InvalidateIMGUILayouts(element.parent); } } EditorGUIUtility.wideMode = originalWideMode; EditorGUIUtility.hierarchyMode = originalHierarchyMode; } } }; inspector.style.overflow = Overflow.Visible; m_IMGUIContainer = inspector; if (!(editor is GenericInspector)) { inspector.AddToClassList(customInspectorUssClassName); } inspector.AddToClassList(iMGUIContainerUssClassName); AddToClassList(iMGUIInspectorVariantUssClassName); return(inspector); }
protected GenericInspectorDrawer(GenericInspector inspector, Object target, SerializedObject serializedObject) { Inspector = inspector; Target = target; SerializedObject = serializedObject; }