Blog,code,iPhone,Unity

My thoughts on Unity Free29 Oct

Just recently, like, very recently (maybe a few hours ago) Unity released their base-level product, Unity Indie for free.

This is pretty huge news for the game development community. It is, as they say (and forgive the pun) a Game Changer.

If you don't already know, Unity is a very powerful tool for rapidly building games. (it is billed as a 3d game engine, but it also works quite well for 2d games) One of the many features of Unity is the ability to take the game project you have built, and with the click of the mouse, build a version for the mac, a version for the pc and a version that runs in a web browser. This is excellent for distributing your game but it has other side benefits as well. I collaborate with people all over the world, and we use the in browser games to share our ideas quickly and easily, not to mention it is much easier to get your testers to test out your prototypes if all they have to do is open a browser window.

Before now, the indie version was not very expensive, less than $200 or so, but now that it is free, I think we will see a flood of new and interesting games come out in the coming months.

What does this mean for indie game development?

Well, the obvious thing is that we will see a ton more web based titles, probably lots of crap, but there will always be a few gems in there.

I think that Flash development will start to see a big challenge from the Unity guys. I know a ton of flash guys who have been eyeing unity for awhile now and this will most likely push them over the edge. dont get me wrong, flash is a great tool, and it is great for making games, but it is not a game-building-tool. Unity is designed from the ground up to make games. Here is a good post to read if you a flash dev who is on the fence: http://diamondtearz.org/2009/01/14/10-reasons-for-flash-developers-to-learn-unity-3d/

The even bigger news for me as an iPhone developer is that I think many many more people will start to use unity to build games for the iPhone.

Now, Unity iPhone Basic (the cheapest iPhone license) is still about $400. And some of the zero budget indie developers might have to think twice about that kind of money (it is totally worth it, trust me) But now you can download the Unity Free and prototype your game, or release a web version or just get to know unity and then be ready to port it over to the iPhone version. We are doing that right now with 'Mole' and I will be blogging about what it takes to move a prototype level game from the desktop version of unity into a working iPhone version.

I will also be interested to see how this effects the other iPhone game-focused APIs like cocoas2d. Cocoas2d and the like are still free (so still $400 cheaper than using unity to develop your game) and if you are building a 2d game it makes a lot of sense to start with cocoas2d, but I can tell you from my personal experience that building a 2d game with unity is very easy and if your time is worth anything to you then the $400 investment to upgrade to iPhone Basic is well worth the money. Also, I cant stress this enough, you can now prototype your game in Unity for free. Even if you then decide to use cocoas2d to build the deployment version (a few reasons you might want to do this, more on that in a second) you can still do a rapid prototype with Unity to figure out all your gameplay mechanics and decide if the game is fun or not.

So, Unity is great, but what are the downsides?

Well, in terms of desktop or web development, there aren't any real downsides. Go get a copy and start making games.

In terms of iPhone development there are a few caveats.

First off, as i have mentioned, it is not free. But $400 is very cheap for what you get.

The biggest issue with using Unity Basic (and to some extent this applies to the pro version as well) to develop iPhone games is that your app size will not be under 10M (which is the size limit for apps to be able to be downloaded over the cell network). For the most part this is not a big deal, most games with any amount of depth tend to be bigger than 10M no matter the development tools used.

However, the casual games that you are trying to sell for $0.99 and you want to be an impulse buy, and so you want them to be less than 10M, these are nigh impossible to make with Unity. Why is that? Well, the unity engine is very capable, comes with all sorts of great things like built in physics, scripting, shaders, and lots of other goodies, but all that comes at the cost of size. If you spring for iPhone Advanced then you can strip out parts of the engine you are not using, and possibly get under the 10M mark, but this is a very hard thing to do.

My advice: even if you are looking to build small casual games for the iPhone, I would still suggest you get the now free Unity and prototype with it. Then once your game is working fall back on one of the other frameworks like cocoas2d to build it. However, if you have even an inkling that your game will exceed the 10M limit, then just get the iPhone version.

Cheers!
-B

Blog,code,iPhone,Unity

UIWebview overlay for Unity3d on the iPhone24 Sep

I just wrote a big post about how to open up a UIWebView overtop of the unity game engine. This is a good way to add Playhaven integration to your app, as we are doing with Snowferno. Anyway, I posted it on the Snowferno development blog:

http://www.snowferno.com/2009/09/23/playhaven-unity-and-snowferno/

Check it out if that sounds like something you might want to do.

Cheers!
-B

Blog,code,multitouch,Unity

xTUIO updates07 Sep

This last weekend I spent a ton of time with Unity3d and the uniTUIO project.

One of these days I will figure out how to cross-post to all the various blogs and things I am currently contributing to, but for now I will just throw some links out there:

There is the link above, that goes to the initial blog post.

http://xtuio.com/blog/2009/09/06/more-sneak-peeks/ is a post about the two layout managers that are 'done' so far.

http://xtuio.com/blog/2009/09/07/unittuiomolecules-project-now-with-more-movies/ shows the newly added movie support and the content switching buttons.

In any case if you are into the multi-touch surface thing, then go check them out. Otherwise, you can safely ignore them.

Cheers!
-B'

Blog,code,Unity

Unity tip for the day #2: simple notification server06 Sep

If you are used to writing code in cocoa like I am, then you have probably become quite addicted to much of the handy API features of cocoa, things like the NSNotificationCenter. .NET and c# might have something like this, but searches for 'notifications' turn up a whole bunch unrelated stuff, so I wrote my own:

BBNotificationServer.cs.zip

Just attach this script to a Game Object ( I usually have at least one empty object that is just my holder for all the scene manager scripts.) and you can utilize the notification services.

Here is a quick rundown of how it works:

First off, we have a BBNotificationList class at the top of the file.

 
public class BBNotificationList {
 
	private ArrayList objectList =  new ArrayList();
 
	public string notificationMessage = "";
 
	public void addObserver(GameObject obj)
	{
		if (!objectList.Contains(obj)) objectList.Add(obj);
	}
 
	public void removeObserver(GameObject obj)
	{
		if (!objectList.Contains(obj)) objectList.Remove(obj);
	}
 
	public void sendNotice()
	{
		if (notificationMessage == "") return;
		foreach ( GameObject obj in objectList ) {
			obj.SendMessage(notificationMessage,SendMessageOptions.DontRequireReceiver);
		}
	}
}
 

Just a very simple container object that holds a list of GameObjects and a 'message'. When the sendNotice() method is called, then each object in the list gets sent the message. Simple.

Next we have the 'server' which is roughly analogous to the NSNotificationCenter.

 
 
public class BBNotificationServer : MonoBehaviour {
 
	private static BBNotificationServer sharedInstance = null;
	private ArrayList notifications = new ArrayList();
 
	// This defines a static instance property that attempts to find the manager object in the scene and
    // returns it to the caller.
    public static BBNotificationServer instance {
        get {
            if (sharedInstance == null) {
                // This is where the magic happens.
                //  FindObjectOfType(...) returns the first AManager object in the scene.
                sharedInstance = FindObjectOfType(typeof (BBNotificationServer)) as BBNotificationServer;
                if (sharedInstance == null)
                    Debug.Log ("Could not locate a BBNotificationServer object. You have to have exactly one BBNotificationServer in the scene.");
            }
            return sharedInstance;
        }
    }
 

We are using a singleton pattern here, so you will need to have the script attached to something in your scene. Once you have that then you can get a ref to the server from any other script in the scene like so:

 
BBNotificationServer  theServer = BBNotificationServer.instance;
 

or just make calls on it directly like so:

 
BBNotificationServer.instance.postNotification("DoSomethingNotification");
 

OK, so the first thing we need to do is be able to add and remove 'observers'. If you are unfamiliar with the notification center from the cocoa API, then an 'observer' is simply an object that wants to be notified by a specific notification.

 
 
	public void addObserver(GameObject obj, string notificationMessage)
	{
		BBNotificationList theList = this.listForNotification(notificationMessage);
		theList.addObserver(obj);
	}
 
	public void removeObserver(GameObject obj, string notificationMessage)
	{
		BBNotificationList theList = this.listForNotification(notificationMessage);
		theList.removeObserver(obj);
	}
 

Again, fairly simple, we have a private method that returns the list for a specific message (and makes a new one if there is not already one) and then we just call the add/remove methods on that list.

Here is that private method:

 
	private BBNotificationList listForNotification(string message) {
		foreach (BBNotificationList list in notifications) {
			if (list.notificationMessage == message) return list;
		}
		// we got here so there was no list, so make a new one
		BBNotificationList newList = new BBNotificationList();
		newList.notificationMessage = message;
		notifications.Add(newList);
		return newList;
	}
 

Right now I just implemented it as an arraylist and we just do a linear search through it. Not super duper fast, but if you only have a handful of notification messages, then it will be plenty fast. If you feel the need for more speed, then just replace this method with something that uses a hashtable and you are all set.

finally, we need to be able to post messages. We already had a look at the actual message posting code in the NotificationList object, and the post notification in the server object is pretty damn simple:

 
	public void postNotification(string notificationMessage)
	{
		BBNotificationList theList = this.listForNotification(notificationMessage);
		theList.sendNotice();
	}
 

yep, that is it.

So how do we use this? If we have a gameobject that we want to react in some way to a notification then we simply have to register as an observer and implement the method that we are observing.

 
	void Start() {
		BBNotificationServer.instance.addObserver(gameObject,"FooAllWidgets");
	}
 
	public void FooAllWidgets()
	{
		this.widget.foo();
	}
 

And that is it. Very simple!

Note: right after I finished this, I decided to check the one place I forgot to check in my earlier searches, and lo and behold, the Unity community has in fact beaten me to the punch (as usual :-) You can find a javascript implementation of a nice notification center at the Unify Community Wiki. It is a bit different than my implementation, it offers a bit more functionailty, and some extra data handling. Stuff that could be added to this one fairly easily if you needed a c# version.

Cheers!
-B

Blog,code,multitouch,Unity

Unity tip for the day: Always name your new GameObject()s06 Sep

So, just to be clear, although I have done two tips in so many days, does not mean that I will necessarily be putting a tip up every day. Just since I am hip-deep in Unity at the moment, I am posting some little things that come to mind as I am coding along here. (currently working on the new xTUIO Unity presentation thingy, also, looking at version 1.1 of Snowferno, and! we are staring a new iPhone game in Unity: currently known as "Game B".. so using Unity quite a bit at the moment)

Anyway, tip for today: always Always ALWAYS name your generated objects.

So you have a little bit of code like so:

 
                if (pivot == null) {
			pivot = new GameObject();
			pivot.transform.position = gameObject.transform.position;
			pivot.transform.localScale = gameObject.transform.lossyScale;
		}
 

And that is great, and it works fine. When you run this code you will have a nice object pop up in your hierarchy called "New Game Object". This is fine if you do this once. But generally you are scripting in order to be able to do lots of stuff at once. So say you have a few dozen objects that all need a pivot, so then you you get a scene hierarchy like this:

Picture 71

Not very useful really. And if you are like me, and try to make everything all nice and objecty, the pivot generating code is somewhere high up in the class tree and there are three or four different classes of object that are using this code, so you have no idea really which one is making them (and not destroying them as intended, or whatever)

Instead just add a single line in there:

 
                if (pivot == null) {
			pivot = new GameObject();
			pivot.name = "Pivot " + gameObject.name; // Name it!
			pivot.transform.position = gameObject.transform.position;
			pivot.transform.localScale = gameObject.transform.lossyScale;
		}
 

This will make debugging much much easier. Anyway, it seems like a simple thing, and it is, but I find myself forgetting to add it in until I have a problem, then I have to spend 20 minutes finding all the places that I generate new objects and adding in a 'name' line. So get in the habit of naming your generated obejcts and your debugging life will become much happier!

note: this is good advice for any object in the unityverse. not just empty game objects. if you are generating any kind of component or camera or whatever, just spend the 2 seconds it takes to give it some name... trust me..

Cheers!
-B

About

meMy full name is Ben Britten Smith.

I go by Ben Britten because Ben Smith is a bit too common and using my full name is a mouthful.

I live in Melbourne, Australia and service clients all over the globe.

Contact

Have some questions?

Feel free to contact me directly at support@benbritten.com with any questions you might have about any of the applications I support.

Thanks!

PHVsPjxsaT48c3Ryb25nPndvb19hYm91dDwvc3Ryb25nPiAtIGFib3V0LXdpZGdldDwvbGk+PGxpPjxzdHJvbmc+d29vX2FkX2JlbG93X2ltYWdlPC9zdHJvbmc+IC0gaHR0cDovL2JlbmJyaXR0ZW4uY29tL3dwLWNvbnRlbnQvdGhlbWVzL3ZpYnJhbnRjbXMvaW1hZ2VzL2FkNDY4LmpwZzwvbGk+PGxpPjxzdHJvbmc+d29vX2FkX2JlbG93X3VybDwvc3Ryb25nPiAtIGh0dHA6Ly93d3cud29vdGhlbWVzLmNvbTwvbGk+PGxpPjxzdHJvbmc+d29vX2FsdF9zdHlsZXNoZWV0PC9zdHJvbmc+IC0gYmVuYnJpdHRlbi5jc3M8L2xpPjxsaT48c3Ryb25nPndvb19ibG9ja19pbWFnZTwvc3Ryb25nPiAtIGh0dHA6Ly9iZW5icml0dGVuLmNvbS93cC1jb250ZW50L3RoZW1lcy92aWJyYW50Y21zL2ltYWdlcy9hZDMzNi5qcGc8L2xpPjxsaT48c3Ryb25nPndvb19ibG9ja191cmw8L3N0cm9uZz4gLSBodHRwOi8vd3d3Lndvb3RoZW1lcy5jb208L2xpPjxsaT48c3Ryb25nPndvb19ibG9nPC9zdHJvbmc+IC0gdHJ1ZTwvbGk+PGxpPjxzdHJvbmc+d29vX2Jsb2djYXQ8L3N0cm9uZz4gLSAvY2F0ZWdvcnkvYmxvZy88L2xpPjxsaT48c3Ryb25nPndvb19jYXRfbWVudTwvc3Ryb25nPiAtIGZhbHNlPC9saT48bGk+PHN0cm9uZz53b29fY29udGFjdDwvc3Ryb25nPiAtIGNvbnRhY3Q8L2xpPjxsaT48c3Ryb25nPndvb19jdXN0b21fY3NzPC9zdHJvbmc+IC0gPC9saT48bGk+PHN0cm9uZz53b29fY3VzdG9tX2Zhdmljb248L3N0cm9uZz4gLSBodHRwOi8vYmVuYnJpdHRlbi5jb20vZmF2aWNvbi5pY288L2xpPjxsaT48c3Ryb25nPndvb19mZWF0cGFnZXM8L3N0cm9uZz4gLSA1NDk8L2xpPjxsaT48c3Ryb25nPndvb19mZWVkYnVybmVyX3VybDwvc3Ryb25nPiAtIDwvbGk+PGxpPjxzdHJvbmc+d29vX2dvb2dsZV9hbmFseXRpY3M8L3N0cm9uZz4gLSA8L2xpPjxsaT48c3Ryb25nPndvb19ncmF2YXRhcjwvc3Ryb25nPiAtIHRydWU8L2xpPjxsaT48c3Ryb25nPndvb19sYXlvdXQ8L3N0cm9uZz4gLSBkZWZhdWx0LnBocDwvbGk+PGxpPjxzdHJvbmc+d29vX2xvZ288L3N0cm9uZz4gLSA8L2xpPjxsaT48c3Ryb25nPndvb19tYW51YWw8L3N0cm9uZz4gLSBodHRwOi8vd3d3Lndvb3RoZW1lcy5jb20vc3VwcG9ydC90aGVtZS1kb2N1bWVudGF0aW9uL3ZpYnJhbnRjbXMvPC9saT48bGk+PHN0cm9uZz53b29fbmF2X2V4Y2x1ZGU8L3N0cm9uZz4gLSAyLDgyLDU0OSw1NTMsNTY3LDUzMiw1MzQsNTM3LDgzMjwvbGk+PGxpPjxzdHJvbmc+d29vX3Nob3J0bmFtZTwvc3Ryb25nPiAtIHdvbzwvbGk+PGxpPjxzdHJvbmc+d29vX3Nob3dfYWQ8L3N0cm9uZz4gLSBmYWxzZTwvbGk+PGxpPjxzdHJvbmc+d29vX3Nob3dfbXB1PC9zdHJvbmc+IC0gZmFsc2U8L2xpPjxsaT48c3Ryb25nPndvb19zdGVwczwvc3Ryb25nPiAtIDEuLCAyLiwgMy48L2xpPjxsaT48c3Ryb25nPndvb190YWJiZXI8L3N0cm9uZz4gLSBmYWxzZTwvbGk+PGxpPjxzdHJvbmc+d29vX3RoZW1lbmFtZTwvc3Ryb25nPiAtIFZpYnJhbnRDTVM8L2xpPjwvdWw+