#Unity3D plugin review: Advanced Inspector

The author of Advanced Inspector gave me a free copy over Christmas. I’d considered it many times, and always ended up choosing not to buy, and write my own fixes/workarounds instead. So I was keen to try this out on a hobby project and see how well it works in practice.

What is it?

A replacement for Unity’s built-in Inspector. This (optionally) changes the editing interface for every single Component in your Unity projects.

Why do we need it?

When you run Unity, you get the standard multi-pane IDE that is the Unity Editor. Whether you’re a programmer, a designer, or an artist, this is your main portal into Unity, and the starting point for all your work.

Anything you select in the 3D/2D scene causes an Inspector panel to appear, with all the editable data about that thing. Unity’s built-in Inspector is very basic; by modern standards of GUI/UX, it sucks. Fixing GUI is very expensive, so instead … Unity has gradually been making the Inspectors more and more customisable.

Traditionally this was very hard to do; in the last 12 months it has become much easier, and Unity has unlocked more features. To date, I’ve not been sure if the 3rd party plugins are fully using the new features.

Unity’s default Inspector: Issues we want to solve

This is NOT an exhaustive list, but these are some of the problems I hit on a regular basis:

  1. Prefabs don’t fully work in Unity yet
    • Try nesting your prefabs; weep.
    • Personally: I don’t dare do this, I saw too many Unity projects get corrupted this way. But some of the 3rd-party Inspector replacements introduce workarounds for this.
  2. Core C# is blocked/unsupported:
    • Dictionary is unsupported; you cannot view them, you cannot edit them
      • NB: there was historical reason for this: Unity itself doesn’t support Dictionary(!), and until very recently it was very difficult to add the missing support.
      • Unity still doesn’t support Dictionary, but since 2014 you can add the support in approx 10 lines of code.
      • You still have to copy/paste that code into every class that uses a Dictionary :(. But it’s better than nothing!
  3. List’s cannot be re-ordered (Unity has a private class that allows this. It’s very good (I’ve used it), but it is not supported yet, has a couple of serious bugs still.)
  4. Inspector customization requires one new class … for every class you want to customize
    • There is a half-implemented system for reducing this burden (see below), but it doesn’t fully work yet.
  5. Inspector customization on a “write once, run many times” basis doesn’t work yet:
    • You CANNOT customize the rendering of Generic types (anything that looks like: “List<string>”) – the feature for this (CustomPropertyDrawer) isn’t fully implemented
      • Until Unity fixes this, it’s surprisingly difficult to manually add support for Dictionary (it’s possible, but all the solutions are ugly and require copy/pasting code in your game projects. Error-prone and time-consuming)

Advanced Inspector

This plugin aims to add some of the missing features (Dictionary! List!), while also removing the need to keep writing new classes every time you want to customize something.

The most exciting for me was Generic List’s and Dictionary’s. Adding support for Dictionary would be transformative on the quality and speed of coding in Unity. It’s also (so far) hard to write yourself!

What do we hope for / expect from this plugin?

Price: $20-40

This is a low-cost plugin. It’s not expensive, so we expect something relatively simple. Professional devs would buy it without blinking – it’s practically free for them – but hobbyists will want to be sure this works well across the board.

NB: “total conversions” of the Unity IDE are especially dangerous: a bug in these can cause mayhem in your dev process. e.g. “I can’t edit the data any more!”. So … we have a higher bar of quality here than normal.

Documentation: PDF Tutorial

Personally, I greatly dislike PDF documentation – HTML is far better for a bunch of reasons. But this PDF (and the more technical PDF Manual) is well written and clear, with liberal use of screenshots.

Verdict: Better than expected for the price range

Core Features:

Here are the stand-out features I noticed in the docs/official page:

  • “Every non-static fields, properties or parameter-less method can be exposed.”
  • “Every list and array’s nodes can be dragged around to reorder them.”
  • “Every field can be expanded to display the inner fields, being in a list or not.”
  • “Every fields can be copy/pasted, even complex type, such as struct, or ComponentMonoBehaviour hierarchy.”
  • “Every fields can be apply or reverted independently. No need to apply/revert the whole prefab.”
  • “Every fields is fully dynamic; can be hidden, renamed, change color, display help box or change how the data is exposed at runtime.”
  • “The inspector is now separated into two columns, one for the labels, one for the editing field. The separator can be moved around, no space wasted.”
  • “Add new data type, like Unity-friendly Dictionary, Ranges or Action Bindings”
  • “Control the Preview section of the Inspector without a custom editor.”

Advanced Inspector: Basic usage

Out of the box, Advanced Inspector doesn’t do anything. As the author puts it:

“By default, the Advanced Inspector does not change any standard behaviour on how your MonoBehaviour or your ScriptableObject are displayed in Unity’s inspector. This behaviour of being “off” is wanted.”

To enable it, it’s not a simple “on/off”. Instead, you have to edit every single source file and copy/paste some new code into your scripts. How much code? As it turns out, this bit is much less painful than it sounds. All you need is:

using AdvancedInspector;
[AdvancedInspector(InspectDefaultItems = true)]

// ...your "public class BLAH : MonoBehaviour {" goes here

Do this, save, and … Advanced Inspector immediately starts working, out of the box. You don’t have to click, refresh, or anything; Unity immediately changes the Inspector for whichever class(es) you edited.

Verdict: easy, relatively painless – but a poor start. For large projects, or ones where you do re-use between games, it’s creating artificial coupling between codebases, and makes your code harder to maintain going forwards.

GUI changes

Unity’s built-in GUI is fugly. I was looking forward to see how the GUI changes :). Here’s a small but fairly rich Component from a hobby project of mine:

public class PlayingCard : MonoBehaviour
{
	public Renderer rendererForFace;
	public Text textTitle;
	public Image imageCardArt;

	public Deck currentDeck;
	public CardData data;
}

The first three properties are standard Unity types. The last two are my game-code. Interestingly, one is a class (a Unity Component/MonoBehaviour), and the other a struct. Here they are:

public class Deck : MonoBehaviour
{
	public GameObject blankCardTemplate;
	public CardLibrary library;
	public List<GameObject> cards;
}

[System.Serializable]
public struct CardData
{
	public string GameID;
	public string CardName;
	public int hpMax, hpCurrent;
}

Note that EVERYTHING here is either “Unity standard”, or “extends a Unity standard”, or “is Serializable”. This means that it’s all supported by the built-in Unity Inspector.

What happens in the GUI? On the left, the project before adding Advanced Inspector. On the right, same component (auto-refreshed by Unity) after adding:

Screen Shot 2014-12-30 at 13.33.57 Screen Shot 2014-12-30 at 13.32.31

OMG I can’t edit Transform any more!

Unity’s minimum width for Inspectors is 275 pixels; Advanced inspector breaks for anything less than 400 pixels.

But … it’s not as bad as it looks. To the left of the “X” components, you see a vertical line. This is a non-standard UI image, and it turns out: it’s a draggable divider; you can drag the divider left/right to uncover the (incorrectly) hidden fields.

Ignoring my custom Component for now, let’s see what happens with the built-in Unity ones:

Screen Shot 2014-12-30 at 14.04.08

It … sort-of works. Notes:

  1. It’s a nice feature. Unity’s hard-coded column widths are often annoying.
  2. It’s not perfect. Moving the divider changes it for ALL components in the inspector. This is bad, because Unity’s built-in Transform needs the divider on the left, but Unity’s built-in other components (e.g. RigidBody) need it on the right.
  3. If you resize your Inspector pane to 400 pixels or more, you can fit everything. If you’re working on a laptop? Get used to frequently resizing, every few seconds, to see what you’re editing, and then to edit it.
  4. You need to know the divider is movable. Newcomers to your project will NOT know this. Easy to explain, easy to remember, but it would be better to include the standard “draggable column” icon somewhere on the divider itself.

Where did my struct go?

Unity didn’t always support structs (sigh). But it has for more than a year now.

By default, Advanced Inspector doesn’t display structs. On my own, using the manual, I couldn’t get it to work. I reached out to the developer, and got some help on this.

With current/previous versions, you need to:

  1. Edit your CLASS THAT HAS A VARIABLE, and enable AI (as normal)
    • Mark this class with: “[AdvancedInspector(true,true)]“
  2. Edit your STRUCT CLASS ITSELF, and specifically enable the struct-handling
    • Mark this class with: “[Expandable(InspectDefaultItems = true)]“

I had problems with figuring out the right place to put the “Expandable” (there were no examples in the docs). If you get it wrong, you’ll get an expandable that expands to show … nothing:

Screen Shot 2014-12-30 at 15.06.47

However … the next version of AI will simplify this, and use “[AdvancedInspector(true)]” everywhere; no more need for the separate “Expandable” keyword.

Verdict: A little fiddly, especially since Unity renders structs out-of-the-box without this, but it works.

Advanced Mode

A lot of the value of Advanced Inspector comes from the fact it is … Advanced. This is a special mode, so let’s try it out.

NB: Unity has a built-in mode for Inspector, called “Debug”; if you don’t know how to use this already, try that first! It reveals a lot of private info on Components.

Left to right (note: because AI won’t work correctly at less than 400 pixels width, I had to shrink these to fit on the webpage. Click each for a full-size version)

  1. Unity’s DEBUG mode
  2. Advanced Inspector’s ADVANCED mode (enable by right-clicking in the Inspector, and select from menu)
  3. Advanced Inspector’s DEBUG mode (ditto)
Screen Shot 2014-12-30 at 14.51.45 Screen Shot 2014-12-30 at 14.52.09 Screen Shot 2014-12-30 at 14.52.50

Observations:

  • AI’s ADVANCED/DEBUG modes made no difference to my custom Component; it has no private properties. I’d hoped they might fix the “not showing the struct” bug, but apparently not.
  • Unity’s DEBUG mode contains some weird stuff; this is to expected: you’re exposing the PRIVATE data that Unity felt you had no reason / need / value to see (sometimes it’s useful)
  • AI’s ADVANCED mode has some neat features – e.g. they’ve upgraded Transform with one of the most-often-requested features people ask Unity for. You don’t need AI to do this, but it’s a nice bonus feature.
  • AI’s DEBUG mode … does NOT include all the data from Unity’s DEBUG mode. I assumed it would be “AI ADVANCED + UNITY DEBUG”, but it’s slightly less than that.

Verdict: I would probably set AI to “Advanced” mode, and leave it always-on. I want features like the World position on transforms!

Lists

Once you enable the plugin on a Component that contains a List, you go from this to this:

Screen Shot 2014-12-30 at 15.45.58 Screen Shot 2014-12-30 at 15.46.49

Pretty much what you expect. Instead of adding 1 to the “Size” field, you press the button at top of list (should be at bottom, following standard UX – but Unity stuck their Size field at the top, so it’s not such a shock).

The UX is weak (those labels + drag-handles on the left are hard to understand), but so is Unity’s built-in renderer for List!

Verdict: Unity’s private renderer beats this, IMHO. It would be nice to see a slightly better UI/UX here. This is a feature you will be using many times an hour, every day, while working in Unity!

Dictionaries

We’ll add a Dictionary to one of the classes where AI is already enabled; like List, we expect (hope!) it will Just Work.

// add "using System.Collections.Generic;" to file if not there already!

public Dictionary<string,int> testDictionary = new Dictionary<string, int>();

WARNING: there is a deliberate bug in this code; read on for info...

Result:

Screen Shot 2015-01-03 at 17.19.38

Notes:

  • This might be a side effect of the missing Serializable; see belowThere’s a bug: it cannot create a new “Dictionary” instance via the Inspector
    • Your code MUST call “testDictionary = new …” or AI will fail to edit it
    • In practice, this is not a big problem: in order to fix Unity’s broken Serialization of Dictionary, you will HAVE to write that code somewhere in your script anyway
    • So … big bug, but very small impact.
  • It’s picked up the datatypes (string for the Key, int for the Value) correctly
  • If you type in a Key that already exists, the “plus” button is greyed out. Good feature!
    • It would be illegal to have the same Key twice
    • Although the UI could be much better here – e.g. show a warning + change button colour to orange or red, to make clear why the Key is being refused. Even better: hilight the Key it’s conflicting with (on a big Dictionary, it’ll be hard to find the duplicate)
  • The hyphen to the left of each entry is actually a DELETE button, with no confirmation and no Undo
    • Again, UI could be much better here

Adam’s stupid mistake: Dictionary is NOT serializable by default

Dictionary is still not fully supported by Unity – of course, this is one of the reasons we wanted AI in the first place!

Unity allows you to manually upgrade each Dictionary to be supported, using some Serialization callbacks, and manually adding the code that ought to be in Unity itself. There’s a blog post that explains how, as well as explaining why it took so long for this support to be added, and what some of the challenges are

Great!

What did I do in the example above?

Oh, yeah. I didn’t bother. So … my dictionary cannot serialize. Serialiaztion in Unity is NOTHING TO DO WITH SAVING TO DISK: it’s much lower-level and more core. It’s most often used in fact when nothing is changing on disk! I’ve seen it run merely because I moved the mouse across the screen.

This is fine, but it means my example above was stupid: As Sampsa points out in the comments, I should have provided a proper serializing Dictionary, and in that case, Undo would probably work correctly.

Verdict: Works great, although the UX/UI is poor. I have written better UI’s for this when making custom datatype editors in Unity and found it well worth the effort. It takes time, but it’s worth it: if you use Dictionary, you use it a lot, and spend a lot of your time in the editor with that GUI.

Undo support

Over the last few months I’ve discovered that some of the recurring bugs in Editor plugins are actually not the authors’ fault: they’re fundamental, critical bugs in Unity itself. I reported one recently that only takes a few seconds to reproduce, on any version of Unity. According to the support folks, it’s been fixed and will appear in a future version Real Soon Now.

Great. But … it leaves me suspicious of Undo support everywhere. (I found another Unity Undo bug last week. Sigh).

Undo seems to work fine with AI, except for the Dictionary (as noted above: this is probably because my Dictionary wasn’t being Serialized; this needs careful retesting, but I think it was probably a false alarm). Works fine with List – you can move things in a list, add to a list … all Undoes fine.

However, there is zero feedback in the GUI to tell you that an Undo has occurred. This is bad because it means you don’t know if the Undo has succeeded. I had to re-name my GameObject’s to unique names so I could confirm that Undo was working.

Verdict: annoying that Dictionary Undo failed. For List Undo, it isn’t AI’s “fault” that there’s no feedback (Unity should be telling you!). But … as noted at the start: with an Inspector replacement, you have to hit a higher-than-normal quality bar; you’re editing people’s sourcecode/data! I would like to see at least a flash, to show that the Undo happened.

Conclusions

GOOD: comes with source-code

It’s reassuring to have this, but … if I’m spending $40 on a product, I absolutely do not have time to be editing the source code to fix bugs. If I have to delve into someone else’s code and: understand it, learn it, plan modifications, modify it, test them, debug … and then re-do it all again each timew a new version comes out … ?

… then it’s cost me too much time, and I’m better off writing my own solution to start with.

GOOD: customized Transform Inspector

It’s a tiny thing, and you can write it yourself quickly and easily. But it’s a really really useful thing. I love it.

GOOD: eye-dropper tool for selecting things

Another minor feature, that worksaround a major Unit UX failure.

When you need to fill a GameObject field in Unity, you have to select the Component, then drag/drop the thing into it WITHOUT SELECTING the thing.

(if you select it, the Inspector vanishes, and is replaced with the Inspector for the thing you just clicked on)

AI gets around this by giving you an eye-dropper to directly select the “thing to go here” from the Inspector itself. Useful, but .. by now, I think most of us have learned automatically to do this via drag/drop.

VERY GOOD: drag/drop reorderable arrays

This is an old plugin, and some of the features (adding/removing stuff from arrays) have been added to core Unity since it was launched. But drag/drop re-ordering is still (amazingly!) missing from Unity.

I suspect we’ll have it in Unity 5, but that’s still some way off.

Again, this is small thing from a UI perspective. And AI’s implementation is very ugly (Unity’s own private-class version is a lot nicer looking). BUT … this code is very very hard to write correctly!

NB: I haven’t fully tested AI’s implementation here. Life is too short; there’s a lot of edge cases you have to check. It worked for a basic case I threw at it.

GOOD: Documentation

It’s not perfect. But it’s better than average, especially in this price range. I’ve seen $100-$200 Unity packages, even very popular ones, with considerably worse documenation! That’s shameful, but sadly true.

With a product like this the situation is constantly changing: every new version of Unity adds/removes bugs and features in Inspectors. I don’t believe any author can keep static PDF’s up to date. I don’t believe they can afford to! Especially not on the low price they’re charign here.

Ultimately, I would prefer to see a FAQ-style docs. Each FAQ tagged with a Unity version number, so you can see at a glance “for MY version of Unity, what’s possible? what works/doesn’t?” etc.

VERY GOOD: Developer support

Browsing the support forum on Unity3D.com, the developer is proactive and prompt in replying to support issues, and fixing them.

You’d expect this for every paid product, but sadly there’s a lot of lazy / cowboy developers selling on the Asset Store, and Unity corp does very little policing of this.

BAD: Defaults to disabled, everywhere

I kind-of understand, but personally I don’t like this. If a plugin is going to “fix” my Inspectors, I’d like it to “Just Do It”. Perhaps have a global setting “default on / default off”. But if I’ve chosen to import the package, that means I want to use it! I’ve already made the decision.

Note that after speaking to the author, this has been changed for the next version. See below for more info

BAD: Editing classes to enable the plugin?

This is a big problem for me, and most of the Unity projects I work on. At the very least, it’s time-consuming; at the worst, it makes the plugin “contagious”: once you use it on project, you’re effectively forced to use it on all projects.

Some examples of the problems I see now, looking at current projects:

  1. If you have many classes – say: 100 to 1,000 – in your project, … it’s going to take you a LONG time to enable the plugin individually on every one
  2. You’re hard-coding every class to depend on this Editor plugin. If you stop using this plygin, C# won’t “ignore” the import: it will refuse to compile/run your game.
  3. You now cannot share your code between different projects, unless you add this plugin to every project.

Note that after speaking to the author, this has been changed for the next version. See below for more info

BAD: requires minimum of 400 pixels width

I’m going to give the author a free ride here: yes, it’s a silly bug, and yes it makes a big negative difference to editing.

HOWEVER … Unity’s engineers made it extremely difficult for us to control width, and adapt to it, when resizing custom Inspectors. Unless you’ve tried it, you would not believe how hard it can be!

The “solution” is for someone to write a new plugin that requires a minimum of Unity v4.6, and uses the new (fixed) GUI API built-in to Unity. But it would be a brave author who does that: currently only 25% of Developers are using Unity 4.6 or later. As a plugin author, you would lose 75% of your revenue immediately!

BAD: Undo support is incomplete

The interface in general for Dictionary is poor, and List isn’t great.

To be honest, I could live with this. I know it would cause some dataloss – stupid mistakes when we’re tired or rushed, human error that wouldn’t have happened with a better UI. But it’s still a big step up from Unity’s refusal to render Dictionary at all, and Unity’s poor editor for List.

Final conclusion: Buy or Don’t Buy?

To be clear: I didn’t use every feature. This plugin is a combination of multiple different, unrelated features and fixes. I’d prefer multiple smaller plugins that each do one thing (even if they depend on one shared backend), but I covered the ones that seemed most exciting to Unity Developers, and the ones that make a big difference to me.

It’s cheap, and there’s good stuff here. Over time, as Unity improves the underlying APIs, my biggest issues here might get fixed. In particular, if the author upgrades it to require a minimum of Unity 4.6, I can see this being a really useful tool.

My initial conclusion was: “but for me, I need structs, and I’m not willing to make every single file dependent on this plugin forever more”. I spoke to the author about this, and suggested a global “default to on / default to off” toggle – and he added it:

unnamedAIsccs

Just getting access to Dictionary and reorderable List is a major win, and to do it with no source-code changes is great. It’s possible you’ll hit problems with other 3rd party plugins that try to improve Inspectors – but off the top of my head, the only other ones are like AI, and you’d expect them to be mutually exclusive anyway.

More reviews?

If you have your own assets up on the Unity Asset Store, and want me to review them, send me a voucher. Or get the author(s) to.

I’ll only review assets I can actually use in a real project – the review might have to wait until I have a free weekend to try it out. But if that’s OK with you, send me an email (address at top of page).

PS: how much do you pay for your plugins?

As an aside: when I was considering the earlier version (before I got the info on structs, and before the global on/off toggle), I thought a lot about value/price.

I would have preferred to pay 2x as much, maybe as much a $70 or $80, to get a fully working version that does everything Unity does, and has no (or fewer) code-level dependencies. From what we see on the Unity3d.com forums, it seems most Unity developers would refuse to pay that, on principle.

(The principle being “I’m too poor/cheap/don’t value your work, even though it would take me months to do it myself”). If you want to change this, encourage your fellow Unity devs to pay more for plugins (and, of course, hold plugin authors to a high standard too)

Easy parametric animations in #Unity3d with code and curves

iOS forces you to use pretty animations: if you don’t tell it otherwise, it will use “ease-in/ease-out” curves to make things feel … smoother, less jerky.

Unity is made for programmers; changes you make to position, size, rotation, etc all happen instantaneously. By default, they won’t even animate, will teleport instead.

So … moving from “prototype with no animation” to “prototype that won’t hurt people’s eyes, and I can share”, what are some tips and gotchas?

Mecanim

Personal opinion, but … most of us are using it to get cheap bipedal walking animations. Which is fine, but a very small percent of the many use-cases for “animation during a game”.

So, I’m ignoring it here.

Playing an animation correctly

First off: don’t use Animation.Play( “anim-name” ) – this method is great for prototyping, but it throws-away the timing info you need later

You can workaround this by putting source-code into every single one of your Animations. Yeah. That works, but .. it’s as safe and maintainable as it sounds. For very complex anims, you’ll have to do that anyway, and it’s a great solution – but for small games it’s overkill.

Always load the AnimationClip

Animation anim = myObject.GetComponentInChildren<Animation>();
if( anim == null )
	anim = myObject.AddComponent<Animation>();

AnimationClip clip = anim.GetClip( animationName );
anim.clip = clip;

Now you know how long the anim takes – it’s “clip.length”

Applying Animations to GameObjects

Design flaw in Unity that we’re stuck with:

Animations OVERWRITE the object state, instead of MODIFYING it

i.e. a jumping animation that moves up and down … will reset your character to the origin, jump them up and down, and then teleport your character back to where they were standing. World’s biggest WTF in engine-design.

Official workaround:

  1. Create an empty GameObject.
  2. Parent your object within the new one.
  3. Apply the animation to the original object (the child).
  4. Re-write all your game-input, controllers, AI, etc so that it moves the new, empty, PARENT object.

Parametric Animation

That’s not quite enough.

In a game, almost all animation is parametric. It is very rare to find something that SHOULDN’T be tweakable via simple config file, NOR influenced by the player’s or AI’s actions.

Unity doesn’t directly support parametric animation; but they provide API calls and features that make it very easy to add yourself. If you know what they are…

Example: Jump with variable length

First, split your animation into two parts:

  1. Parametric part (in this case: how much ground-distance does the jump cover?)
    • You implement this as an AnimationClip, following Unity’s standard process / official docs.
  2. Static part (in this case: how high they jump, the curve of up and down movement (should look like acceleration: moves quickly at first, slower as it nears the peak, then fast again as it falls))
    • You implement this in code, using a co-routine. See next paragraph..

First, you write it without a co-routine, to test it works:

public void PlayJump( GameObject myObject, Vector3 jumpDistance )
{
	myObject.transform.position = myObject.transform.position + jumpDistance;
}

Works, right? Great. But it teleports you from start to finish.

Then you convert it to a co-routine, causing Unity to smoothly animate it. W00t! Here, you use Unity’s provided method for smoothly moving something over time: Vector3.Lerp() (google it if you don’t know what a “lerp” is, it’s used in almost every game ever written).

public void PlayJump( GameObject myObject, Vector3 jumpDistance )
{
	StartCoroutine( CoMove( myObject, myObject.transform.position + jumpDistance );
}

private IEnumerator CoMove( GameObject myObject, Vector3 finalPosition )
{
	float elapsedTime = 0, transitionTime = 1f /* spend 1 seconds moving */;
	Vector3 savedOriginalPosition = myObject.transform.position;

	while( elapsedTime < transitionTime )
	{
	myObject.transform.position = Vector3.Lerp( savedOriginalPosition, finalPosition, (elapsedTime/transitionTime) );
	elapsedTime += Time.deltaTime;
	yield return new WaitForEndOfFrame();
	}
}

Your jump should now combine a Unity Animation and a parametric / controllable distance.

But … you want the jump distance and jump animation to be synchronized. For that, you need the clip-length we grabbed earlier:


public void AnimateAndPlayJump( GameObject myObject, Vector3 jumpDistance )
{
	Animation anim = myObject.GetComponentInChildren<Animation>();
	if( anim == null )
		anim = myObject.AddComponent<Animation>();
	
	AnimationClip clip = anim.GetClip( animationName );
	anim.clip = clip;
	
	// now you know how long the anim takes - it's "clip.length"
	
	anim.Play(); // uses the new .clip
	
	PlayJump( myObject, jumpDistance, clip.length );
}

public void PlayJump( GameObject myObject, Vector3 jumpDistance, float duration )
{
	StartCoroutine( CoMove( myObject, myObject.transform.position + jumpDistance, duration );
}

private IEnumerator CoMove( GameObject myObject, Vector3 finalPosition, float duration )
{
	float elapsedTime = 0;
	Vector3 savedOriginalPosition = myObject.transform.position;

	while( elapsedTime < duration )
	{
	myObject.transform.position = Vector3.Lerp( savedOriginalPosition, finalPosition, (elapsedTime/transitionTime) );
	elapsedTime += Time.deltaTime;
	yield return new WaitForEndOfFrame();
	}
}

Now it’s perfect.

Then you try it in-game, and it’s about 10% slower than you intended. Easy, speed up the ani– oh, wait. Unity’s animation editor DOES NOT ALLOW you to speed up / slow down your animationclips. Ouch. Burn!

Controlling animation speed

You can change the speed of an animation itself, but it’s a bit non-obvious how to do it. You unintuitively iterate through the AnimationStates, and set their speed to the INVERSE of the ratio of speeds. Wat? Read the code:

public void AnimateAndPlayJump( GameObject myObject, Vector3 jumpDistance, float animationDuration = 0f )
{
	Animation anim = myObject.GetComponentInChildren<Animation>();
	if( anim == null )
		anim = myObject.AddComponent<Animation>();
	
	AnimationClip clip = anim.GetClip( animationName );
	anim.clip = clip;
	
	if( animationDuration > 0f )
	{
		/** Modify the animation-clip, for this animation only */
		foreach( AnimationState s in anim )
		{
					s.speed = transitTimeSeconds/overrideAnimationDuration;
		}
	}
	// now you know how long the anim takes - it's animationDuration
	
	anim.Play(); // uses the new .clip
	
	PlayJump( myObject, jumpDistance, animationDuration > 0f ? animationDuration : clip.length );
}

Very nice. Fully controllable animations, integrated with gameplay. Aw, yiss!

Editable curves for your Parametric animations

There’s a problem with the above: you make a beautiful jump, which arcs nicely through space, using Unity’s Curves in the animation window, but … the distance itself is constantly increasing. You can’t have the character squat, get ready, then jump – they will skid along the ground while squatting!

There are many obvious code solutions; they’re mostly wrong.

Instead, there’s a 1-line change + new variable (of type AnimationCurve). IF you do it this way, Unity gives you a powerful graphical editor for the PARAMETRIC part of your animation – IMHO it’s easier to use than the Animation window, which is a little tragic, but useful.

private IEnumerator CoMove( GameObject myObject, Vector3 finalPosition, float duration, AnimationCurve timingCurve = null )
{
	float elapsedTime = 0;
	Vector3 savedOriginalPosition = myObject.transform.position;

	if( timingCurve == null )
	{
		timingCurve = AnimationCurve.Linear( 0, 0, 1f, 1f ); // identical to a Lerp
	}

	while( elapsedTime < duration )
	{
	myObject.transform.position = Vector3.Lerp( savedOriginalPosition, finalPosition, timingCurve.Evaluate( (elapsedTime/transitionTime) ) );
	elapsedTime += Time.deltaTime;
	yield return new WaitForEndOfFrame();
	}
}

This. Is. Awesome.

Animation and Physics

Read Sampsa’s Excellent short post on this topic, with do’s and don’ts, and explanations.

Also: run the webplayer demo he included there! It’s a wonderfully quick way to see for yourself what these (undocumented) core features in Unity actually mean in practice.

Net changes: enable Kinematic while Animating

Depending on your situation, you may want to use some or all of Sampsa’s improvements. But at the very least, you’ll want to switch to Kinematic during your animation (so that Unity doesn’t do something dumb, like override the animation with a falling-due-to-gravity).

NB: if you want the animation to play *while falling*, you’ll have some fun times. You can’t re-use the official Parenting trick, because you’re only allowed one set of physics / RigidBodies within a single hierarchy of parent/child/grandchild/etc. Bummer.

public void PlayJump( GameObject myObject, Vector3 jumpDistance, float duration )
{
	/** c.f. Sampsa's article, but generally you want to do this while you're animating */
	myObject.GetComponent<PlayingCard>().isKinematic = true;

	StartCoroutine( CoMove( myObject, myObject.transform.position + jumpDistance, duration );
}

private IEnumerator CoMove( GameObject myObject, Vector3 finalPosition, float duration, AnimationCurve timingCurve = null )
{
	... // rest of method here

	/** re-enable physics so it can be knocked around, stood on, etc */
	myObject.GetComponent<PlayingCard>().isKinematic = false;
}

…but you PROBABLY want to enable “animatePhysics” too (c.f. Sampsa’s demo).

A Whiteboard Xmas Card for everyone

What can you draw with a whiteboard, if you’re not an artist? Let’s see..

Many of my friends live on different continents. It was too late to post cards, and I was staring blindly at my whiteboard when I had an idea: A picture for everyone, photographed, emailed … Then wiped clean. A transitory, ephemeral, virtual gift made out of something physical and real.

(there’s a background to this, see below the images)

PS: apologies for variable quality – I was doing these as fast as possible, trying to get them out same day (Xmas Day).

IMG_20141225_224459 IMG_20141225_225137 IMG_20141225_230807 IMG_20141225_231300
IMG_20141225_232047 IMG_20141225_233613 IMG_20141225_234827 IMG_20141225_235750
IMG_20141226_000710 IMG_20141226_012840 IMG_20141226_013834 IMG_20141226_014528
IMG_20141226_020551 IMG_20141226_021514 IMG_20141226_022811 IMG_20141226_030250
IMG_20141226_031039 IMG_20141226_032140 IMG_20141226_033113 IMG_20141226_122938
IMG_20141226_123945 IMG_20141226_125359 IMG_20141226_133850 IMG_20141226_134557
IMG_20141226_135051 IMG_20141226_155430 IMG_20141226_160437 IMG_20141226_220730
IMG_20141226_222932 IMG_20141227_172428 IMG_20141227_174607 IMG_20141228_171110

If you didn’t get one, well … Maybe you should keep in touch more, my friend!

But seriously: I’m not finished yet. Watch your inbox.

Background

This Christmas, I did my first serious drawing/painting in 15 years, as a gift for someone. I was surprised (actually: stunned) how well it came out. Unfortunately, it wasn’t appreciated.

I wanted to make something positive out of it, anything. I’d poured too much time into that, and too much care, to write it off and move on.

Here’s the results. I took the theme of my original hand-made card: an image specific to the recipient, something that they (and their close friends) would recognize and understand immediately.

There’s a few that tie obviously to well-known people in Web, Education, Games industries.

Unity’s failure as an Entity System, example 1: Selecting things

Entity Systems in Unity… some examples of the problems

This is a new series of blog posts, where I’m going to document specific ways + concrete examples in which Unity fails (sometimes spectacularly) as an “ECS” game engine.

I like Unity; but the core architecture (which is very old) is a half-assed ECS, and if we’re to upgrade it into a really good, modern, architecture … we first need to understand exactly where it’s failing, and why.

So, let’s start with Selecting Things…

Background

Game

A 2-player card game where each player normally draws a card each turn, and then plays one or more cards. Sometimes (e.g. when discarding because “too many cards in hand”) they have to select more than one card at once.

Initial version of game will be 1-player versus computer. Very soon: want to upgrade to OPTIONAL 2-players on-screen, with one using the mouse, other using gamepad. Ultimately, want to also add over-the-internet multiplayer (which ends up interfacing with the codebase in a very similar way to the original 1-player-vs-computer, so we can ignore for now).

Code Situation

Player taps card. Now … we must inform many other scripts and independent systems, so they can choose to eg.

  • ignore (if invalid for current state of game)
  • react (e.g. zoom to display the card more clearly)
  • “select” internally (side-effects include: deselect other things)
  • advance the game (if it was waiting-for-input)
  • ..etc

Problem

What/where do you send the “player clicked on a card; can some piece(s) of code PLEASE deal with this??!!?” ?

Addendum

In Unity, only the low-level “card” object can sensibly detect it has been clicked on.

Both Unity’s Physics (old) and EventSystem (new) effectively force this via their core design. Both require you to attach scripts to the physical objects that will be clicked.

In practice, this is bad for OOP (and bad for ECS too). When there’s e.g. 100 cards all of which must be separately clickable, your code is really in the wrong place. You don’t want cards (which sometimes are in a deck, sometimes on the table, sometimes “virtual” (perhaps in a virtual, unopened booster pack etc)) … to be containing all the GAME logic required to know what to do when they’re touched!

Classic Entity System / ECS solution

  1. Create a SelectedByPlayer component
  2. Add it to the card
  3. Sit back, and relax. Code that cares about input will scan “get me all SelectedByPlayer components” on each frame, and react accordingly

Everything works automatically; any System/Processor that’s “waiting for a selection”, or “making render changes when selections add/remove”, etc … will pick up what it needs, with no work.

You can add new input-handling routines simply by adding them. That’s all. No other changes needed.

Attempting to solve this in Unity

UNITY 4.6/5.0

Maybe … NB: I’ve only just started using the new GUI/EventSystem in Unity 4.6+ .. create a custom Input event, and a custom InputModule that can understand that, and then put all the code for ALL affected systems/processors into one monolithic ugly, hard-to-maintain script from Hell.

I suspect that this code will be quite maintainable w.r.t. adding new Input hardware in future – e.g. allowing mouse vs gamepad. But it’s going to suck at the rest, all the business-logic and handling. Which is going to be > 95% of the maintenance cost.

You get one small benefit: you can separate-out different inputs (click versus drag). Sadly, in reality: 95% of game actions will be simple clicks. This is one of those “the code architecture sounded great in academic situation, but reality is so unbalanced, it works out less well in practice” situations.

This is a classic OOP solution, and has the downsides. The only significant benefit I can think of is that it’s a “known” Hell: if you’ve done a lot of OOP game coding, you’ll be familiar with the pain you’re going to run into.

UNITY CLASSIC

Make a new class “CardClickManager” whose sole purpose is to reference all the possible bits of OOP code that “might” need to react, and which has to be updated by hand EVERY TIME you modify, add, or remove some input-handling code ANYWHERE else in the codebase.

Pretty much the same as above, except it:

  • … is even more simplistic (no event-dispatch systems)
  • … making it even harder to maintain + debug
  • … is slightly more proprietary

Conclusions / Improving Unity

So far, I cannot think of any sane, maintainable solution here other than “suck it down and use OOP, and suffer forever”, or “throw away Unity GameObject/Component, and implement a proper ECS”.

That’s fine, though. That’s the point of these posts – to hilight situations where there’s no good middle-ground, where we must create the data-centric, cleanly-separated architecture of a modern ECS.

Counter-ideas very welcome! Comment away, guys…

How much should you use a Scripting language when writing a Game?

Ask 10 game developers if you should use more script code or less, and you will get 11 different answers. They are all correct: it’s very situation-specific. Use of scripting languages is highly dependent on the humans and the practical / project-management issues.

Why?
Continue reading

Makerbot Replicator2 Upgrade: new fan duct

I reviewed a whole bunch of these on Thingiverse, and the best combination of simplicity and effectiveness appeared to be this one:

…but you want to print these at 0.1mm layer height, or less, and that’s difficult with the model above. So I tweaked it a bit:

NOTE: The WordPress authors can’t be bothered to implement safe/secure uploads; instead, they block ALL uploads (which is very stupid and doesn’t solve ANY security problems). This file has to be renamed when you download it. Stupid, stupid, stupid programmers.

WordPress Is CRAP.stl

Changes

The original model has two small circular screw-holes. Makerbot printers can’t print these very well – Both the official slicer, and the main commercial / open-source slicers get it wrong and print the holes in a bad way (untethered; it’s an obvious heuristic to fix, but no-one has implemented this yet). Net effect: the holes slide about during layer 2, and usually detach, and ruin the print.

To fix this, I cut a slice out of each hole, making them into hooks. This follows the design of Makerbot’s original fan duct, and makes the print easy to do even at high speed and low layer-height.

3DPrinting tips: cooling, fans, and PLA temperatures

This is hugely important to 3D printing, and generally: no-one talks about it online (at least, not with any authority: more “blind leading the blind”). Which is silly: the engineering behind this is obvious (and it’s often obvious from looking at a 3D printer that it’s been under-engineered in this critical area).

NB: I don’t know which parts of “correct, obvious” cooling are blocked by stupid patents that should never have been granted. That might excuse the poor design of most printers today. Might.

My experience so far is that “more cooling of printed object is better”. But that’s an over-simplification…
Continue reading

Towards a Unity3D ECS: what GUI? What features?

This year, one of my goals was to build a sane, powerful, viable Entity System / Entity-Component System within Unity3D. Something I could build current and future games on, and save a lot of dev-time (both in ease-of-use and in easily adding missing features that I wish Unity had).

So, progress?
Continue reading

Site disappeared? Apache ARGH!

Transferring server to new home.

Allowed it to install latest versions of core software.

Turns out … the lovely people at Apache have made major site-breaking changes to their config system, so that upgrading WILL break existing sites.

Took an hour to discover that :(.

Epic saga of Unity3D deserialization of arbitrary Objects/Classes

(a summary writeup of the things I tried – based on this Unity blog post: blogs.unity3d.com/2014/06/24/serialization-in-unity/ – to get Unity 4.5 to correctly serialize/deserialize simple object graphs)

UPDATE: I belatedly discovered that EditorUtility.setDirty() is fundamental to Unity; if you have even one single call of this missing, Unity will corrupt data when you save the project. In some of the cases below, where everything was fine EXCEPT on fresh startup, I suspect that was the real problem: a missing setDirty(). I thought this method was cosmetic, but tragically: no.

This is not easy to read, it’s bullet points summarising approximately 2 weeks of testing and deciphering (plus a month or so spent learning-the-hard-way the things that are in the Unity blog post above. Note that the blog post only came out very recently! Until then, you had to discover this stuff by trial and error)

Serializable-thing:

– example on blog won’t work if e.g. your Class is an object graph.
– e.g. class Room { List doors; }. class Door { Door otherDoor; }
– …can’t be serialized. Can’t be stored as a struct, unless you have a GUID per “Door” instance. That’s no surprise, didn’t bother me: This is standard in most serialization systems.
– So we go on a quest to create a GUID…

GUID1:

– class Door : ISerializeCallback { Door otherDoor; public string guid = Guid.NewGuid().ToString(); /* use OnBefore / OnAfter callbacks to store the guid of the other door / find the door from guid */ }

Unity inspector lists:

– if you add an item to the list, 2 things corrupt your data:
1. all existing objects are NOT MOVED, but are CLONED into new list. This breaks our GUID.
2. the new item is a carbon-copy clone of the old – so it ends up with the SAME GUID (ouch)

GUID2:

– class Door { [SerializeField]private string _guid = Guid.NewGuid().ToString(); }
– now the inspector no longer clones the guid … BUT … instead it sets it to null.
– it seems to run the constructor, then use serialization to delete all values it finds

GUID3:

– class Door { private string _guid = Guid.NewGuid().ToString(); public string serializedGuid; /** use serialize callbacks to maintain serializedGuid */ }
– Disable the Editor’s list-renderer: it has at least two major bugs that corrupt data. Use the UnityEditorInternal.ReorderableList.
– NB: ReorderableList – with no customization – does not have either of the two bugs I saw with built-in Inspector’s lists.
– NB: as a bonus, with RL, we can avoid the “run constructor, delete all data, deserialize, reserialize” cycle, and directly create a new, blank instance with a safely generated – FRESH! – Guid.

Ctrl-D in Editor:

– breaks this, because we have no idea if a deserialize event comes from “ctrl-d” or from “read back from disk” (or from a prefab instantiating into the scene).

GUID4:

– class Door { public Room serializedRoom; private string _guid; /** use callbacks to peek into the serialized room, and use the guid as a “local ID within this room” */ }
– Because we’re now leaning on Room (which is a GameObject) to provide part of our GUID, in theory we don’t care about prefab/ctrl-d/etc — the code inside MonoBehaviour will automatically separate-out those cases for us.

Work with everything except prefabs, I think

– eventually gave up, removed the GUID completely, and changed game design to only allow ONE door to connect any pair of rooms. Yes, I was desperate!

THIS WORKS! Until you restart Unity:

– restarting unity causes this to deserialize on a different thread, and now you’re NOT ALLOWED to peek into the serialized room. You cannot use it as a substitute ID. You get crashes at load-time).
– …apart from that, this works fine. We have a solution that worked for ctrl-D, for prefabs.

GUID5:

– class Door { public Room serializedRoom; private bool _isUnityStillOnBackgroundThread; /** use the bool to say “deserialize happened but the data is NOT VALID, DONT RUN ANY METHODS” */ }
– …also use an AutoRun script with [InitializeOnLoad] and “EditorApplication.update += RunOnce;”
– …the autorun script waits for Unity to startup, then goes and Finds all objects, and finds all Rooms, all Doors — and does the fixup.

Fail, but can’t be debugged:

– I have no idea why this failed. It appeared perfect. Simply moving code that worked inside the deserialize (but crashed because it was run on “wrong” thread) out into the post-launc RunOnce method … silently fails. No errors, but no data.
– NB: this is impossible to debug, because we can’t even call ToString() on the deserialize method :(.

Conclusion

Give up. Make 10,000’s of Component instances instead. Waste memory, kill performance (especially at runtime: imagine how bad the AI’s going to be iterating over this!) but hey – IT WILL WORK. Because it leans on the built-in hacks that MonoBehaviour has had for years (which we’ve all been using millions of times a day without realising / appreciating ;)).

Debugging A* Pathfinding in Unity

I needed fast, efficient, … but powerful, adaptable … pathfinding for my hobby project. My minions have to fly, walk, crawl, teleport, tunnel their way across a procedural landscape. Getting to that point has been tricky, but the journey’s been interesting.

We want something that intelligently routes creatures around obstacles, and picks “shallow” routes instead of scaling cliffs (or vice versa for Giant Spiders etc). Something like this:

Screen Shot 2014-08-10 at 20.09.36

Continue reading

OpenGL ES 2 – Video on iPhone in 3D, and Texture-Map sources

This is a blog post I wrote 6 months ago, and my life got too busy to finish it off, finish testing the code, improving the text. So I’m publishing this now, warts and all. There are probably bugs. There are bits that I could explain better – but I don’t have time. Note that the code is ripped from apps where I ACTUALLY USED IT – so I know it does work, and works well!

In brief:

  1. Using different “sources” of textures in OpenGL, not just images!
  2. Using CALayer’s as a source — allows for video in 3D!
  3. Using “Video straight from the video decoding chip” as a source – faster video!

Continue reading

Review: good SMS apps for Android

Why do we need this?

In a bizarre move, Google deleted the perfectly good SMS app from Android. Yeah. Hmm. Well, read this TechRadar piece for some thoughts on that.

Sadly, Google’s corporate policy is that the consumer is always wrong: you’re not allowed to simply “use the app I already had, that worked great”. Time for a trip to the Android App Store…

I tried:

Quick review of each

TextSecure

  1. does what it’s supposed to: show all conversations, send texts
  2. uses the “standard” view of SMS that we’re all accustomed to

…Deal breaker

  1. there’s no widget. Without a widget, you can’t get your phone to show “at a glance” new and recent SMS texts on the home screen / dashboard

Evolve SMS

  1. has a widget that works

…Dealbreakers

  1. enormously unpleasant “forced swipe” control system. I’m not sure why. Maybe: “Facebook did it, and it sucked, so Facebook stopped. But we want to be Facebook, so let’s copy their failures!”
  2. the back button is actually broken. This is a core feature of Android, one of the biggest improvements compared to iPhone. And Evolve broke it. (Sad face).
  3. the widget can’t be resized. Fixed size widgets are a real pain – you can’t place them where you want, cant put the things you want on same screen, can’t control the info displayed

HelloSMS

  1. basically works

…Dealbreakers

  1. stupid forced-swipe control (see above)
  2. On first start, requires you to swipe in wrong direction
  3. no widget

Go SMS Pro

  1. has a widget!
  2. basically works, but ugly

…Dealbreakers

  1. The widget WILL NOT DISPLAY incoming/recent texts. Instead it displays ONE text, and you have to hit buttons to “scroll” the widget to next / previous text. Wat?
  2. The app hangs if it’s not your “default SMS app”: you type something, it hangs. No other app had this problem, they all did a popup explaining, including a single-tap “fix this” button.

chompSMS

  1. has a widget
  2. looks really nice

…Dealbreaker

  1. The widget … is simply “an ugly resized version of the app icon” … and it does nothing. Seriously, a developer chose to add this feature, and implemented … nothing. Wat?

Summary / Winners

TextSecure is a perfect recreation of ” an SMS app that just works, the way its supposed to” … Apart from the lack of widget (essential!). It even has Apple iPhone style “free text messages to other users of the app”. If they’d fix that missing widget, it would be worth paying for…

chompSMS is very much like TextSecure, perhaps slightly prettier (personal preference). But the broken widget is just as bad as TextSecure’s, maybe worse. And it lacks the “free SMS” mode and “secure SMS” modes of TextSecure.

Evolve has the only working widget (essential!). But … you’ll frequently exit the app unintentionally when you hit the back button. And it’s unusable unless you like “swipe all the time to control UI instead of using the back button” behaviour.

Final thoughts

The rest … are not winners. I’m using TextSecure for now. When people say “people on Android don’t buy stuff”, partly it’s because the apps are incomplete: most of these apps haven’t been fully developed (how can you have a broken widget? Why did you launch without a widget? etc).

NB: as a developer, I can attest that “adding a widget” is very easy. It’s stressful the first time, and then you read the docs and examples, and realise “wow! this is going to be super quick to implement!”.

World-exploration game, done differently

Inspired by Markus / @notch, and how he got MineCraft going in the early days, I’m live-prototyping a game idea I’ve been thinking about for ages. It’s about exploring a landscape … where cities affect dungeons, and dungeons affect cities.

(this is stress-relief for me, an “evenings and weekends” project. By day, I’m helping Schools teach children to program, but that’s HARD (no investors, lots of costs – at the moment, I get paid nothing))

Play in web browser here (very early prototype!)

Screen Shot 2014-07-25 at 12.31.23

July 2014

Current build focusses on the “City building” interface. Initially, you won’t be building cities, you’ll be building small camps / trading forts, etc. So this lets me play with the interface, the scale, the rendering, etc. Make sure it’s fun.

Create something – but take screenshots! Because there’s no “save” yet. Super-early prototype.

Long term gameplay

  1. Explore a huge landscape in FPS
  2. Any location, “create a camp”, and it switches to the isometric view you see in current demo. Build yourself a home/fort/etc.
  3. Fast-travel between locations, but this triggers “random encounter” events … or run between locations manually.
  4. Turn-based / DungeonMaster style dungeons are randomly generated near to each camp. Explore the dungeons for resources and to level-up.

Unlike e.g. Skyrim … when you find an interesting location, you can’t fast-travel to it. You have to build a camp next to it, and fast-travel to that. But your camp can be overrun/destroyed/stolen while you’re away.

So … you’ll be building (and maintaining) a lot of bases around the world. I want to be sure that base-building is easy and fun, even after you’ve done it lots of times already, before progressing with the rest!

(I’m trying to make it “repeatably fun” by having the landscape HUGELY affect your base design)

Webmail on your Debian server: exim4 + dovecot + roundcube

95% of linux configuration on Debian servers is simple, well-documented, well-designed, easy to do, with only a tiny bit of reading of docs.

Sadly, “making email work” is most of the 5% that’s: nearly impossible, very badly designed, badly packaged/documented. This OUGHT to take an hour or two, in practice it takes ONE WEEK to setup. WTF? In 2014? Unacceptable!

So I took several incomplete/broken guides, dozens of pages of help and advice, and synthesized this complete, step-by-step guide. This should get you the webmail you actually want (!) in an hour or less.

Continue reading

Your Pricing Models dictate your business success

Many businesses underestimate the power of a clever Pricing Model. I’m selling a new product at the moment (we’re helping schools teach children to program), so pricing models occupy a lot of my head right now.

Startups are so unsure of what model to use that they often say “anything, so long as we get sales”. They usually focus on simplicity (with a “new” product, a complex pricing model can tip people over the edge and make them “give up” on buying).

Which is fine, but a cunning pricing model can work wonders.
Continue reading

How to tidy your Unity code by putting it in a DLL

The importance of Re-use

Here’s a story that may sound familiar:

You downloaded Unity, watched some tutorials on YouTube, and had a physics “game” running the same day. Excited, you started writing the game you’ve always wanted to make. Possibly – bitten before when trying this with GameMaker etc – you thought to organize your source code: folders, subfolders, logically-named scripts, etc.

Fast-forward a few months, and you have 50 scripts in 40 sub-folders, some of it re-usable, some of it hardcoded for your game. Hoooo-Kayyyy… Well, it’s not too bad. And then a new opportunity comes along – a paid contract, a game-jam, a collaboration with a friend – and you want to re-use some code from your main project. You look at the folder structure, you look at how intertwined it’s all become … and you weep.

Without re-use, what seemed like an “easy” project becomes just a little too much work, and you never finish it. Back to square one :(.

Code re-use in Unity

There are five major aspects to code re-use when making Unity apps. Most of these are shared with general programming, but these are the ones I’ve found *especially* important when doing Unity development.

Good names

The best way to get good at naming things in a program is to focus on “what makes a bad name”, and “Don’t do that”. e.g.

  • If you have to open a Script to remember what it does … it has the wrong name.
  • If you keep typo’ing the script when referencing it in other scripts … it’s the wrong name
  • If your script is more than a thousand lines long … it’s the wrong name AND you’ve put too much junk in there; split it!
  • If you can’t find a script, because you can’t remember which folder it’s in … the folder name is wrong, AND the script name is wrong (should have been a name that forced you to put it in the right place first time!)
  • …etc

Renaming scripts in Unity is a minor pain: you rename it, then you have to close the file in MonoDevelop, re-open it, and (assuming it was a C# class) rename the class in source-code too. (I keep hoping latest Unity will do this automatically, but I’m a version behind at the moment).

We need Sub-folders. Lots of Sub-Folders

… you can never have too many. Give them good names, though!

De-couple your code

Ah, now it gets tricky. The art of decoupling takes much practice to master.

Decoupling is why C# (and Java) has the “interface” keyword. The concept is much easier to understand after you cocked it up, written code you can’t re-use, because everything’s too inter-dependent.

“I can’t just copy/paste that script to my new project, because it references 3 other scripts. Each of which … references another 12. ARGH!”

Unity itself doesn’t use Interfaces (though it really ought to!) – and you have to use a little ingenuity to use them yourself (Google it, it’s only a few small caveats). But C#-interfaces simply give you a compiler-compatible way of decoupling: you have to design your classes as decoupled to start with. Again, google this and ask around – it’s too big a topic for me to do justice to here!

Package your code, so you can re-use it

Libraries. This is why The God Of Programming invented Libraries. So, how do you do a Library in Unity?

Libraries in Unity: the easy DLL

There are two kinds of DLL’s:

  1. Real DLL’s, as used by Real Men, who write all their code in C++
  2. Fake DLL’s, as used by the rest of us, who just want an easy life so we can focus on making our game

A DLL is a great way of packaging code – it’s a very widely-used standard. So, Unity uses DLL’s for this (good move) – but if you google “Unity make DLL” you’ll get distracted by the huge complexity and depth of C++/Unity integration, and you don’t need any of it. Instead, you’ll be doing “DLL light”, which is easy.

But, as with most Unity features, it’s almost entirely undocumented. And, out of the box, it will fail. For bonus points, Unity will give you completely the wrong error message when it goes wrong. Yay!

Step 1: write a Unity script in Unity

Do something simple. I wrote a class that makes random numbers, following XKCD’s advice:

using UnityEngine;

/** In Unity 3, you cannot have namespaces. So comment out this next line. Unity 4 is fine */
namespace MyTestDLL
{
	public class DLLClass
	{
		public static int GetRandom()
		{
			return 4;
		}
	}
/** In Unity 3, you cannot have namespaces. So comment out this next line. Unity 4 is fine */
}

Make a second script that uses that first one, e.g.

using UnityEngine;

public class TestScript : MonoBehaviour
{
	void Start()
	{
		print( DLLClass.GetRandom() );
	}
}

…attach it to a GameObject, check it works.

Step 2: follow Unity’s docs on creating and using a DLL

You’d think this would be enough, but it isn’t. However, the docs are simple, direct, and I found them easy to follow.

So http://docs.unity3d.com/Documentation/Manual/UsingDLL.html = read this and do what it says

NB: they write a slightly more complex script to use than mine, with but whatever. The idea is the same.

Step 3: Use the namespace, Luke. And Interfaces. And …

Now that your DLL is compiling/building in MonoDevelop … you are no longer stuck with Unity’s arbitrary rules and restrictions! The world is yours!

(so, even in Unity 3, you can now use the namespace. Which makes it MUCH easier to keep your code well-organized ;))

Step 4: What about the [square brackets]?

These Just Work ™ exactly as they did in Unity scripts. e.g.

using UnityEngine;

namespace MyTestDLL
{

/** Hey! Look! Unity editor-features ... coded outside of Unity */
[ExecuteInEditMode]
[System.Serializable]
	public class DLLClass
	{
...

Step 5: Editor extensions, editor scripts, editor GUIs, etc

This is where it breaks. If you had any Editor scripts (which, in Unity, MUST be stored in the “Editor” root folder, or one of its subfolders), you can include them in your DLL – but they won’t work.

Worse, when you trigger them (e.g. by selecting a GameObject that did custom editor rendering), you’ll get:

Error: multi-object editing not supported !

…at least, you do in Unity 3.x. Fixed in 4.x, I suspect? But I haven’t gone back to try it since I fixed the bug :).

There is some mumbo-jumbo on the internet (and Unity forums) about complicated workarounds, notably courtesy of AngryAnt (with a Jan 2014 post here, with some extra info worth reading but NOT required!). But these are long-since outdated and unnecessary. The fix is very simple: we must create TWO DLL’s!

  1. DLL #1: the one we already had
  2. DLL #2: will contain ONLY the editor-scripts, and we’ll drag/drop it into Unity’s “Editor” folder.

This is extremely logical, simple, and easy to remember. And it works beautifully! But .. how?

Step 5a: Upgrade MonoDevelop project to output not one, but two, DLL’s

First, right-click on the top-most item in MonoDevelop’s “Solution” panel, and select “Add New Project…”:

Screen Shot 2014-05-24 at 20.54.53

As you did earlier, choose “Library (C#)”. I recommend naming this “SomethingSomethingEditorScripts” (where “SomethingSomething” is your library name, which you used for the first DLL).

Second, you need to edit the References (as you did with first DLL), and this time repeat the steps and add ALL of:

  • UnityEngine.dll
  • UnityEditor.dll
  • AND: instead of the “.Net Assembly” tab, use the “Projects” tab and select your main DLL/library. It should be the only option

That gives you something like this:

Screen Shot 2014-05-24 at 20.58.22

…see how I have two “projects” in MonoDevelop, one which just uses normal Unity stuff, the other which additionally uses Unity Editor stuff? And the second one “references” the first, so it can see/use/create the classes and methods from the first one.

Step 5b: Put the DLL’s in different places

Build, and find the output files. The first project/DLL will still only be making one DLL, but the folder for the SECOND project/DLL will conveniently build BOTH projects and contain BOTH DLL’s.

Make sure you put one DLL “anywhere except Editor” and the other one “in Editor, or a subfolder of Editor”.

Finally, create some GameObject’s, open up the DLL’s in Unity’s Project view (expand the triangle) and drag/drop the Scripts onto your objects as desired. Click on them in the Scene view, and all your OnGUI, OnGizmos etc methods should run exactly as normal.

Step 6: Rejoice!

Now you can share your code with other Unity projects simply by drag/dropping the 2 x DLL’s into a new Unity project. BOOM!

Beautiful! Easy, simple, impossible-to-screw-up ;). That’s how I like my code re-use…