To clarify: How do you add GUI components to the Scene View, not in the Game View, that are persistent?
I’ve searched the web hi and low for the answer to this and found that the question is often misunderstood or people simply say it can’t be done. The closest thing I found to a solution is a convoluted method of using a Script attached to an Object in the Scene that a CustomEditor points to and then it only displays when that object is selected.
Good news, it can be done. I’ll post the solution below so others can use this.
Here is the solution I came up with.
This method is very slick and piggy backs on the SceneView Object. This way you don’t have to have anything selected.
Cheers,
Doc
using UnityEditor;
using UnityEngine;
public class SceneGUI : EditorWindow
{
[MenuItem("Window/Scene GUI/Enable")]
public static void Enable()
{
SceneView.onSceneGUIDelegate += OnScene;
Debug.Log("Scene GUI : Enabled");
}
[MenuItem("Window/Scene GUI/Disable")]
public static void Disable()
{
SceneView.onSceneGUIDelegate -= OnScene;
Debug.Log("Scene GUI : Disabled");
}
private static void OnScene(SceneView sceneview)
{
Handles.BeginGUI();
if (GUILayout.Button("Press Me"))
Debug.Log("Got it to work.");
Handles.EndGUI();
}
}
Here is the solution. You can place this script anywhere it does not need to be in the editor folder. The reason this works is that the CustomEditor is looking for typeof ‘GameObject’. So it is now displayed when anything is selected in the scene, hierarchy or project.
Cheers, Doc
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(GameObject))]
[CanEditMultipleObjects]
public class funBoy : Editor
{
public void OnSceneGUI()
{
Handles.BeginGUI();
if (GUILayout.Button("Press Me"))
Debug.Log("Got it to work.");
Handles.EndGUI();
}
}
I don’t think you can actually do that with the current GUI system. As far as I know the scene view doesn’t render any GUI objects. It will probably work with the new GUI system that comes out later though.
What I did to do what you want, was to create a seperate window, storing all GUI objects in a list and display them in the seperate window (rendering them in the OnGUI method). And if I wanted to see what a camera was seeing from the scene view, I attached a Render Texture and drew the cameras view on that (requires pro though).
using UnityEditor;
using UnityEngine;
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
public class GuiEditor : Editor
{
private Camera m_renderFromThisCamera = Camera.main;
private RenderTexture m_RenderTexture = null;
/// <summary>
/// Initializes the GuiEditor window.
/// </summary>
public static void init()
{
//Show existing window instance. If one doesn't exist, make one.
EditorWindow editorWindow = EditorWindow.GetWindow(typeof(GuiEditor));
editorWindow.autoRepaintOnSceneChange = true;
editorWindow.Show();
}
void OnDisable()
{
if(m_RenderTexture != null)
m_RenderTexture.Release();
}
/// <summary>
/// Is called only once.
/// </summary>
public void Awake ()
{
m_RenderTexture = new RenderTexture((int)position.width, (int)position.height, (int)RenderTextureFormat.ARGB32);
}
/// <summary>
/// Updates the camera image if active.
/// This function is not used when in playmode.
/// </summary>
public void Update()
{
if (m_renderFromThisCamera != null)
{
m_renderFromThisCamera.targetTexture = m_RenderTexture;
m_renderFromThisCamera.Render();
m_renderFromThisCamera.targetTexture = null;
}
if(m_RenderTexture == null)
CreateRenderTexture();
else if (m_RenderTexture.width != position.width || m_RenderTexture.height != position.height)
CreateRenderTexture();
}
private void CreateRenderTexture()
{
if(m_RenderTexture != null)
m_RenderTexture.Release();
m_RenderTexture = new RenderTexture((int)position.width, (int)position.height, (int)RenderTextureFormat.ARGB32);
}
/// <summary>
/// Renders all GuiObjects.
/// </summary>
void OnGUI()
{
// Render all GUI objects.
// Render the Camera view here.
if(m_RenderTexture == null)
CreateRenderTexture();
else
GUI.DrawTexture(customWindowRect, m_RenderTexture, GuiEditorSettings.Instance.CameraScaleMode);
}
}
Its a VERY simple pseudo code of how I did it. It probably won’t work or even compile, so don’t just copy paste it, but it maybe gives you an idea how it can work.
I hope this gives you some help. Good luck!