piątek, 13 lipca 2012

Unity3D Yielding

To be honest the first time I find out about yield keyword in JavaScript was when I was learning Unity3D scripting. Did you know that yield is a built in mechanism of JavaScript? I didn't know that and Unity3D documentation was not very helpful on this ground either either:

The yield statement is a special kind of return, that ensures that the function will continue from the line after the yield statement next time it is called.

And

You can also pass special values to the yield statement to delay the execution of the Update function until a certain event has occurred.

Ok, so... yielding will break my function execution. This function will continue next time it is called. Pretty straightforward to me. So I wrote something like this:

private var explode : boolean;

function Update() {
    if (explode) {
        Explode();
    }
}

function Explode() {
    Flash();
    yield WaitForSeconds(1.0);
    Destroy();
    explode = false;
}

Guess what happened? Explosions appeared all over the screen like Explode() function was called over and over again. What the hell happened?! Let's look that explanation of yield by Mozilla fundation:

The function containing the yield keyword is a generator. When you call it, its formal parameters are bound to actual arguments, but its body isn't actually evaluated. Instead, a generator-iterator is returned. Each call to the generator-iterator's next() method performs another pass through the iterative algorithm. Each step's value is the value specified by the yield keyword. Think of yield as the generator-iterator version of return, indicating the boundary between each iteration of the algorithm. Each time you call next(), the generator code resumes from the statement following the yield.

Ok, so yield creates an iterator. We cannot assume that this is true for Unity3D JavaScript but this explanation may lighten up what is really happening.
After further digging I found example code of Daniel Rodriguez on his blog. He came with nice yield explanation and this example:

function MyCoroutine()
{
    print("This is printed second");
    yield;      //Return control to the Start function
    print("This is printed one fourth, exactly one frame after the third");
}
 
void Start()
{
    print("This is printed first");
    MyCoroutine();
    print("This is printed third");
}

Then let's go through this with keeping official yield explanation in mind:
  1. in Start() the This is printed first is printed
  2. diving into MyCoroutine()
  3. printing This is printed second
  4. yield will break execution od MyCoroutine() - returning to Start()
  5. printing This is printed third - so far so good
  6. wait, where's Update()? It's not important? Ok....
  7. When the fourth message will be printed then? How?
It will be printed. And MyCourotine() is not called in Update() I can assure you. Do you know why? This is my conclusion:
  • when yield is called it creates an iterator and puts it in (let's call it) yield queue to resume the execution later
  • right before the Update() call (or if there's no Update() let's think that it exists and it's empty) Unity is looking for each iterator in yield queue. If yield was called without parameters then execution will be resumed immeadletly.
  • calling method that contains yield over and over again doesn't resume the execution but will create more iterators in the yield queue. All these iterators will be executed (this is why I saw many explosions all over the screen).
What is the simplest way of thinking of yield (without parameters) in Unity3D? I belive it's To delay execution of further code and execute it before next Update() iteration. It's important to not to call function containing yield statement multiple times if you don't want to make it execute multiple times.


And I want to point here that this is only my assumption based on few experiments. I can be wrong here and please correct me if so. I believe that by time I will practice unity scripting something more and I will correct my above statements.

Sources:

Lab2 overboard!

Aye mateys! Just finished Lab2 project of Unity 3D tutorial by Walker Boys Studio. It took me somewhat more time because of fewer of things that were new and exciting. It is difficult to take the same things twice when you feel that you understand things quite a lot. But it's ok. It is finally done.

>>> Launch <<<

Production time

Predicted -> Actual

  • Setup:  10 -> 15
  • Assets: 45 -> 20
  • Player: 30 -> 40
  • Enemy:  20 -> 15
  • Menus:  40 -> 15
  • GUI:    30 -> 10
  • Build:  10 -> 2
  • Review: 10 -> 10

Additional changes

  • Extra socket to fire with (actually I added two extra sockets) - 10 minutes
  • Random asteroid speed and scale - 5 minutes
  • Pickup item: double (triple) shot and extra life - 30 minutes
  • Player flashes when hit - 10 minutes
  • Blocking cube - 15 minutes
  • Levels with different difficulty levels (I made 3) - 10 minutes

Project details

The goal of this project was to create 2D space shooter game controlled by keyboard with shield and lives countdown. I think that target of this tutorial was to solidify knowledge from Lab 1 and previous tutorial sessions.

Software and materials used

Didn't changed too much. Sublime Text is great script editor and I will stick with it from now on for sure. I managed to setup cloud backup solution called SpiderOak and I recommend it to everyone who values theirs data. SpiderOak as opposed to Dropbox encrypts your data before any upload so its quite safe no matter who have access to your uploaded files on the other side.

SpiderOak is monitoring your files continuously so any change is backed up and uploaded right away. What's more any file is versioned and you can quickly revert any unfortunate change made to project (like removing important assets or messing up the scenes). "Why don't you use SCM instead?" you say. I could but I don't need SCM right now. I will not revert my work to state commited many days or months before and I will not fork or merge my work anytime soon. Simple backup solution is all I need by now.

Final thoughts

Two lab projects behind and three to go. I think I understand Unity 3D a little better by now. I think a need to speed up a little. There is no time to waste. Lab 3! Here I come!

poniedziałek, 2 lipca 2012

Unity Course Lab 1

I've been doing Unity Course by Walker Boys Studio lately and I'm going through lab projects. One of the requirements is to create a blog and post my progress, so here I go!


Timeframe

From 26 June 2012 to 2 July 2012 (7 days).

Maybe but just maybe I think about counting off 29 and 30 of June. At these two days I've been in Warsaw at the Java developers conference. This is one time a year event.

Production Time

I am not counting time needed to listen to presentation talk (including rewinding) because I can't recall time I needed to listen it again and again. I can only recall how much time I needed or will I need to create each element of the game.

Predicted time -> real time (in minutes)
  • Setup 10 -> 10
  • Assets 45 -> 60
  • Player 30 -> 40
  • Enemy 20 -> 15
  • Menus 40 -> 20
  • GUI 30 -> 10
  • Build 10 -> 1
  • Review 10 -> 10

Additional changes

Blinking sphere 

Done in 40 minutes


This one took me by surprise. I tried to use yield to create blinking and failed miserably (unity created about 100 instances of explosion particles all over the scene). I needed to deeply understand what "yield" is actually doing and documentation is lack of this information (I found this). Finally everything is in order and I think I will write another blog post about yielding.

Moving cube

30 minutes
This was fairy simple. I made it to rotate in 3d :-)

Random respawn time for spheres

5 minutes
Too easy :-)

Make the Sphere move in a circular pattern

30 minutes
I had little problem with angle calculation but it's ok now.

Project Detail

The goal of this project was to create mouse clicking game with objects to destroy and score to earn. What I did was in biggest part what the tutorial told me to except particles effect. I spent some time to tune how explosion should look like just for fun.

Software and materials used

Rather not surprising are these two: Unity 3D 3.5.2, Windows 7 x64.
What about text editor? I think that UniSciTE is a horrible script editor that I don't want to use ever again. Instead I discovered that there are working Unity plugins for my favorite Sublime Text. After 5 minutes everything was up and running!



Final Thoughts


This is rather new experience for me to write game by creating objects first and writing scripts second but I like this new approach. What is important that I don't feel limited in any way when thinking about what I can create with Unity. It's exciting to think that I will be capable of creating really good-looking games 5 to 10 times faster than before with less effort on my side. It sounds funny that creating 3D worlds looks now much simpler than creating these in only two dimensions.

Unity rocks :-)