Auto Save in Unity

What can you do when a team member suffers a recurring Unity editor crash, losing all level design work ? My answer was to write a small and helpful editor extension – auto save! (and then blog about it).

TL;DR

This post describes a simple solution for implementing auto save in Unity that saves the currently open scene every 5 minutes (configurable).

The code is available for easy consumption in a few ways:

  • GitHub – Also updated in case i get any feedback / future posts
  • Gist

The code is imported and works out of the box, import / paste it into your Unity project and you’re good to go.

Problem

It started a few days ago: a member of our team started experiencing occasional Unity editor crashes a few times daily. We do not know the exact reason for crashes, but we suspect it may be related to memory issues combined with voodoo magic. No matter what the root cause was, these crashes caused real damage in lost data (game levels) which we could not afford having.

In order to keep lost work to a minimum, I suggested to implement a basic auto save solution, so at least we can go back to a backup in case the editor crashes.

Solution – AutoSave

The solution uses pretty simple editor scripting to the rescue. The process can be described in 3 main steps:

  1. Hook a delegate to EditorApplication.update.
  2. In this method, check if the scene should be saved (if the configured time has elapsed. The default is 5 minutes).
  3. In case we need to save, generate a new unique name for the scene and save it to disk.

In order to have the code up and running when you launch the editor, the class is marked with the [InitializeOnLoad] attribute and initialization is done in its static constructor.

Show Me the Code

This is the complete code, you can paste it into your project:

using System;
using System.IO;
using System.Globalization;
using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
public class AutoSaveScene
{
	private const string SAVE_FOLDER = "Editor/AutoSaves";

	private static System.DateTime lastSaveTime = System.DateTime.Now;
	private static System.TimeSpan updateInterval;

	static AutoSaveScene()
	{
		EnsureAutoSavePathExists();

		// Register for autosaves.
		// Change this number to modify the autosave interval.
		RegisterOnEditorUpdate(5);
	}

	public static void RegisterOnEditorUpdate(int interval)
	{
		Debug.Log ("Enabling AutoSave");

		updateInterval = new TimeSpan(0, interval, 0);
		EditorApplication.update += OnUpdate;
	}

	/// <summary>
	/// Makes sure the target save path exists.
	/// </summary>
	private static void EnsureAutoSavePathExists()
	{
		var path = Path.Combine(Application.dataPath, SAVE_FOLDER);

		if (!Directory.Exists(path))
		{
			Directory.CreateDirectory(path);
		}
	}

	/// <summary>
	/// Saves a copy of the currently open scene.
	/// </summary>
	private static void SaveScene()
	{
		Debug.Log("Auto saving scene: " + EditorApplication.currentScene);

		EnsureAutoSavePathExists();

		// Get the new saved scene name.
		var newName = GetNewSceneName(EditorApplication.currentScene);
		var folder = Path.Combine("Assets", SAVE_FOLDER);

		EditorApplication.SaveScene(Path.Combine(folder, newName), true);
		EditorApplication.SaveAssets();
	}

	/// <summary>
	/// Helper method that creates a new scene name.
	/// </summary>
	private static string GetNewSceneName(string originalSceneName)
	{
		var scene = Path.GetFileNameWithoutExtension(originalSceneName);

		return string.Format(
			"{0}_{1}.unity",
			scene,
			System.DateTime.Now.ToString(
			"yyyy-MM-dd_HH-mm-ss",
			CultureInfo.InvariantCulture));
	}

	private static void OnUpdate()
	{
		if ((System.DateTime.Now - lastSaveTime) >= updateInterval)
		{
			SaveScene();
			lastSaveTime = System.DateTime.Now;
		}
	}
}

Built In AutoSave

It should be noted that apparently Unity does autosave the current scene every time you enter play mode. If this is enough for you (for example – the game crashed during play mode), a copy of the scene can be found in YourProject/Temp/__EditModeScene.

Conclusion

The code in this post helps ensuring no scene data is lost when experiencing editor crashes. I deliberately kept it short & simple so it can be easily “digested”. Autosaving can be further visited by adding any of the following:

  • Configuration – Allow controlling autosave (turning on/off, setting time interval) from an editor window or menu item.
  • Capping number of autosaves – Nobody really needs 50 copies of the open scene; instead, only 1 or 2 copies can be saved and recycled on every new save.
  • New save triggers – The current code saves every X minutes. The code can be adapted to save under different scenarios.

Resources

Posted in GameDev, Programming, Unity, Unity Editor, Unity Editor Extensions, Unity Snippets, Unity Tricks | Tagged , , , | 1 Comment

Please Encapsulate Your Fields

The inspector is Unity’s one stop shop for fiddling with game objects’ values and is one of the used windows of the Unity editor. The default inspector picks up the properties to display using a set of simple rules (read here).

While the inspector provides an easy way for programmers and designers to easily edit gameplay elements, it does so many times at the cost of code encapsulation. This post shortly discusses this issue and suggests a simple, built-in solution that Unity provides, to better encapsulate your code.

OMG It’s all public !

Consider the following piece of script code:

using UnityEngine;
using System.Collections;

public class LaserObstacle : MonoBehaviour
{
    public int DamageAmount;
    public float DamageDuration;
    public int NumberOfBeams;

    public GameObject LaserPrefab;

    // Implementation details ...
}

This results in an inspector that lets you edit all the public fields you exposed in script:

Inspector

 

 

 

 

In smaller projects this may not be such a big issue, but the problem is that this breaks the object’s encapsulation. Once the code base grows and you have thousands of scripts, having all their internal “guts” exposed to all other code can cause serious issues (what implications will changing *this* piece of code have ?)

I don’t blame us all for writing code that’s all public – it’s what we’re all used to seeing for years in many code samples and most of the online resources I’ve seen. I believe the reason for this is that samples usually focus on succinctly getting something done and not dealing with the correct structuring of code.

[SerializeField] to the rescue

So we want to still allow editing scripts through the editor while having the code encapsulated, exposing only what is needed (the code’s public API).

In order to achieve this we can follow this pattern:

  • Set fields on MonoBehaviours to private.
  • Decorate fields that should be exposed in the inspector with the [SerializeField] attribute.
  • (Optional) expose public properties on the script to allow accessing its internal state fields.

The code shown above could be rewritten like so:

using UnityEngine;
using System.Collections;

public class LaserObstacle : MonoBehaviour
{
    [SerializeField]
    private int damageAmount;

    public int DamageAmount
    {
    	get { return damageAmount; }
    }

    [SerializeField]
    private float DamageDuration;
    [SerializeField]
    private int NumberOfBeams;

    [SerializeField]
    private GameObject LaserPrefab;

    // Implementation details ...
}

What did we gain here ?

  1. The inspector for the script looks the same (we can edit it in the same way).
  2. The class does not expose all fields as public.
  3. We can expose the data we want using properties (can also make a property read only by controlling its get/set accessors).

I can not think of  any downside to such code, aside from the extra typing involved. I believe I will adopt this style from now on when creating new scripts.

EDIT:

Lucas from Unity kindly replied to me (on Twitter), saying that aside from typing more, there’s no other downsides:

Screen Shot 2014-12-22 at 00.03.13

Conclusion

I’ve shown a simple, built-in way, that does not require creating new inspectors or custom editor code, that allows us to have the best of both worlds – working with inspectors and keeping our code encapsulated. I would love to hear any comments or other suggestions whether there are any disadvantages to this code that I clearly missed. Feel free to comment and share you thoughts !

Resources

Posted in GameDev, Programming, Unity, Unity Editor, Unity Tricks | 4 Comments

Finding Missing References in Unity

Screen Shot 2014-12-06 at 15.54.40This post shows a short and simple solution for finding missing references in Unity.

EDIT: The original code was improved upon feedback (thanks: Amir Barak, Thomas Viktil, Alex Kogan, Amir Ebrahimi).

The code was updated to include:

  • Error context (can click to get to the game object)
  • Find missing components (not only missing references inside scripts)
  • Find inactive scene objects as well
  • Formatting – keep it all under 80 chars

Missing References

A missing reference is different from having no reference at all (in which case the inspector shows “None”). These can occur for a variety of reasons, for example: moving asset files outside of the Unity editor, a result of a mixup in .meta files that results in having a link to an invalid object id (or due to a bug – see this bug).

The major issue is that missing references can be hidden somewhere in the project, only to be found too late in the process. Luckily, we can exercise some editor scripting to the rescue…

Solution

Here is the full code for finding these missing references, in case you run into this issue:

using System.Collections;
using System.Linq;
using UnityEditor;
using UnityEngine;

public class MissingReferencesFinder : MonoBehaviour 
{
	[MenuItem("Tools/Show Missing Object References in scene", false, 50)]
	public static void FindMissingReferencesInCurrentScene()
	{
		var objects = GetSceneObjects();
		FindMissingReferences(EditorApplication.currentScene, objects);
	}

	[MenuItem("Tools/Show Missing Object References in all scenes", false, 51)]
	public static void MissingSpritesInAllScenes()
	{
		foreach (var scene in EditorBuildSettings.scenes)
		{
			EditorApplication.OpenScene(scene.path);
			FindMissingReferences(scene.path, Resources.FindObjectsOfTypeAll<GameObject>());
		}
	}

	[MenuItem("Tools/Show Missing Object References in assets", false, 52)]
	public static void MissingSpritesInAssets()
	{
		var allAssets = AssetDatabase.GetAllAssetPaths();
		var objs = allAssets.Select(a => AssetDatabase.LoadAssetAtPath(a, typeof(GameObject)) as GameObject).Where(a => a != null).ToArray();
		
		FindMissingReferences("Project", objs);
	}

	private static void FindMissingReferences(string context, GameObject[] objects)
	{
		foreach (var go in objects)
		{
			var components = go.GetComponents<Component>();
			
			foreach (var c in components)
			{
				if (!c)
				{
					Debug.LogError("Missing Component in GO: " + FullPath(go), go);
					continue;
				}
				
				SerializedObject so = new SerializedObject(c);
				var sp = so.GetIterator();
				
				while (sp.NextVisible(true))
				{
					if (sp.propertyType == SerializedPropertyType.ObjectReference)
					{
						if (sp.objectReferenceValue == null
						    && sp.objectReferenceInstanceIDValue != 0)
						{
							ShowError(context, go, c.GetType().Name, ObjectNames.NicifyVariableName(sp.name));
						}
					}
				}
			}
		}
	}

	private static GameObject[] GetSceneObjects()
	{
		return Resources.FindObjectsOfTypeAll<GameObject>()
			.Where(go => string.IsNullOrEmpty(AssetDatabase.GetAssetPath(go))
			       && go.hideFlags == HideFlags.None).ToArray();
	}
	
	private const string err = "Missing Ref in: [{3}]{0}. Component: {1}, Property: {2}";
	
	private static void ShowError (string context, GameObject go, string c, string property)
	{
		Debug.LogError(string.Format(err, FullPath(go), c, property, context), go);
	}
	
	private static string FullPath(GameObject go)
	{
		return go.transform.parent == null
			? go.name
				: FullPath(go.transform.parent.gameObject) + "/" + go.name;
	}
}

Paste this code into an editor folder, load the scene you’d like to find missing references in, and click the menu option “Tools/Find Missing references in scene”.

Any issues found will be shown in the Console (as errors).

The code is also available on GitHub

Posted in GameDev, Unity, Unity Editor, Unity Tricks | 9 Comments

Unity Editor Extensions – Custom Inspectors

This is the 2nd post in the “Unity Editor Extension” series.

The post describes the basics steps for creating custom inspectors in the Unity editor. In the next posts of the series i will dive into more advanced topics such as working with inspectors along with Unity’s serialization system.

Inspector Basics

InspectorThe inspector is one of the mostly used windows in the Unity editor – a single view that displays all the relevant information for a game object and allows manipulating it easily.

By default, the inspector allows editing everything that can be serialized, according to these rules (see this post):

  • Public, or marked with [SerializeField]
  • Not static
  • Not const, readonly
  • Field of a type that can be serialized

You may ask yourself what fields can be serialized (I recommend having a read of the blog post linked above):

  • Custom non abstract classes with [Serializable] attribute.
  • Custom structs with [Serializable] attribute. (new in Unity4.5)
  • Objects that derive from UntiyEngine.Object
  • Primitive data types (int, float, double, bool, string, etc)
  • Arrays of a type that can be serialized
  • List<T> of a type that can be serialized

Creating a Custom Inspector

Unity allows creating a custom inspector for your custom defined classes. This can be done for a variety of reasons, for example: customizing the looks of the inspector or automating a certain behaviour (do something whenever a field’s value changes).

To create a new inspector, you first create a new editor class (code file placed in an Editor folder) and derive it from the Editor class. This class should also be decorated with the CustomEditor attribute, in order to let the engine know which type the editor is used for:

[CustomEditor(typeof(MySettingsClass))]
public class MySettingsEditor : Editor
{
    public override void OnInspectorGUI()
    {
        // This is where the magic happens.
    }
}

The overriden method OnInspectorGUI is the one providing the GUI code for displaying the inspector’s contents. This post does not deal with the creation of GUI elements and how to style the new inspector – these topics are planned to be covered in a future post.

Displaying the Default Inspector

Sometimes you may want to keep the looks of the original inspector while only adding minor changes to it. This can be done using the DrawDefaultInspector method. For example, consider adding a “Reset” button to the Transform component:

[CustomEditor(typeof(Transform))]
public class TransformEditor : Editor
{
    public override void OnInspectorGUI()
    {
        if (GUILayout.Button("Reset"))
        {
             var transform = target as Transform;

             transform.position = Vector3.zero;
             transform.localScale = Vector3.zero;
             transform.rotation = Quaternion.identity;
        }

        // This draws the default inspector for MySettingsClass
        DrawDefaultInspector();
    }
}

InspectorWithResetThe result of the code above can be seen on the right. You can see that a new “Reset” button was added at the top of the Transform’s inspector, followed by the original fields that are part of the Transform component.

NOTE: The default inspector is a generic implementation and may not be the one you’re used to! For example, the Transform component has a built-in custom implementation inside UnityEditor.dll, that is implemented exactly as described above (deriving from Editor and decorating with the CustomEditor attribute). Unfortunately, if you want to override that inspector instead of the default one, you’ll have to resort to reflection to invoke that inspector’s methods.

Example Usage – Execute custom code when the inspector gets modified

In this example, whenever something in the inspector GUI changes, custom code will execute and print to the console that the object was modified:

using UnityEngine;

[CustomEditor(typeof(MonoBehaviour), true)]
public class MonoBehaviourPropertiesEditor : Editor
{
    public override void OnInspectorGUI()
    {
        // Draw the default inspector first.
        DrawDefaultInspector();

        if (GUI.changed)
        {
            OnModified();
        }
    }

    private void OnModified()
    {
        Debug.Log("Inspector modified: " + target.name);
    }
}

This is a rather contrived example, but this can have real valuable usages. In our project, for example, we have an inspector that lets you select a “mode” for the edited object. Once the mode is selected, a method is called (in the same way that is shown above) that changes the visual state of the object so it matches the new mode, making the changes available immediately in the scene view.

Summary

We’ve seen how to create a custom inspector  for a custom class (inspectors are not only used to edit MonoBehaviours, they can edit any serializable asset, such as ScriptableObjects).

Stay tuned for the next parts of this series where i plan to talk about more advanced topics related to inspectors, such as serialization and Property drawers.

Resources

Posted in GameDev, Unity, Unity Editor, Unity Editor Extensions | Tagged , , | 2 Comments

A Summary of Unity Attributes

attributesUnity uses attributes all over the place for statically declaring different things. Version 4.6 RC2 has a whopping count of 45 (!) attributes to decorate your classes, methods and fields.

This post is a brief summary of all of Unity’s (public) attributes. I believe that by exploring APIs, we can learn a bit more and expand our knowledge of what’s available in the engine; I certainly found a few attributes that could be useful for my day to day job.

NOTE: some of these attributes are undocumented and some are probably ‘leftovers’ from older versions that are not used any more.

Leave a comment with how many of these you actually knew and used :)

What Was Counted

The following code was used to query for all attributes. It takes into consideration public attributes from UnityEngine and UnityEditor assemblies, omitting those that are marked as Obsolete:


var unityEngineAttributes = typeof(MonoBehaviour).Assembly.GetExportedTypes().Where(t => IncludeType(t)).ToArray();

var unityEditorAttributes = typeof(CustomEditor).Assembly.GetExportedTypes().Where(t => IncludeType(t)).ToArray();

private bool IncludeType(Type t)
{
    return t.IsPublic
           && !t.IsDefined(typeof(ObsoleteAttribute))
           && typeof(Attribute).IsAssignableFrom(t);
}

UnityEngine

These attributes are defined in UnityEngine.dll and are available to both editor and runtime classes:

Inspector Related

  • PropertyAttribute – A base class to derive custom property attributes from. These attributes are used over script public variables to control how they are drawn in the inspector. For more info see link, link
  • TooltipAttribute – A built-in PropertyAttribute that adds a tooltip to script variables in the inspector.
  • SpaceAttribute – A built-in PropertyAttribute that adds spacing around script variables in the inspector.
  • HeaderAttribute - A built-in PropetyAttribute that adds a header over a script variable in the inspector.
  • RangeAttribute – A built-in PropertyAttribute that constrains an int/float field in the inspector to a specified range.
  • MultilineAttribute – A built-in PropertyAttribute that changes string editing in the inspector to a multi-line textbox.
  • TextAreaAttribute – A built-in PropertyAttribute that allows string editing in the inspector inside a flexible text area.
  • HideInInspector - Hides a field from being displayed in the inspector (although it is still serialized).
  • SerializeField – Notifies Unity that the field decorated by the attribute should be serialized.

Menu Related

  • AddComponentMenu – Allows placing custom scripts (MonoBehaviours) under a different category of the Add Component menu (the default is under Scripts).
  • ContextMenu – Add custom commands to the inspector’s context menu of the current script.
  • ContextMenuItemAttribute – Used to add a context menu (right-click menu) in the inspector for a specific field. See this link for more information.

Execution

  • RPC – Marks a method so that it can be used along with Unity networking and be invoked by remote clients.
  • ExecuteInEditMode – Placed over a script (MonoBehaviour) to have it execute even when not in play mode.

Components Related

  • DisallowMultipleComponent – Prevents the same component from being added twice to the same game object.
  • RequireComponent – Specifies that a component marked by this attribute requires another component (which will automatically be added when using the component).
  • MonoPInvokeCallbackAttribute – Allows registering a static method so it can be passed and invoked from unmanaged code. See this link for more info.
  • ThreadSafeAttribute – No documentation :( *may* be related to this
  • ConstructorSafeAttribute – No documentation :( Probably used by native code/Mono.
  • AssemblyIsEditorAssembly – Marks all types in an assembly to be considered as editor classes.
  • SelectionBaseAttribute – Marks scripts as selection bases (defines the behaviour of which object will be picked when selected in the scene view).
  • DefaultValueAttribute – Compiler-injected attribute when using default values for method parameters.
  • ExcludeFromDocsAttribute – Probably used internally to hide certain classes from the auto-generated documentation.
  • FormerlySerializedAsAttribute – Provides a way to rename fields after they’ve been assigned without losing their values.
  • TypeInferenceRuleAttribute – No documentation :(
  • ImageEffectTransformsToLDR – Switch to LDR rendering
  • ImageEffectOpaque – Image effects marked with this attribute will be rendered after opaque geometry (but before transparent geometry).

Unknown (Flash Related?)

  • ImplementedInActionScriptAttribute – No documentation :( Probably not used anymore.
  • NotConvertedAttribute – Instructs the build pipeline to not convert the given type to the target platform.
  • NotFlashValidatedAttribute – Don’t try to validate a type/member for the Flash platform.
  • NotRenamedAttribute – Prevents name mangling of constructors, methods, field names.

UnityEditor

These attributes that are defined in the UnityEditor.dll and are available to editor classes:

  • InitializeOnLoadAttribute – Allows running custom code when the editor launches.
  • CustomPreviewAttribute – Mark a class as the provider of a custom preview for a given type.
  • CustomPropertyDrawer – Provides information for property drawers (or decorator drawers) on which type they’re a drawer for. See this link.
  • TreeAttribute – No Documentation :( Seems related to Unity’s tree editor.
  • CallbackOrderAttribute – Defines callback order ???
  • PostProcessBuildAttribute – Used to mark a method that will be called following a build (to allow post processing of the final output).
  • PostProcessSceneAttribute – Get a notification just before building a scene (allows to perform processing before it is built).
  • DidReloadScripts - mark a method with this attribute to receive a notification when scripts were reloaded.
  • OnOpenAssetAttribute – Marks a method to be called when opening (double-clicking) an asset in the project browser.
  • CustomEditor - Provides an Editor derived class (inspector) the type it is editing.
  • CanEditMultipleObjects – Marks a custom editor (inspector) as able to edit multiple objects at the same time.
  • PreferenceItem – Adds custom preferences section to the preferences window.
  • MenuItem – Adds a menu item to the main editor window and inspector windows.
  • DrawGizmo – Add a gizmo renderer to any component.

 

Posted in GameDev, Unity | Tagged , , | 2 Comments

Wonderball Heroes hits 500K downloads on Google Play

This is going to be a very brief show off post.

Wonderball Heroes, the game that me and the team over at Moon Active are working on for the last few months has recently hit the 500,000 downloads mark !

Still a long way to get to the first million, but it’s definitely a nice milestone to reach.

I recommend all Android users to go check it out :)

*For iOS users, you can also get the game from the App Store of course: https://itunes.apple.com/il/app/wonderball-heroes/id859987839?mt=8

500K Downloads

500K Downloads

Posted in GameDev | Tagged , | Leave a comment

Unity Editor Extensions – Menu Items

The Unity editor allows adding custom menus that look and behave like the built-in menus.  This can be very useful for adding commonly used functionality that is frequently needed to be accessible directly from the editor UI.

In this post i’ll show how new menu items in the Unity editor are created and try to provide real-world example usages to every described topic.

Adding Menu Items

In order to add a new menu to the top-level toolbar, you should create an editor script (a script file that is placed anywhere in the project under a folder named Editor). Menu items are created in script code as static methods that are marked with the MenuItem attribute.

For example, it’s common to add a new “Tools” menu (or a top-level menu with your company’s name) to provide options that are commonly used by your team/company.

Here’s an example of adding a new Tools menu with an option under it (clears all PlayerPrefs data):

using UnityEngine;
using UnityEditor;

public class MenuItems
{
    [MenuItem("Tools/Clear PlayerPrefs")]
    private static void NewMenuOption()
    {
        PlayerPrefs.DeleteAll();
    }
}

This creates a new editor menu called Tools, and places a menu item called Clear PlayerPrefs under it:

AddingMenuItem

 

 

It’s also possible to create new menu items under an existing menu (e.g: under the Window menu), and also to create multiple levels of menus for better structuring and organization (recommended):

using UnityEngine;
using UnityEditor;

public class MenuItemsExample
{
    // Add a new menu item under an existing menu

    [MenuItem("Window/New Option")]
    private static void NewMenuOption()
    {
    }

    // Add a menu item with multiple levels of nesting

    [MenuItem("Window/SubMenu/Option")]
    private static void NewNestedOption()
    {
    }
}

This results in the following menu items:

MenuOptions

 

 Hotkeys

To allow power users and keyboard junkies to work faster, new menu items can be assigned with hotkeys – shortcut key combinations that will automatically launch them.

These are the supported keys (can also be combined together):

  • % – CTRL on Windows / CMD on OSX
  • # – Shift
  • & – Alt
  • LEFT/RIGHT/UP/DOWN – Arrow keys
  • F1…F2 – F keys
  • HOME, END, PGUP, PGDN

Character keys not part of a key-sequence are added by adding an underscore prefix to them (e.g: _g for shortcut key “G”).

Hotkey character combinations are added to the end of the menu item path, preceded by a space), as shown in the following examples:

// Add a new menu item with hotkey CTRL-SHIFT-A

[MenuItem("Tools/New Option %#a")]
private static void NewMenuOption()
{
}

// Add a new menu item with hotkey CTRL-G

[MenuItem("Tools/Item %g")]
private static void NewNestedOption()
{
}

// Add a new menu item with hotkey G
[MenuItem("Tools/Item2 _g")]
private static void NewOptionWithHotkey()
{
}

Menu items with hotkeys will display the key-combination that is used to launch them. For example, the code above results in this menu:

MenuHotkeys

 

 

 

Note: There’s no validation for overlapping hotkeys ! defining multiple menu items with the same hotkey results in only 1 option being called by hitting the key combination.

Special Paths

As seen, the path passed to the MenuItem attribute controls under which top level menu the new item will be placed.

Unity has a few “special” paths that act as context menus (menus that are accessible using right-click):

  • Assets – items will be available under the “Assets” menu, as well using right-click inside the project view.
  • Assets/Create – items will be listed when clicking on the “Create” button in the project view (useful when adding new types that can be added to the project)
  • CONTEXT/ComponentName – items will be available by right-clicking inside the inspector of the given component.

Here are some examples of how to use these special paths:


// Add a new menu item that is accessed by right-clicking on an asset in the project view

[MenuItem("Assets/Load Additive Scene")]
private static void LoadAdditiveScene()
{
    var selected = Selection.activeObject;
    EditorApplication.OpenSceneAdditive(AssetDatabase.GetAssetPath(selected));
}

// Adding a new menu item under Assets/Create

[MenuItem("Assets/Create/Add Configuration")]
private static void AddConfig()
{
    // Create and add a new ScriptableObject for storing configuration
}

// Add a new menu item that is accessed by right-clicking inside the RigidBody component

[MenuItem("CONTEXT/Rigidbody/New Option")]
private static void NewOpenForRigidBody()
{
}

The results for this code segment is these new menu options:

AssetsMenu

Assets (project view) right-click menu

AssetsCreateMenu

New option available from the Asset’s CREATE button

CONTEXTMenu

New context menu option for the RigidBody component

Validation

Some menu items only make sense in a given context, and should not be available otherwise. Enabling/disabling menu items according to their usage context is done by adding validation methods.

Validation methods are static methods, marked with the MenuItem attribute, passing true to the validation argument.

The validation method should have the same menu path as the menu it is validating, and should return a boolean value to determine whether the menu item is active or not.

For example, Validation methods can be used to add a right-click menu  to Texture assets only under the project view:

[MenuItem("Assets/ProcessTexture")]
private static void DoSomethingWithTexture()
{
}

// Note that we pass the same path, and also pass "true" to the second argument.
[MenuItem("Assets/ProcessTexture", true)]
private static bool NewMenuOptionValidation()
{
    // This returns true when the selected object is a Texture2D (the menu item will be disabled otherwise).
    return Selection.activeObject.GetType() == typeof(Texture2D);
}

When right-clicking on anything that is not a texture in the project view, the menu item option will be disabled (greyed out):

TextureGreyedOut

Controlling Order with Priority

Priority is a number that can be assigned to a menu item (passed to the MenuItem attribute) that controls the ordering of menu items under the root menu.

Menu items are also automatically grouped according to their assigned priority in increments of 50:

[MenuItem("NewMenu/Option1", false, 1)]
private static void NewMenuOption()
{
}

[MenuItem("NewMenu/Option2", false, 2)]
private static void NewMenuOption2()
{
}

[MenuItem("NewMenu/Option3", false, 3)]
private static void NewMenuOption3()
{
}

[MenuItem("NewMenu/Option4", false, 51)]
private static void NewMenuOption4()
{
}

[MenuItem("NewMenu/Option5", false, 52)]
private static void NewMenuOption5()
{
}

The code example results in the menu that has 2 groups of items, according to the assigned priority:

Priority

 

 

 

 

If it is required to add and organize menu items under existing Unity menus, a bit of “guess work” is needed, as most of the built-in menu items use priorities. Another option is to use a tool such as Reflector and look at the source code for internal Unity code (such as UnityEditor.CreateBuildInWindows) that is responsible for creating some of the menus in the editor.

Related Classes

Below is a listing of a few extra classes that are related to adding new menu items.

MenuCommand

When adding a new menu item to an inspector (using “CONTEXT/Component”, as described above), sometimes it is necessary to get a reference to the actual component (e.g: to modify its data).

This can be done by adding a MenuCommand argument to the static method that defines the new menu item:

[MenuItem("CONTEXT/RigidBody/New Option")]
private static void NewMenuOption(MenuCommand menuCommand)
{
    // The RigidBody component can be extracted from the menu command using the context field.
    var rigid = menuCommand.context as RigidBody;
}

As seen in the code example, when invoking the menu item, the component that serves as its context can be accessed using the context field.

ContextMenu

This attribute allows defining context menu items. This works exactly the same as defining a method with the MenuItem attribute with a path that starts with “CONTEXT/…”.

The difference is that with this attribute, you define the default context menu for a given component, whereas with the MenuItem approach, you “extend” other components’ menus (for example – the default components that are part of the engine).

Example – a component that exposes a context menu option to clear its data:

public class NameBehaviour : MonoBehaviour
{
    public string Name;

    [ContextMenu("Reset Name")]
    private static void ResetName()
    {
        Name = string.Empty;
    }
}

ContextMenuItem

This attribute is added to fields of a component (MonoBehaviour) class, to allow adding context menus at a finer resolution. While the ContextMenu attribute shown above adds context menus at the component level, marking fields with this attribute will add a right-click menu to individual public fields.

Since this attribute is added to a field and not a method, it accepts 2 arguments: the display name of the menu item and a name of a method (instance method) to be invoked when the menu item is selected.

Example – Adding a method to randomly initialize a component’s field to some state:

public class NameBehaviour : MonoBehaviour
{
	[ContextMenuItem("Randomize Name", "Randomize")]
	public string Name;

	private void Randomize()
	{
		Name = "Some Random Name";
	}
}

This code results in this context menu when right-clicking on the Name field of this component:

ContextMenuItem

Wrap Up

As shown in this article, extending the Unity editor with custom menus can be pretty straightforward.

Building commonly used functionality and having it available from the editor is recommended for teams of all sizes and can be a huge time saver.

Links

Posted in GameDev, Unity, Unity Editor, Unity Editor Extensions | Tagged , , , | 3 Comments

Unity Editor Extensions Series

The Unity editor offers many APIs for extending it in various ways to enhance your
development workflows. This contains things such as hooks into the build pipeline, creation of custom windows, menu items and custom inspectors to name a few.

In this series I will explore the various Unity editor extensions and hook points of the Unity Editor, all with real-world example usages and code samples.

Posted in GameDev, Unity, Unity Editor, Unity Editor Extensions | Tagged , , , | Leave a comment

Unity Snippets – ScriptableObject Factory

ScriptableObjects are serializable Unity objects that are attached to a GameObject (like MonoBehaviours). Their typical use is for storing data, and they can also be saved as an asset in you project, just like any other texture or audio clip.

If you’re not familiar with them- be sure to check out this video: Introduction to Scriptable Objects.

Creating a ScriptableObject

Most code samples that describe how to create a new Scriptable object repeat the same boring, boilerplate code that looks something along the lines of:

var obj = ScriptableObject.CreateInstance<MyNewType>();
string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath (path + "/" + "assetName.asset");
AssetDatabase.CreateAsset (asset, assetPathAndName);

AssetDatabase.SaveAssets ();
EditorUtility.FocusProjectWindow ();
Selection.activeObject = asset;

Unfortunately, there’s no built-in option to create one from the editor…

The little recipe here actually performs the same code as above, including adding a menu item to the editor, but it only works for a single class, and not for all ScriptableObject-derived types you define.

ScriptableObjectFactory

I’ve put together a short editor extension that will look for all ScriptableObject types in your project and let you select which one you want to create.

This extension adds a new menu option under Assets/Create or Project/Create:

Create a ScriptableObject

Create a ScriptableObject

 

 

 

 

 

 

 

 

 

 

 

 

Create a ScriptableObject

Create a ScriptableObject

 

 

 

 

 

 

 

 

 

 

 

 

 

Once you click this option, a popup window opens and allows you to select what type of ScriptableObject you want to create:

Popup for creating a ScriptableObject

Popup for creating a ScriptableObject

 

 

 

 

 

The source code for this little helper is available at: ScriptableObjectFactory.

It’s also available as a .unitypackage here: UnityPackage

Enjoy :)

Resources

  • ScriptableObject documentation: http://docs.unity3d.com/ScriptReference/ScriptableObject.html
Posted in GameDev, Unity, Unity Editor | Tagged | 2 Comments

Pimp My Debug.Log

This post describes a quick “tip” for improving how you work with logging in Unity. Share it with your team in case you find it useful :)

Console Window Mess

As developers we probably spend 50% of our time debugging code (it is my blog, so i get make up fake statistics). Any Unity developer who spends more than 5 minutes with the editor probably knows the Debug class, and more specifically the Debug.Log method that prints log messages to the Console window.

While it’s easy to log messages, the Console window can quickly get cluttered and it becomes super hard to find the exact trace message you’re looking for.

Rich text formatting seems to be one of Unity’s best kept secrets (haven’t seen people using it yet), but it can come in handy for tidying up the Console window.

Rich Text Formatting

Log messages passed to Debug.Log and its other variants (LogError, LogWarning, etc) can include special “tags” that provide formatting for the log message, for example:

Debug.Log("<color=green>This is a green message!</color>");

These tags control the visual properties of the displayed text, such as its size and color. For all the fine details check out the documentation here.

The only issue is that it can be tedious to manually format all log messages, which may drive you to not use this feature at all.

Luckily, there’s a better option. Enter the “Extension Method” solution.

String Extensions Class

Instead of manually formatting every log message and adding the required tags, we can create a static extensions class, and define a few extension methods on the string type.

The following code snippet adds a few extension methods on the string class:

This allows writing simple code, without having to manually add the formatting tags:

// Update is called once per frame
void Update ()
{
    var message = "Hello, World!";
    // Print the message in green.
    Debug.Log (message.Colored (Colors.green));

    // Compose different formatting together.
    Debug.Log (message.Bold().Sized(16));

    // Works with LogError as well.
    Debug.LogError (message.Italics());
}

The code snippet above prints out the following logs in the Console window, with the proper formatting:

Console window output

Console window output

Notes

  • Rich text formatting works with all Debug.LogXXX methods.
  • Editor GUI controls also support rich formatting, however it must be explicitly enabled.
GUIStyle style = new GUIStyle ();
style.richText = true;
Posted in C#, GameDev, Unity | Tagged , , , | Leave a comment