/// <summary> /// Registers a scene GUI callback for the target object of the supplied editor context. /// </summary> /// <param name="ctx">Editor for the object whose scene GUI should be drawn.</param> /// <param name="action">GUI calback for the object.</param> public static void RegisterObjectGUICallback(ISceneGUIContext ctx, System.Action action) { UnityFeatureDefineSymbols.AddSymbolForAllBuildTargets("IS_CANDLELIGHT_SCENE_GUI_AVAILABLE"); Object target = ctx.SceneGUIContext.target; // don't register same target more than once if (s_RegisteredContexts.Count(r => r.Target == target) > 0) { return; } // don't register targets of the same type if they're on another object System.Type targetType = target.GetType(); for (int i = 0; i < s_RegisteredContexts.Count; ++i) { if (targetType == s_RegisteredContexts[i].Target.GetType()) { if (target is ScriptableObject) { return; } else if ( (target as Component).gameObject != (s_RegisteredContexts[i].Target as Component).gameObject ) { return; } } } s_RegisteredContexts.Add( new RegisteredContext { Callback = action, Context = ctx.SceneGUIContext, Target = target } ); }
/// <summary> /// Registers a scene GUI callback for the target object of the supplied editor context. /// </summary> /// <param name="ctx">Editor for the object whose scene GUI should be drawn.</param> /// <param name="action">GUI calback for the object.</param> public static void RegisterObjectGUICallback(ISceneGUIContext ctx, System.Action action) { Object target = ctx.SceneGUIContext.target; // don't register same target more than once if (s_RegisteredContexts.Count(r => r.Target == target) > 0) { return; } // don't register targets of the same type if they're on another object System.Type targetType = target.GetType(); for (int i = 0; i < s_RegisteredContexts.Count; ++i) { if (targetType == s_RegisteredContexts[i].Target.GetType()) { if (target is ScriptableObject) { return; } else if ( (target as Component).gameObject != (s_RegisteredContexts[i].Target as Component).gameObject ) { return; } } } s_RegisteredContexts.Add( new RegisteredContext { Callback = action, Context = ctx.SceneGUIContext, Target = target } ); }
/// <summary> /// Executes any registered scene GUI callbacks. /// </summary> /// <param name="ctx">Object from whose context this method is called.</param> /// <param name="width">Desired width of scene GUI area. 281 is minimum width for sliders to appear.</param> /// <param name="anchor">Corner of the viewport to which the controls should be anchored.</param> public static void Display(ISceneGUIContext ctx, float width = 281f, GUIAnchor anchor = GUIAnchor.TopLeft) { // early out if scene gui is disabled or there are no valid registered contexts if ( !IsEnabled || s_RegisteredContexts.Count == 0 || s_RegisteredContexts.Count(k => k.Target != null && k.Callback != null) == 0 ) { return; } // ensure only the first context invoking this method during a layout phase will display the GUI if (Event.current.type == EventType.Layout) { s_DisplayInvoker = ctx.SceneGUIContext.target; } if (s_DisplayInvoker != ctx.SceneGUIContext.target) { return; } if (Event.current.type != EventType.Layout) { s_DisplayInvoker = null; } // begin gui matrix Handles.BeginGUI(); // begin the area width = Mathf.Min(width, Screen.width - 2f * s_ViewportPadding); float height = Screen.height - 2f * s_ViewportPadding - SceneGUI.SceneViewTabHeight; GUISkin oldSkin = GUI.skin; GUI.skin = Skin; GUILayout.BeginArea( new Rect( (anchor == GUIAnchor.LowerLeft || anchor == GUIAnchor.TopLeft) ? s_ViewportPadding : Screen.width - s_ViewportPadding - width, (anchor == GUIAnchor.TopLeft || anchor == GUIAnchor.TopRight) ? s_ViewportPadding : Screen.height - s_ViewportPadding - height, width, height ) ); { Color oldColor = GUI.color; GUI.color = new Color(oldColor.r, oldColor.g, oldColor.b, oldColor.a * 0.65f); EditorGUILayout.BeginVertical(EditorStylesX.SceneBox); { GUI.color = oldColor; s_ScrollPosition = EditorGUILayout.BeginScrollView(s_ScrollPosition, GUILayout.ExpandHeight(false)); { for (int i = 0; i < s_RegisteredContexts.Count; ++i) { if (s_RegisteredContexts[i].Target == null || s_RegisteredContexts[i].Callback == null) { continue; } FontStyle fontStyle = GUI.skin.label.fontStyle; GUI.skin.label.fontStyle = FontStyle.Bold; EditorGUILayout.LabelField( s_RegisteredContexts[i].Target.GetType().Name.ToWords(), GUI.skin.label ); GUI.skin.label.fontStyle = fontStyle; EditorGUIX.DisplayHorizontalLine(); ++EditorGUI.indentLevel; s_RegisteredContexts[i].Callback.Invoke(); --EditorGUI.indentLevel; } } EditorGUILayout.EndScrollView(); } EditorGUILayout.EndVertical(); } GUILayout.EndArea(); GUI.skin = oldSkin; Handles.EndGUI(); }
/// <summary> /// Deregisters the scene GUI callback for the supplied object. /// </summary> /// <param name="ctx">Editor for the object whose scene GUI should no longer be drawn.</param> public static void DeregisterObjectGUICallback(ISceneGUIContext ctx) { s_RegisteredContexts.RemoveAll(k => ctx.SceneGUIContext.targets.Contains(k.Target)); }