Moving from JavaScript to C# in Unity3D

If you’re anything like me, when approaching Unity3D for the first time you asked yourself a crucial question: Which programming language should I write in? As a Flash developer experienced in ActionScripts 1, 2 & 3, the temptation for me was to go for JavaScript. Syntactically, JavaScript and ActionScript are very similar. And from my point of view, JavaScript is the more popular language of the three Unity offers. I figured that whilst many experts may be using C#, most of the tutorials and sample code would be written in JavaScript, and I didn’t want to spend my time transposing code when I was trying to learn the fundamentals.

If that’s what you’re thinking, be you a Flash developer or not, I suggest you reconsider. I always knew I’d turn to C# eventually, but I was surprised by how quickly I found a need to do it. And what’s more, I discovered this: ActionScript 3.0 is more similar to C# than it is to JavaScript. There, I said it.

OK, syntactically speaking, what I just wrote is a load of balls. But in terms of functionality, I honestly think it’s true. Coming from AS3, when using JavaScript you’ll quickly find yourself wondering to where certain functions and keywords have disappeared. It seems like they should be there, I mean the code looks the same, but they ain’t there.

Anyway, that choice aside, this post is going to highlight some of the things I’ve discovered whilst converting an incomplete space invaders game from JS to C#. Note: part of the reason it was incomplete is because I couldn’t manage things the way I wanted to without the use of C#, particularly its better native Array(List) object and events.

 

Unitialised variables

Unitialised variables in C# are not allowed. Fields are, variables are not. This means you can write:

public class Class1
{
int i; //i will equal 0
}

But you cannot write:

for(int i; i < Array.Count; i++)
{
//Do something. Or not, as ‘i’ will be uninitialised!
}

Pity, as I became quite used to doing that in ActionScript. Then again, and without going into too much detail, in ActionScript the temptation was then to apply the same trick to a nested loop, which would be a mistake. A very unfortunate mistake. So, maybe it’s for the best.

More info here and here.

 

Null objects do not evaluate to false

Here’s another trick I got used to. Want to know if an Array element contains an object? How about:

if(array[i]) //do something with array[i]

Fine in ActionScript, I assume JavaScript as well. But that’s not going to help you in C#. You’ll have to be explicit and write:

if(array[i] != null) //do something with array[i]

 

You can’t add to only one of a Vector’s properties

This is Unity-specific, but it seems that rather than writing:

gameObject.transform.position.x += 10;

You’ll have to add a whole new Vector3 object, like so:

gameObject.transform.position += new Vector3(10, 0); //Can use overloaded constructor to pass a value for ‘z’ here as well, if need be.

 

Interfaces. Oh boy.

Look, this one is hard for me. I have spent years now building extensible, component-driven frameworks, mostly for e-learning, and I got into the habit of, basically, putting an interface on everything. If SomeClass doesn’t have an ISomeClass interface, IDon’tWantToKnowAboutIt. Using interfaces in Unity however quickly got out of control, and I’m now of the opinion that, for the time being at least, they are best avoided.

It started like this: We’ve got a space invaders type game, and in this game several elements can be destroyed. There are the enemy ships, the player ships, and the shields, all of which we want to affect when a shot collides with them. So having detected the shot collision with something, we need to pull out a reference to thing with which it has collided. Was it an enemy, the player, or a shield?

Well quite frankly, it shouldn’t matter. I don’t know, and I don’t wanna know. The glory of object oriented programming is that we can relate to each other all the objects which should take damage. This could be in the form of a common interface, say ITakeDamage, or we could define a base class which the enemy, player, and shield extend. In either case, our base class or our interface will expose a function called TakeDamage( float strength ).

Here’s where the trouble begins. You’ve got the object with which the shot collided, and you want to find all ITakeDamage components in that object. Well bad news, buster, you can’t. Well, not without a lot of casting and some warnings. The problem is that GetComponent, and its related methods, all return an object, or stack of objects, of type Component. As the ITakeDamage interface is not the Component class, this is going to draw the ire of whichever code editor you’re using (in my case Visual C# Express).

There’s a little forum discussion on this very issue, at the end of which is a post by myself explaining that, faced with this problem, I ended up doing this:

Component[] components = collider.gameObject.GetComponents<Component>();

foreach (Component obj in components)
{
        if (obj is ITakeDamage)
        {
                (obj as ITakeDamage).TakeDamage(strength);
                health -= (obj as ITakeDamage).Resistance;
        }
}

So fine, we’ve got our interface in. It’s a little clumsy, but it’s there. So what’s the problem? Well, you can see that there’s another property in that interface, called ‘Resistance’. The thing is, an interface cannot define fields, only properties. Put another way, that Resistance field is going to need a getter/setter pair; it cannot just be a public field in whichever classes implement our ITakeDamage interface. (Well, not if you want it to be defined by the interface.)

And here, dear reader, is where the final, Earth-shattering blow comes in: The Unity Inspector panel helpfully exposes all public fields, allowing you to modify their default values within Unity, and give unique default values to unique instances of the same object in your scene. Do you think the Inspector exposes public properties (with getters and setters) also? The hint here is that if the answer were ‘Yes,’ I wouldn’t be going on like this :)

No, it can’t. Maybe one day, maybe not. For now your only option, if you really, really, wanted to use an interface, would be to link your getter/setter pair to …a public field. Quite frankly folks, if you go that far just to implement an interface, you’ve gone stark raving mad, and I’m having none of it. Now in truth, I think I’m better served by a base class in this scenario anyway, as there’s lots of shared functionality. And I think my old habits are dying hard. Look, we’re not here to create frameworks; we’re here to make games!

For the curious, here’s the base class in all its glory:

using UnityEngine;

public class TakesDamage : MonoBehaviour
{
    public float Health = 1;
    public float Resistance = 1;
    public bool IsAlive = true;

    public delegate void DeadHandler(TakesDamage sender);
    public event DeadHandler Dead;

    public void TakeDamage(float strength)
    {
        Health -= strength;
    }

    protected virtual void Update()
    {
        if (Health <= 0) HealthDepleted();
    }

    protected virtual void HealthDepleted()
    {
        IsAlive = false;
        if (Dead != null) Dead(this);
    }
}

Posted in n00b, Unity3D | Leave a comment

Transforming to Unity3D

Before we begin, welcome to my blog :) All the old entries have been deleted, although they were merely four in number, and served only the purpose of demonstrating my old Flash work, such as it was. I suspect I’ll never again go hunting for a Flash role, which leads us to this blog post.

I’m really keen to get into Unity3D, though who knows if I’ll ever use it professionally. Still, a guy’s gotta have a hobby.

The transition from Flash to Unity is a theme which I imagine will occur throughout this blog. But why have a blog at all? Seb Lee-Delisle, during one of his courses which I was attending, paused to look up, on his own blog, how he had achieved something in order that he could demonstrate it to us attendees. He remarked that this is the reason to keep a blog: as a means of “remembering stuff.” Of course in that case, it was for recall. In this case, it’s to assist the sorting out of my head, and encourage whatever thoughts I have to bed in.

I am a total n00b, so there will be many questions asked, and fewer answered, at least by me. But if you can answer them, please make me happy and do it!

So, today’s topic is: object transforms. Ha! Bet you didn’t see that pun coming all the way from the title, did ya? More accurately, it’s an exploration of naming. You see, I’m confused. Here’s why.

We’re going to conduct a little experiment here. We’re going to make a cube. Then we’re going to make an empty container object and put the cube inside it, at the coordinates (1,1,1). Then, we’re going to place that container object into the world at (0,0,0). So, it goes: world contains Cube Parent, which contains The Cube.

Here’s a screengrab to help. I’ve marked the position of the Cube Parent with a pink splurge.

So there you see the Cube Parent at (0,0,0), and The Cube is at (1,1,1) inside the parent (and therefore, also in the world). Now, to keep things simple, from here on I’m going to make unilateral changes to positions and scales. So if something is scaled 2 on the x axis, it’ll be scaled 2 on the y and z axes as well. But I’ll simply say that its scale is ’2.’

So in the above scenario, I want to highlight the state of a few properties, as retrieved by a script assigned to The Cube. Grabbing the Transform (this.gameObject.transform), we have two properties representing the x position: position.x and localPosition.x. In this scenario, both values are 1. So what’s the difference? Well, let’s move on and find out.

In this second scene, the Cube Parent has moved to (1,1,1). What do those previous two values of x have to say for themselves now? Well localPosition says that x is still 1, but regular position.x now says it’s 2. Aha! So in the world as a whole, the centre of the cube is at x = 2. We’ve moved the parent to 1, The Cube is already at 1 inside that parent, and the effect of this (1 + 1) is that The Cube now sits at x = 2 in the world.

So, it would seem that ‘local’ as far as the Transform object is concerned means the coordinate space of the object’s parent. The non-local value represents the object’s position in the grand scheme of things.

There’s another property in the Transform object which I’d like to highlight, which is called localeScale, and behaves the same way. If I were to scale The Cube by 2, localeScale would indeed read 2. But if I were to keep the scale of The Cube at 1, and scale Cube Parent by 2 instead, the net result would be the same (2), but localeScale would nonetheless be 1. In both cases however, another property, called lossyScale, would always be 2. This is consistent with what we’ve already seen with the positions; locale (or local) represents the direct properties of the object, regardless of the net result of other parent objects acting upon it. If you want the net result, it’s available in other properties (‘position’ and ‘lossyScale’).

Except, here’s my first gripe: they’re not named very well, are they? Was there really a need for ‘locale’ and ‘local’? And to get the net position we have simply ‘position’, whereas to get the net scale it’s ‘lossyScale.’

Now let’s move on to the Mesh. Grabbing the Mesh by calling GetComponent(MeshFilter).mesh, the value of mesh.bounds.center.x is 0. In which of those two scenes, you ask? Oh, only both of them! And the mesh.bounds property also states, again in both cases, that the size of The Cube is 1.

So, OK, it appears that these properties represent the original state of the object, regardless of the many ways in which you may have affected it. You may have created a cube 1 unit in size and then scaled it up, but as far as the Mesh is concerned that’s not important. You may have moved it, but the Mesh only exists in its own little world. There is nothing external. The Cube exists not in a world; The Cube is the world!

Now, that’s fine. Hell, that’s useful! But how does the documentation explain this? Well, the documentation for Mesh.bounds explains that it is “the [...] bounding box of the mesh in its local space (that is, not affected by the transform).”

In its local space. There’s that word again! But wait, back in our first example, didn’t ‘local’ mean the coordinate space defined by the Cube Parent? So what does it refer to here? I mean, in order for an object to have a position, it must be positioned within something. And that something is not the Cube Parent, because we know that The Cube is at 1 inside the parent, not 0. So the conclusion is that the mesh, being a component of The Cube, is positioned within a coordinate space defined within The Cube itself.

So a couple of questions. Firstly, can one ever reposition the mesh so that it is not at 0, and what would be the purpose of this? Most importantly, couldn’t these properties be named better, and couldn’t the documentation be a touch more illuminating? It took me a lot of experimentation to understand the differences between these properties. Five of these scenes in total, as it happens. I’m fine with differences conceptually, but with those names and the wording in the documentation I had to see for myself which properties did what, as it certainly wasn’t clear beforehand.

I reiterate: I am a total n00b. Perhaps someone out there can set me straight? I feel I may have failed to grasp one or more things here.

Posted in n00b, Unity3D | Leave a comment