Adding the little padlock button to your EditorWindow!

One of the less well known features of Unity is the little padlock button that lives in the upper-right corner of the Inspector window. This button is fantastic because it causes the inspector to ignore future selections and thus allowing you to select other objects without affecting the contents of the inspector.

Those who are needing (or just want the fancy little padlock!) to achieve a similar type of locking functionality in their own custom editor windows can simply by adding the magic method “ShowButton” to their editor window class. In fact, you don’t have to add a padlock, you could add some other icon!

Screenshot of custom editor window with lock icon.

Screenshot of custom editor window with lock icon.

Continue reading

Syntax Highlighting with DITA

Syntax highlighting is something that I like in user documentation because I feel that it helps make source listings easier for people to understand.

When I first examined the possibilities several months back there did not appear to be a ready solution that worked with Ditac by XMLmind. Additionally the DITA specification does not seem to specify a standard technique for identifying the syntax used in code blocks. I had planned to integrate XSLTHL into my XHTML and XSL:FO stylesheets but I couldn’t really spare the time.

Fortunately it seems that XMLmind have themselves implemented syntax highlighting using XSLTHL. As a bonus they have implemented this for each of the supported deliverables and customizing the output styles and colours is super easy.

A good selection of syntaxes are supported which can be activated using the outputclass attribute.

<codeblock outputclass="language-csharp"><![CDATA[
public class SomeCoolClass {

    public void DoSomething() {
        Debug.WriteLine("Hello World!");
    }

}
]]></codeblock>

Here is an example from the Rotorz Tile System user guide:
http://rotorz.com/tilesystem/guide?ref=25d80dd4-f917-424a-a390-b95e5588f69c

Working with DITA Topic Identifiers

When writing my new user documentation using DITA I have found myself attempting to maintain a consistent naming convention for my unique topic IDs. The problem with this approach (to me at least) is that it would be fairly easy to inadvertently reuse the same “unique” identifier for two separate topics.

So I pondered on a better solution and did some searching through online user documentation that uses DITA (or something very similar). One of the things that I noticed about these various websites is that they use a GUID instead of a carefully named identifier. A much easier solution! All I needed was an easy way to generate GUIDs in my XML documentation.

Unfortunately the XML software that I use (OxygenXML) doesn’t appear to have a GUID generator built-in as standard. Instead of wasting too much time trying to figure out how to write a Java plugin for Oxygen I decided to write a simple application using C# which registers a system-wide hotkey Ctrl+Shift+V which generates a new GUID (with a custom prefix “guid-”) and pastes that into the application that I am working with (Oxygen and NotePad++). Another nice touch is that because this uses the clipboard Ctrl+V can be used to re-paste the same GUID over and over until a new GUID is generated (or until something else is copied to the clipboard!)

I added a few extra options which others might benefit from and uploaded the source (BSD) and a compiled executable to GitHub for those who might find this of use!

https://github.com/kruncher/guid-generator-hotkey

Choosing an Extensible Documentation Solution

For a while I have been using Microsoft Word to author user guides and to be fair this has been a good solution up until now. Since beginning work on Rotorz Tile System there have been a number of product updates which have required multiple updates of the user documentation. Despite using style presets the process of maintaining consistent formatting and updating illustrations is extremely time consuming. I also feel that there is a need for a web based version of the documentation to make it easier for some people to find their way around.

So… ultimately I required a solution that takes a number of document fragments that can be composed in a variety of ways to provide at least two deliverables (PDF plus web based documentation). After some careful thought I also decided that I would like to avoid directly formatting the documentation that I write to save valuable time; this should be handled automatically by the documentation solution. Continue reading

Possibility of reusing custom editors in custom window?

This functionality has since been added in Unity 4!
See: http://docs.unity3d.com/Documentation/ScriptReference/Editor.CreateEditor.html

Several weeks ago I had some ideas that would add lots of flexibility to my custom editor window. In a nutshell the idea was to add, modify and remove certain components. To be honest I thought that this would be relatively easy because this functionality is already available within Unity inspector windows. I remembered seeing `EditorGUILayout.PropertyField` and I foolishly assumed that would do the trick, but I was wrong…

My next attempt was to enumerate component properties using `SerializedObject` and `SerializedProperty`. Whilst this approach did in fact provide something that resembled a custom inspector, it was extremely lacking. When I realised, this couldn’t possibly utilise custom editors!

For example, the `Transform` component has a custom inspector which is tailored specifically for it. In Rotorz Tile System we use a custom inspector on `RotorzTileSystem` components which allows properties to be modified and actions to be performed. These custom inspectors are easily defined using the `CustomEditor` attribute. So the idea here is to reuse these custom editors (which are not necessarily created by myself) within my editor window!

With thanks to MonoDevelop’s fantastic assembly browser I came across the undocumented class `UnityEditor.ActiveEditorTracker`. The publicly exposed methods are well named and fairly self-explanatory. So I had a go at creating a rough mockup of a custom inspector. I was pleasantly surprised at how easy this had now become. Creating a rudimentary custom inspector is as simple as shown below:

using UnityEngine;
using UnityEditor;

public class CustomWindow : EditorWindow {

    [MenuItem("Window/Test")]
    public static void Test() {
        EditorWindow.GetWindow<CustomWindow>("Test");
    }

    GameObject activeGO;
    Editor editor;

    void Update() {
        if (activeGO == Selection.activeGameObject)
            return;

        activeGO = Selection.activeGameObject;
        editor = null;

        if (activeGO != null)
            editor = UnityEditor.ActiveEditorTracker.MakeCustomEditor(activeGO.transform);

        Repaint();
    }

    void OnGUI() {
        GameObject go = Selection.activeGameObject;
        if (go == null)
            return;

        // Use the registered editor for `Transform`
        EditorGUILayout.InspectorTitlebar(true, editor.target);
        editor.OnInspectorGUI();
    }

}

Unfortunately this functionality is not currently documented and as such cannot be used in a commercial Unity extension because there is no guarantee that it will continue to work in future versions of Unity. This is a great shame because I could put this to good use! I also suspect that the developers of PlayMaker could utilise this functionality if it were documented for customisable action GUIs.

Please consider voting for Unity Technologies to add a basic level of documentation for this functionality :-)
http://feedback.unity3d.com/unity/all-categories/1/hot/active/document-unityeditoractiveedi 

Changing data structure of MonoBehaviour in Unity Extension

Several customers who have purchased Rotorz Tile System have made a number of feature requests that exceed the original design of the product. I am delighted that my fellow game developers are finding Rotorz Tile System useful in their projects. There have been some fantastic suggestions which have already helped further the product.

Instead of hacking new features into the current design it seems more appropriate for the existing data structure to be updated. In addition to improving performance and reducing memory overhead it will make the new features easier to maintain. Continue reading

Prepare 2D tile set for Rotorz Tile System [video]

I recently received a question asking if Rotorz Tile System could be used to paint 2D tiles. A tile is a three-dimensional object that is represented by a prefab. So the answer was yes, because a plane can be created and mapped to the tile texture. When working with tile sets it is generally a good idea to pack tiles into a texture atlas in order to keep the number of draw calls low.

The process of creating such tiles manually is not an overly complicated procedure, but can easily become time consuming. A plane mesh must be created for each texture atlas mapping with varying UVs for each tile. A tile brush must then be created for painting with. So I decided that it would be useful to add a utility window to ease the process of creating 2D tile brushes.

The following video demonstrates the process of creating a 2D tile set. The video then proceeds to demonstrate the creation of an oriented tile brush using the automatically generated tile brushes.

Credit for demo atlas artwork: http://mapledev.tumblr.com/post/10406905135/howtotileset Continue reading

Developing extendable editor extensions for Unity 3D

Many of the editor extensions that are available from the asset store are closed source. For those who do not understand, this simply means that the source code is compiled into one or more class libraries (DLL).

There are a number of very good reasons why some extension developers choose to do this:

  • Avoid script naming conflicts with user code and indeed other extensions

    Unity requires that each script file that contains a MonoBehaviour is named to match the class name. Unity does not allow two user scripts to coexist with the same name; neither directories or namespaces will help here!

    However, these limitations do not apply to behaviours that are exposed by a class library. When developing a class library it is also possible to put namespaces to good use! This helps to avoid clashing with other extensions! Continue reading

Fall Detection for Platform Game in Untity 3D

In order to detect that a player has fallen to certain death there needs to be some sort of detector. The detector needs to be positioned and scaled to fill the gap at the point of no return. Box colliders tend to work best for this because they can be positioned and scaled easily.

In my game I wanted the player to respawn from the side that they fell from to avoid skipping a tricky area! To achieve this I added one sensor for each major ledge. Upon being hit, the sensor selects itself as the active respawn position for that fall.

The way in which falls are detected and handled will vary with design. I found that there are usually two such sensors for each fall, one before and one after. Or perhaps just one for the start and/or end of a level! Of course there may be occasions where additional sensors are needed; like with high climbs. Continue reading

Easily create levels for Unity 3D using Rotorz Tile System!

When creating Munchy Bunny! I was using an extension called Tidy Tile Mapper which allows you to create levels using 3D tiles. This is a fantastic extension for Unity which offers a lot of powerful features. Unfortunately I encountered several major limitations which made it difficult to achieve what I needed:

  • Each level consists of two separate grids; a large one for platforms and a smaller one for chocolate bricks, eggs, diamonds, etc. The grids have to occupy the same space on the Z-axis. This meant that the grids had to be separated to work on them and then moved back again afterwards. This was an extremely slow and tedious process which caused the Unity editor to crash on multiple occasions.
  • I found that the Unity editor began to run extremely slowly when using grids (even when empty) of 300 columns by 100 rows (the small grid size for Munchy Bunny!)
  • It was  not possible to define custom block orientations which meant that I was unable to create blocks to the quality that I desired. Continue reading