Everyday Flash

Creative use of technology // A blog about 3D Flash and Actionscript by Bartek Drozdz

Loading and manipulating images in Unity3D

As I promised here's the first article exploring Unity as a 3D web application tool.

Every web application nowadays is data driven, therefore the ability to dynamically load assets is crucial. Unity3D can load plain text, images, video and sound. Since loading plain text is not so interesting, I thought I'd see how it works with an image.

Here's a little experiment I called "Image Decomposer". It loads an image passed as parameter in the URL and creates a wall of little cubes which colors are based on the pixels of the image. When you rollover the cubes they fall down slowly decomposing it, hence the name.

The code is pretty simple, you can get the source here. Below are a few things I found out while making it.

URL parameters

A very useful way to pass parameters to your swf files is to attach them as a query string in the embedding HTML, like this: flash.swf?paramA=valueA&paramB=valueB. It's a Flash classic!

The good news is that is also works in Unity. Take a look a the HTML source of the demo to see how the image URL is passed to the unity3d file. Inside Unity3D it's very easy to get access to it through a static property called Application.srcValue. It returns the whole path, including the file name and you need to parse the query string yourself. Here's a sample code in C#:

C#:
  1. string su = Application.srcValue;    
  2. string qs = su.Substring(su.IndexOf("?") + 1);
  3. char[] deli = "=".ToCharArray();
  4. string[] ps = qs.Split(deli);

The 'ps' array now contains pairs of key/values from the query string.

Loading freedom

Unity3D supports JPG and PNG format. Sadly GIFs are not supported, even animated... ;) The really nice thing is that there aren't any security restrictions when loading files from other domains. This is something that drove me crazy so many times with Flash! In Unity3D pass a valid URL and it will load the asset, it's so simple. If you don't believe me - just paste any link pointing to an image in the demo ("image" parameter in the URL) and see it for yourself.

I wouldn't expect things to be like that forever though, so use it while you can people!

Coroutines and C#

To deal with asynchronous events, like loading an external asset, Unity3D uses coroutines. They are a bit different from events in AS3, but not very much. If you are a fan of C# and want to use coroutines you may find the official documentation a bit unclear. So, first, read the official documentation here and here, and continue reading this post afterward.

What caught my attention is that to use the yield statement, the enclosing method must return IEnumerator. But all of the inherited methods in MonoBehavior, like Start(), Update() and the event handling ones return void.

Surprisingly, it turns out that you can just change the signature of any of those methods so that they return IEnumerator! If this isn't breaking OOP rules, I don't know what is. But, since it works, it's ok I guess. It's certainly not obvious. Otherwise it is possible to create a custom function that returns IEnumerator and use the StartCoroutine() method of MonoBehavior to run it.

Another thing is that with C# you need to write yield return... not just yield... The official docs being written in Javascript they tend to omit the new operator as well, and C# does not like that. So, if the docs say:

JAVASCRIPT:
  1. yield WaitForSeconds(2);

and you copy/paste this to a C# script, you need to edit this line and make it look like this:

C#:
  1. yield return new WaitForSeconds(2);

If you keep this in mind you will spare yourself some annoying compile errors.

Scaling images (or why you don't need to do this)

Once the image is loaded, it can be assigned to a Texture2D object, which is the type to store bitmaps in Unity3D. From now on it can be used as a texture for any material. For example, you can create a plane and assign it as the main texture of the plane's material or use GUI.Label to display the picture in 2D. But let's do something more interesting.

Texture2D has a few methods to extract information from the image, the most basic being GetPixel() and SetPixel(). They work exactly the same way as their equivalents in AS3 BitmapData class. The first allows to get the color of a pixel at a given coordinate, the other does the opposite.

When you start to play with these and you use images embedded in the project, make sure to select the "Is Readable" checkbox in the inspector. Images loaded dynamically are readable by default.

In the demo, no matter how big the loaded image is, the amount of cubes generated remains the same (it will adapt for different aspect ratios though). My first idea was to scale the image to something like 50x50 pixels, and then using getPixel() to fetch the color for each cube. But I found out that there isn't any function to resize an image in the API. Sure, I could write my own function, but this can get quite complex as you can see here. Fortunately there is a better way.

Texture2D has a method called GetPixelBilinear(). It uses bilinear filtering to evaluate the color of the image at a specific point defined by normalized coordinates (i.e. in 0-1 range). If the word "bilinear" sounds familiar to you it's because Photoshop also uses this algorithm to scale images. With this method the same code can be used to get pixel colors from images regardless of their size and aspect ratio:

C#:
  1. Color c1 = image.GetPixelBilinear(0,0); // always top-left color
  2. Color c2 = image.GetPixelBilinear(1,1); // always bottom-right

It's much more elegant (and faster) than scaling images!

As a side note: it would be also very easy to implement an actual resizing function using this method, in case you really need that. I'm sure that by now you can figure out how to do this :)

What's next?

The above example is simple but I hope it shows you how to get started with dynamic content. As far as images are concerned, much more is possible. By using custom shaders and render textures you can apply filter effects to images (and video). However, these features are available only in Unity3D Pro and besides, explaining it would make this post way too long. I'll do that in a separate article instead.

Unity3D: beyond games

I am not a game developer. For the last 10 years (with some short intervals) I've been working as a Flash designer and developer and I have been creating projects more or less related to advertising such as animations (including banners, that I actually enjoyed making), video sites, rich media interfaces, web applications, 3d simulations and, sometimes indeed, simple games.

I believe however, that Unity3D is much more that a game development platform, and all those kind of projects could be tackled with Unity3D as well. In some cases the result would be pretty awesome and way beyond anything we can currently dream of with Flash and Actionscript - and this kind of opportunity is what I am looking for. (In some other cases it could end up with a disaster, similar to what happens when sites that clearly require HTML are done with Flash. We will see those too, simply because errare humanum est).

Technology adoption is not as fast as we could wish. I'm sure that eventually Unity3D will become the standard for 3D applications on the web, but we're not there yet. So far it has been very successful with games for the iPhone and it starts to emerge as the tool of choice for online games. The advertising business will follow and adopt it as well. We can expect top interactive agencies and production companies to start releasing Unity3D productions soon. I hope this will happen within this or the next year. Chances are that such projects are already in the making.

The reason why this will happen is that Unity3D is versatile. It is marketed as a "game development tool", but it has numerous features that allow much more that that. It allows to integrate diversified content (2D, 3D, video, sound), has a great animation tool and a powerful scripting API to create any kind of complex logic.

As I got back from FITC Amsterdam loaded with new energy and inspiration, I decided to take a deeper look at Unity3D scripting and go at least a bit beyond the basics and beyond the "building a 3rd person shooter" scenario. As a long time Flash developer there are some problem/questions that are typical to Actionscript technology and I decided to check how similar problems can be solved with Unity3D. Here are the first 3 questions that came to my mind, pretty basic actually:

1. How to dynamically load an image into Unity3D and do something with it?
2. How to draw lines, points and shapes at runtime?
3. How to generate content with code?

The questions order starts with those that have been easiest to answer. I have some more questions lined up, so this post might get updated. Anyway, in the coming days (or weeks rather) I'll be posting the solutions. I made some experiments, I have some code to share and some tips that I found on the way. See you soon!

Speaking in Amsterdam, London & Toronto

Amsterdam, London, Toronto

The conference season is upon us!

Following my last year short presentation at Flash On The Beach and at the Warsaw Flash Camp, this year I will continue my adventure with public speaking. In the next months I will be having my sessions at 3 highly interesting events.

1. FITC Amsterdam, February 22nd-23rd

FITC Amsterdam is only a few weeks away. I've been to FITC last year and I really enjoyed the conference (and the parties too). I am thrilled to be back this year as a speaker. If you want to catch my session it's on Monday (Feb 22nd) at 12:30. If you are interested in Unity and in 3D in general you should definitely attend! For more information, here's a detailed session description. I hope to see you there!

FITC it's of course much more than my presentation. There are 2 days packed with interesting sessions, so be sure to checkout the schedule to see what's interesting for you. There is also a party every evening - a great opportunity to do some networking and to have a few beers and some other stuff (remember, we're in Amsterdam!). So grab your tickets before they're all gone!

2. London LFPUG Meeting, March 25th

If you can't attend FITC and you miss my session in Amsterdam, don't panic! You can catch me again next month in London. On March 25th I will speak at the next in the series of LFPUG meetings.

It will be a evening packed with realtime 3D, as I will be speaking together with Rob Bateman from the Away3D team. Here's some detailed info about the event. The event is free, all you need to do is register, so if you are in London don't miss it!

3. FITC Toronto, April 25th-27th

Finally in April I'll be making the move over the Atlantic all the way to Canada for FITC Toronto, where I will also be talking about Unity. There is no schedule yet, but it's should be coming soon. However, the tickets are already on sale. If you hurry you might even get a early bird price!

This is very exciting for me for several reasons. First, it's a major conference with 3 days of sessions, workshops and even a recruiting event. It's not to be missed not only if you live in Toronto, but for anyone in the region. And I've heard people come for FITC from all over Canada and US.

Second of all it's my first time I will attend a conference in North America. I looking forward to meet a lot of people whom so far I knew only from blogs and twitter. So if you are around don't hesitate to get in touch!

Finally, it will be my first visit to Toronto and I heard a lot of good stuff about the city. We also plan a short family vacation afterwards to visit Montreal and Quebec.

Next?

I'm currently entirely focused on those upcoming events, preparing all the materials and the presentation. However, I hope for more opportunities in the future. If you happen to organize a Flash and/or Unity event and you are looking for speakers be sure to let me know!

I don't have any further plans at this moment, except that I will also attend OFFF in Paris in June (as guest, not as speaker).

Photo credits [1] [2] [3]

A 3D racing game in Flash with Away3D

Scion Street Racer

I am proud to announce my latest project. It's a 3D racing game done in Flash with Away3D. I worked on this project together with Calisto Labs and our client was Snowball Media. My task was to create the 3D game part. It was great fun to work on this project. The team at Calisto Labs did a awesome job and everything went smoothly!

The project required to use my Actionscript and 3D modeling skills together on a scale like I never did before. I spent a lot of time with Blender and Unity in the last months, and without this experience I feel the project would be beyond my abilities. Also, having a direct comparison between Flash and Unity allowed be to see things in a larger perspective.

Flash vs. Unity... again

I built the game with Away3D FP10. I must say that Flash 3D has gone a long way since I first started to play with it, and Away3D is a very solid engine. The 2K polygon limitation is a thing of the past, and the correct perspective projection in FP10 makes everything look so much better. The team also added some other crucial features to create 3D environments - ex. frustum clipping.

Before starting this project I was working on a Unity3D racing demo, so I managed to get quite a few ideas on how to build such a thing. However, when I moved back to Flash, I was a bit desperate because I realized how much stuff I got used to in Unity is just not there in Flash. A built-in physics engine would be the most important one.

Home-made physics and collision detection

For physics in Flash I was tempted do use JigLib at first. But soon I found out that JigLib is way too complex, creating a realistic car behavior would be very difficult and it would probably eat too many CPU cycles. I estimated that Away3D will take around 90-95% of available processing power, so there's no space for any other complex piece of code to run in the same time. I always think that when it comes to 3D in Flash performance is quality, and there is no excuse for poor performance, even if you want something to look "realistic". So I ended building something very very simple.

Once I got the car driving around, I needed to add some collision detection. In Unity you quickly get used to the fact that any 3d object is a collider which makes collision detection a no-brainer - just implement a listener method and get a call whenever your object collides with another one. And if you need to add realistic collision response, you just make the object a rigid body and there you go! (Ok, you may need to adjust some settings, but still it's pretty straightforward).

In Flash it seemed like a much more complex task. I was thinking in the lines of creating a system based on the geometry of the track. I started to study curve equations just to realize I wouldn't make it even if I had a year to complete the project! Then I remembered, that a good way to test collision with complex shapes is a bitmap.

The way it works is that it takes the car's position and checks against a map of the track that has different colors for different areas - ex. red for the road, green for the sideways and so on... Since it samples only a few pixels per frame and all it does is check their RGB values, it's lighting fast. Truly, Flash is the art of minimal!

Scenery

The most fun part was to create the scenery. I've never tried to import such a large 3D scene into Flash so I wasn't even sure if Away3D would handle it. It turns out it did handle it pretty well. Instead of using Collada I went with Wavefront (OBJ) format for the meshes as I feel it gave me more flexibility. OBJ is a simple format which makes it a bit easier to see what's going on while Collada is bloated and overly complex for my taste. I used Blender to model the track and the few objects that you can see around it - lampposts, houses and the tunnel.

Lightning

Lightning is very important in low poly scenes, because it adds a lot of detail and atmosphere to the scenery, without adding any polygons. Even thought the scenery is simple, I ended up having more that 60 lamps. Of course all those lights needs to be baked on the textures, there's no way to run them in real-time. Blender has a very good texture baking tool and all this works fine for static objects. But what about objects that move, like the car?

For lightning the car, I reused the concept from collision testing. But instead of a collision map I made another one - a light map. Basically it's a bitmap with white areas where the scenery is lit and dark ones where it's not. By sampling a single pixel on every frame I can see if the car is passing through a lit area. Then, all I have to do is to apply a color transform on the car texture to make it brighter. Again - a minimal solution, but it works!

Now that you know all about it, go ahead and try it out!

Modifiers in Unity3D

Ringo from FlashBookmarks asked me if there were modifiers similar to AS3Dmod in Unity. I searched for something similar some time ago, but didn't find anything interesting.

However, when I was starting C# scripting, I ported two of the modifiers from AS3Dmod - Bend and Twist. So I thought to share them with everyone. Don't expect much, it's not the full library, just two classes. If I have some free time, I'll look into how to implement stacking, since for the moment you cannot apply two modifiers to the same object (the second one won't have any effect).

To play around with them grab this package and import it into Unity. Keep in mind that the modifiers work at runtime, so you won't see any effects in the editor until you run the game. If you want to animate them, just add another script that will have a reference to the modifier instance and change it's properties at each Update() call.

If you are interested in this kind of "bricolage" with 3D geometry, I recommend to take a look at the Procedural Examples project provided by Unity. You will find there some highly interesting samples like dynamic extrudes or perlin noise. It's a great starting point to explore runtime geometry transformation.

Of course, take a look into the sources of the modifiers too! You'll see how simple it is to access the geometry at runtime and do some modifications. Basically it goes like this:

C#:
  1. MeshFilter mfilter  = GetComponent(typeof(MeshFilter)) as MeshFilter;
  2. mesh = mfilter.mesh;
  3. Vector3[] vs = mesh.vertices;
  4. int vc = vs.Length;
  5. for (int i = 0; i <vc; i++) {
  6.   // Modify your vertices here
  7. }
  8. mesh.vertices = vs;
  9. mesh.RecalculateNormals();

Things worth notice: In Unity a vertex is just an instance of Vector3 - there isn't any special class for this, as in Flash-based 3D engines.

You can see a bit of the casting-drama I need to do (lines 1-2) to get to the object holding the actual geometry information (Mesh). That's a bit annoying in C#, with JS that code would be more readable. Anyway, it's better to make that only once, in Start() and not at every Update().

To get correct lightning effects on the materials, do not forget to call mesh.RecalculateNormals() after you've modified the positions of the vertices.

If you want to modify your mesh continuously (i.e. to animate it) it's necessary to keep the original array of vertices, because the code above overwrites the original positions. Take a look at the source code in the package to see how I did it.

That's all for now, hope you enjoy it!

First steps in 3D design

There's something you'll quickly realize when you start playing with Unity. It's the fact that you won't go far without some basic knowledge of a 3D editor. I've been using Blender for my Flash 3D experiments, but I can't honestly say I knew anything about it. I was able to model some very basic shapes, and whenever I needed something more complex I'd ask someone who's more experienced or just find a free model on the Internet. With Unity it just doesn't make sense. You won't be able to understand half of the functionality if you don't have a 3D editor to work with. By the way, I'm not the only one who noticed this.

As a logical consequence, I decided to take a step back and learn Blender. I don't want to go into details on the choice of software. If you prefer Maya or Cinema4D, fine. I grew to like Blender, but I know it makes a horrible first impression. The thing about Blender is that it's free, and that's a huge advantage for beginners.

After some time of modeling, texturing and setting up lights and I started to really love that. I felt like I was taken 10 years back, at the time when I was discovering Flash, HTML, building my first "home page". I'm sure you all know the great feeling when you start to understand something new and your skills grow every day. There's nothing like it! (Ok, there are other things better than that, but let's stay within our geeky subject).

At first I wanted to get just enough skills to continue with Unity3D development. But soon I realized that this might be what I'd like to do for a living. Wait, what? Can you imagine? I'm in my thirties. I'm doing pretty well in flash development business. Is there anything more stupid that dropping all this and becoming a 3D designer? And how many years I would need to become any good at this? Or maybe it's just a matter of a couple months to master the tool and I'll be all set? But maybe I don't have what it takes to be a 3D designer. However a fundamental thing I believe in, is that there's no such thing as innate talent and all you need is enough persistence...

I've been struggling with those questions for a while, and I don't have any answers yet. In the meantime I ordered some books, found some tutorials and kept learning to keep all the options open. I still have a long way to go, but I can already see some results.

As my modeling skills grow, I feel much more confident as a 3D developer because I can understand where the assets come from, how they are built, how visual effects are achieved. Those things were like a black box to me before. Now I can even build some 3D stuff myself. It's so much worth the effort even if I'll never work as full time 3D designer.

The two Unity examples above are my first, modest 3D modeling experiences. One is a mini game. It features a scenery that I populated with a few models including my first car model. Apart from modeling the scenery elements I used that as a testing ground for many Unity features like the terrain engine, line and trail renderers, rigid body physics, car simulation, particle systems and of course scripting. The end result is a bit random, but I don't remember having that much fun for a long time!

The second is a small interior scene (really small!). I couldn't grasp how lightmaps work in Unity until one morning I woke up and I just knew (yeah, that's how it happens sometimes!). During the day, I quickly threw up this demo to test if my understanding was correct. I think it was, even though in the end the shadows came out too subtle. Anyway, I'm doing more experiments on that subject now and maybe I'll write a separate post on how to work with lightmaps in Blender & Unity.

That's it for now! I'll see where it takes me, but you should expect more 3D modeling related posts on this blog from now on. Also, I'm not giving up on coding... yet ;)



  • FITC10


  • FITC10