- Home /
OnSceneGUI called without any object selected
OnSceneGUI is only called if an object by the given type is selected in the editor. The given type is denoted by the C# Attribute CutomEditor. The below example is almost there as it is called when any type of object is selected.
I want to get OnSceneGUI() called at all times even when no objects are selected. Anyone got an idea on how to make that work?
using UnityEditor; using UnityEngine; using System.Collections;
[CustomEditor(typeof(GameObject))] public class SceneGUITest : Editor { void OnSceneGUI() { Debug.Log("OnSceneGUI with any object selected"); } }
Answer by NZRoadKill · Jun 11, 2010 at 06:40 PM
You should use a static function and the attribute for drawing gizmos.
[CustomEditor(typeof(GameObject))]
public class SceneGUITest : Editor
{
[DrawGizmo(GizmoType.NotSelected)]
static void RenderCustomGizmo(Transform objectTransform, GizmoType gizmoType)
{
//Draw here
}
}
This will work for all Transform components (which each GameObject has).
Thanks, this lets me get an update even when not having an object selected. I wanted to use this for custom sceneview navigation which it almost works for aswell. Only missing thing is all events. The Event.current in the context above does have mouse position, but event types of mouse down etc are not received - only the repaint event.
Answer by Skjalg · Feb 08, 2012 at 09:11 AM
This works in Unity 3.5
using UnityEditor;
using UnityEngine;
public class TestWindow : EditorWindow
{
[MenuItem("Window/" + "Test")]
public static void Init()
{
// Get existing open window or if none, make a new one:
TestWindow window = GetWindow<TestWindow>();
window.title = "Test";
SceneView.onSceneGUIDelegate += OnScene;
}
private static void OnScene(SceneView sceneview)
{
Debug.Log("This event opens up so many possibilities.");
}
public void OnDestroy()
{
SceneView.onSceneGUIDelegate -= OnScene;
}
}
There is another way that makes it also start up by default when unity starts up and you dont need the menu item to kick start it. Just use the attribute [InitializeOnLoad] ins$$anonymous$$d.
http://docs.unity3d.com/Documentation/$$anonymous$$anual/RunningEditorCodeOnLaunch.html
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! the above link is perfect
!!! exactly what I needed
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Answer by Elecman · Aug 05, 2013 at 03:25 PM
Skjalg is correct. However, when Play mode is entered and then returned to Editor mode, OnScene() will not be called anymore. Furthermore, any other initialization code that is placed in Init() will be lost as well when you go from Play mode back to Editor mode. To solve this problem, use this:
using UnityEditor;
using UnityEngine;
public class TestWindow : EditorWindow
{
[MenuItem("Window/" + "Test")]
public static void Init()
{
// Get existing open window or if none, make a new one:
TestWindow window = GetWindow<TestWindow>();
window.title = "Test";
// SceneView.onSceneGUIDelegate += OnScene;
}
private static void OnScene(SceneView sceneview)
{
Debug.Log("This event opens up so many possibilities.");
}
public void OnDestroy()
{
SceneView.onSceneGUIDelegate -= OnScene;
}
public void Update()
{
if(SceneView.onSceneGUIDelegate == null){
SceneView.onSceneGUIDelegate += OnScene;
//Any other initialization code you would
//normally place in Init() goes here instead.
}
}
}
you can use [InitializeOnLoad] attribute and than static constructor. It'll be called on editor startup and on leaving play mode as well.
Answer by Esteem · Nov 17, 2017 at 06:21 PM
if you want a custom OnSceneGUI so you can have your own stuff in it while you have any Game Object selected, you can do:
(- you want the reverse engineered Transform version so it doesn't change your InspectorGUI settings.)
[CustomEditor(typeof(Transform))]
and then download reverse engineered default TransformInspector from wiki.
then yo can do something like this:
[CanEditMultipleObjects, CustomEditor(typeof(Transform))]
public class UniversalOnSceneGUI : Editor {
#region Original Transform GUI
private const float FIELD_WIDTH = 212.0f;
private const bool WIDE_MODE = true;
private const float POSITION_MAX = 100000.0f;
private static GUIContent positionGUIContent = new GUIContent(LocalString("Position")
, LocalString("The local position of this Game Object relative to the parent."));
private static GUIContent rotationGUIContent = new GUIContent(LocalString("Rotation")
, LocalString("The local rotation of this Game Object relative to the parent."));
private static GUIContent scaleGUIContent = new GUIContent(LocalString("Scale")
, LocalString("The local scaling of this Game Object relative to the parent."));
private static string positionWarningText = LocalString("Due to floating-point precision limitations, it is recommended to bring the world coordinates of the GameObject within a smaller range.");
private SerializedProperty positionProperty;
private SerializedProperty rotationProperty;
private SerializedProperty scaleProperty;
private static string LocalString(string text) {
return LocalizationDatabase.GetLocalizedString(text);
}
public void OnEnable() {
this.positionProperty = this.serializedObject.FindProperty("m_LocalPosition");
this.rotationProperty = this.serializedObject.FindProperty("m_LocalRotation");
this.scaleProperty = this.serializedObject.FindProperty("m_LocalScale");
}
public override void OnInspectorGUI() {
EditorGUIUtility.wideMode = ZoneController_ZoneVisibility.WIDE_MODE;
EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - ZoneController_ZoneVisibility.FIELD_WIDTH; // align field to right of inspector
this.serializedObject.Update();
EditorGUILayout.PropertyField(this.positionProperty, positionGUIContent);
this.RotationPropertyField(this.rotationProperty, rotationGUIContent);
EditorGUILayout.PropertyField(this.scaleProperty, scaleGUIContent);
if (!ValidatePosition(((Transform) this.target).position)) {
EditorGUILayout.HelpBox(positionWarningText, MessageType.Warning);
}
this.serializedObject.ApplyModifiedProperties();
}
private bool ValidatePosition(Vector3 position) {
if (Mathf.Abs(position.x) > ZoneController_ZoneVisibility.POSITION_MAX) return false;
if (Mathf.Abs(position.y) > ZoneController_ZoneVisibility.POSITION_MAX) return false;
if (Mathf.Abs(position.z) > ZoneController_ZoneVisibility.POSITION_MAX) return false;
return true;
}
private void RotationPropertyField(SerializedProperty rotationProperty, GUIContent content) {
Transform transform = (Transform) this.targets[0];
Quaternion localRotation = transform.localRotation;
foreach (UnityEngine.Object t in (UnityEngine.Object[]) this.targets) {
if (!SameRotation(localRotation, ((Transform) t).localRotation)) {
EditorGUI.showMixedValue = true;
break;
}
}
EditorGUI.BeginChangeCheck();
Vector3 eulerAngles = EditorGUILayout.Vector3Field(content, localRotation.eulerAngles);
if (EditorGUI.EndChangeCheck()) {
Undo.RecordObjects(this.targets, "Rotation Changed");
foreach (UnityEngine.Object obj in this.targets) {
Transform t = (Transform) obj;
t.localEulerAngles = eulerAngles;
}
rotationProperty.serializedObject.SetIsDifferentCacheDirty();
}
EditorGUI.showMixedValue = false;
}
private bool SameRotation(Quaternion rot1, Quaternion rot2) {
if (rot1.x != rot2.x) return false;
if (rot1.y != rot2.y) return false;
if (rot1.z != rot2.z) return false;
if (rot1.w != rot2.w) return false;
return true;
}
#endregion
private void OnSceneGUI() {
}
}
sorry for the necro post @kjems , It's for future reference.