vrijdag 2 november 2012

Unity and rotations, what about the rotation point?

I've been playing around with Unity for a while now. It's a great cross platform (pc, web, mobile) tool for developing 3D games (in C# or javascript). One of the things I had to get used to was rotations, and something called a Quaternion.

I won't go into the details of Quaternions here, there are plenty of good references such as wiki. However, there was one thing that took me a while to get clear, and for that reason I'll share it with you here.

All rotations can be represented by an axis and angle. If you think about this for a while, it seems reasonable. Pick up a matchbox, imagine sticking a pin through it (the axis), hold both ends of the pin and spin the matchbox a little. Voila, a rotation.

Now an axis in 3D math notation is a vector with 3 coordinates (x,y,z) and an angle is just a number, so a 4th coordinate. This gives rise to Quaternions, which are 4 dimensional vectors, as a way of expressing and carrying out rotations (I won't bore you with the details).

The point that had me confused for a while is that a 3D vector (x,y,z) is an arrow/pin stuck through the origin of the 3D coordinate system (0,0,0). But how does that relate to the matchbox. You can stick the pin through the matchbox from below or from the side, or squiff, or .... It seemed to me that you also need to specify the rotation point (place you stick the pin in).

Turns out this is true. However, you can still express all rotations with Quaternions. the idea is that you first move (translate) the matchbox so that the origin (0,0,0) of the 3D coordinate system is at the rotation point. Then, you can perrform the rotation.

So how does this all work in Unity? Well, all GameObjects have a (non visible) pivot point. When you call transform.rotate() the rotation is around this point (default space.self).

When you have a 3D model of a six legged alien, the location of the pivot point is a bit arbitrary. It also seems to depend on what kind of 3D content creation tool you are using (say Maya). For something simple like the default Unity cube, the pivot point is in the centre of the cube (seems logical). You have a button on the editor screen to show the pivot point (toggle pivot/center).

If you want to rotate around a different point, then you can use the Unity function tranform.rotateAround which requires you to specify the rotation point as well as the axis.

Small Side Note: rotateAround() always use World coordinates, whereas rotate() can use both local/self or World (default is self, so around the gameobject pivot point).

The mobile development scale from web to native

I remember the day when the only way to develop cross platform was Jave ME and Symbian (C++) was the biggest platform to target. Thankfully, those days are now long behind us and there are now many, many ways to develop apps for mobile platforms. I thought it would be usefull to arrange the various approaches along the "scale" from web to native, starting with the web end:

Websites (css/html/javascript/++)

All(?) mobile devices have a browser preinstalled, so all you have to do is build a website and the people will show up (wouldn't that be great).

Use HTML(5), css, javascript to build the webpages and for the rest of the web application, use any server side technology you like, be that php, python, .Net, Java, ...

There are plenty of great mobile frameworks that take the sting out of cross browser problems. Jquery Mobile (javascript), HTML5 Boilerplates, and Less/Frameless (CSS) to name but a few.

Phonegap (html/css/javascript)

Just a small step away from a website in a mobile browser is your own "native" browser app. Phonegap is a tool that allows you to develop apps using your front end developers: css, html(5), javascript. The resulting "web pages" are packaged into a native "browser" app which can run on Android and iOS (and probably more). You can of course use ajax to make web calls to your web application server if required.

In addition, PhoneGap provides a javascript library that allows you access to the mobile device. This allows you to use the mobile file system, accelerometer, etc...

The UI will not be "native" in that you determine how your app looks with css and html.

Marmalade (C++)

Develop once (in c++) and deploy to both Android and iOS (and more). Quite a leap from the web languages to c++, but you still only have to develop once to get multiple native apps. The native mobile UI is (partially) available via wrappers. Marmalade seems to be used alot by game development. Probably because it is so low level it caters to alot of (graphics) performance.

Marmalade also has a Web variant, which allows apps to be built using html, css, and javascript, in much the same way as for example PhoneGap.

Mono (C#)

Not quite fully cross platform, but certainly not native. Mono for mobile comes in two flavours, MonoTouch for iOS (you need MacOs to develop on) and Mono for Android (you can develop on many platforms). Mono allows you to develop you apps in C# against a subset of .NET.

The UI code(C#) needs to written seperately for iOS and for Android. The reason is that Mono gives you access to the native UI, as if you were developing natively. So on Android you will be creating Activities and using xml layout files, while on iOS you will be using UIViewControllers and the xCode interface builder.

You can build your business logic once and reuse across mobile platforms, just not your UI.

You will be able to access all (most) of the device functionality. The app will package and include part of the .NET CLR (only the parts required by your app), making the app a bit bigger than native apps.

Native (Java/Objective C)

Of course, you can always go native. That is guaranteed to give you full access to the device and the UI. No waiting on the cross platform tools to update their wrappers to the latest versions of the mobile OS etc. Native will give you the best performance and user experience, but will require the app to be built seperately for each platform.

Android development is in Java and Eclipse is a great IDE that integrates nicely with the Android SDK.

iOS is developed in Objective-C and requires a Mac to develop on. As I haven't had much experience here, I'll refrain from making comments.