A quick recipe for instant
SceneView goodness

viewing image effects in the scene view


by Nicholas Francis
Jun 4, 2013

I just coded this up and want to share it: There’s a hook that allows you to see image effects in the scene view. Paste the code below into a .cs file, and derive any image effects from SceneViewFilter.

(Explanation below the code)

using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class SceneViewFilter : MonoBehaviour {
#if UNITY_EDITOR
	bool hasChanged = false;

	public virtual void OnValidate ()
	{ 
		hasChanged = true; 
	}
	
	static SceneViewFilter  ()
	{
		SceneView.onSceneGUIDelegate += CheckMe;
	}

	static void CheckMe (SceneView sv)
	{
		if (Event.current.type != EventType.Layout)
			return;
		if (!Camera.main)
			return;
		// Get a list of everything on the main camera that should be synced.
		SceneViewFilter[] cameraFilters = Camera.main.GetComponents<SceneViewFilter> ();
		SceneViewFilter[] sceneFilters = sv.camera.GetComponents<SceneViewFilter> ();

		// Let's see if the lists are different lengths or something like that. 
		// If so, we simply destroy all scene filters and recreate from maincame
		if (cameraFilters.Length != sceneFilters.Length)
		{
			Recreate (sv);
			return;
		}
		for (int i = 0; i < cameraFilters.Length; i++)
		{
			if (cameraFilters[i].GetType() != sceneFilters[i].GetType())
			{
				Recreate (sv);
				return;
			}
		}

		// Ok, WHICH filters, or their order hasn't changed.
		// Let's copy all settings for any filter that has changed.
		for (int i = 0; i < cameraFilters.Length; i++)
		if (cameraFilters[i].hasChanged || sceneFilters[i].enabled != cameraFilters[i].enabled)
		{
			EditorUtility.CopySerialized (cameraFilters[i], sceneFilters[i]);
			cameraFilters[i].hasChanged = false;
		}
	}

	static void Recreate (SceneView sv)
	{
		SceneViewFilter filter;
		while (filter = sv.camera.GetComponent<SceneViewFilter> ())
			DestroyImmediate (filter);

		foreach (SceneViewFilter f in Camera.main.GetComponents<SceneViewFilter> ())
		{
			SceneViewFilter newFilter = sv.camera.gameObject.AddComponent (f.GetType()) as SceneViewFilter;
			EditorUtility.CopySerialized (f, newFilter);
		}
	}
#endif
}

(This is V.2 - thanks to Benoit for pointing out some stupid stuff I'd done)

The hook that allows you to do this is Unity's SceneView.onSceneGUIDelegate. Any functions added to this delegate will get called when the sceneview processes the event. It's parameter is a SceneView. Through this we can get to the sceneview's Camera. Then it's a matter of copy all image effects to this camera. We do this with AddComponent and then use Unity's SerializedObject to copy over each field.

Note: This hasn't been tested thoroughly, and probably doesn't handle arrays and nested objects, etc. Works fine for us, however 🙂

Have fun. And remember: If it breaks, you get to keep both pieces.


by Simon Barsky
June 9, 2013

Really cool! Much nicer than having to switch to the gameview to see how your scene looks. Just a heads up you should be getting components like this: GetComponents (), otherwise the script won’t build.


by framebunker
June 10, 2013

Hi Simon – it looks like WordPress was eating the <SceneViewFilter> in both our post and your comment. Thanks for helping to catch that.


by Simon Barsky
June 10, 2013

Ah, I didn’t even notice that in my comment, annoying 🙂


by Seith
September 2, 2013

Sounds amazing! So I saved this code as “SceneViewFilter.cs” but now how should I exactly proceed to actually see the game camera filters applied to the scene camera? Please feel free to be as detailed as possible in your reply… 🙂


by framebunker
September 4, 2013

Seith, Image effects in Unity usually consist of both a script and a shader. I would recommend looking at one of the effects that ships with Unity to see how this works. To modify an existing image effect (or write a new one) to make use of this, the actual script for the filter needs to derive from SceneViewFilter instead of MonoBehaviour.


by Martijn
October 30, 2013

Any1 who has a fix when you have both the game and the scene view visible ? error’s destroying rendertexture that’s active etc? Other than that this is very helpfull!!


by Martijn
October 31, 2013

I added the below the SceneViewFilter[] lines :

if (!EditorApplication.isPlaying)
{
foreach (var sceneViewFilter in sceneFilters)
{
sceneViewFilter.enabled = false;
}
}

Seems to work!

Add Your Comment