Unity3D

Guys, not only the next free update just got release. It's also that the formerly "Indie" version is now available for free !!!!! !!!! !!!!

Go download it NOW

YAY

It's so intensively refreshing to see a company of enthusiasts doing all the stuff I was hoping for Virtools over so many years. When I read their interviews I sometimes I get the feeling that they read my mind! But moreover they go even further with it!!!!

Thank you!

Background details in this Gamasutra interview and in in their 2.6 press release. And look at the Unity 2.6 release notes or have at glance at this extract:

  • streamed loading in the background
  • new profiler
  • animation curves
  • possibility to use any version-control system
  • new audio backend
  • better integration for Visual Studio
  • Render Target AA (nice !!)
  • Floating Point Render Target
  • Snapping
  • Terrain Brush size Preview
  • New hotkeys for Terrain editing
  • Debug Releases of the Standalone player
  • direct import of Cinema4D files on Windows
  • fixed rendering artifacts for intersecting geometries on windows
  • etc

Before opening your projects with 2.6, backup! 2.6 does a reimport and break backwards compatibility!

Interactive 3D for all – especially for casual games – is now !!!

YAY ! πŸ˜€

I already reported about prior attempts. Now one of the Unity developers uses his "do-what-you-want" Fridays to experiment with a visual scripting system.

Unity VLE proto

That 'development experiment' is currently called "Visual Logic Editor". You will notice that it's purely event-driven plus it contains low-level logic-components. Thus it looks more in the style of Crytek's Flow Graph and maybe a bit like Unreal's Kismet.

This kind of system are also used a lot in procedural content generation like found in .werkkzeug, mapzone/substance air and genetica. Or for Shader creation like with ShaderFX or mental mill.

Virtools hierarchical graph works quite differently as data and program flow are modeled separately – Kismet seems a bit like like a hybrid in that area, but as I never tried I don't know for sure. I hope at one point VLE at least goes in the direction of encapsulated hierarchical flows, because otherwise it may become quite messy with growing logical complexity – most systems add that at a later point anyways.

Example of how messy a Flowgraph can look like (found on the web):

Messy Flowgraph

The key for visual scripting system are hierarchical ones. It's like a LOD – level-of-detail system or programming functions/methods plus it facilitates re-usability. Personally, I prefer modeling state-machines that defines behaviour with these kind of of hierachical visual-scripting systems, as you can *look* at the relations and patterns. In code it's not that visible at a glance, in my humble opinion – even when using Co-Routines.

I am becoming a .Net/C# fan πŸ˜‰

With it's reflection ability, you can do some nice things. For example output all public data values of an object onto your screen. A little minimal example for Unity debugging/tweaking purposes …

Let's say we have two classes with public data we are interested in

    class MyDataOne : Object
    {
        public float AirDensityRo = 1.225f;
        public float LengthInMeters = 2156.33f;
        public float MetersPerSecond  = 2.0f;
    }

    class MyDataTwo : Object
    {
        public int Iteration = 0;
        public float Offset = 13.0f;
        public float Affinity  = 2.0f;
    }

We then save both instances into a list

List<Object> DisplayedDataObjects = new List<Object>();

void Start()
{

   DisplayedDataObjects.AddRange(new Object[] { new MyDataOne() , new MyDataTwo () });

(…)

 And in the OnGUI context you can draw the values for example like this

        (…)

        float yOffset = 15;
        foreach (Object obj in myDisplayedObjects)
        {
            yOffset += 5;
            GUI.Label(new Rect(5, yOffset, 240, 20), "== " + obj.ToString() + " ==");
            yOffset += 15;
            FieldInfo[] fields = obj.GetType().GetFields();
            foreach (FieldInfo field in fields)

            {
                if (field.GetValue(obj) != null)
                    GUI.Label(new Rect(1, yOffset, 240, 20), field.Name + ": " + field.GetValue(obj).ToString());
                yOffset += 15;
            }
        }

The nice thing is that you can rename (refactor) member names and classes without worries as changes will visible immediately. With the list you can also modify quite quickly in what objects you're actually interested in.

The reflection stuff is in "System.Reflection".

Just a little note, mostly for that I remember it better in the future πŸ˜‰ . Like Virtools, Unity's coordinate-system is Y-Up, unlike 3ds max where it's Z-Up.The Virtools exporter does all the conversion for you under the hood (except for Characters).

Looks like for Unity you need to pay attention. Currently my level in Unity is rotated 180 degrees around the up-axis, compared to the 3ds max scene. I realized that a bit late …  Anyways, for characters, car and the like one can do the following to get the same Z-Axis alignment as forward orientation in both applications:

Go into pivot-edit mode ("Affect Pivot Only" in the Hierarchy of the Command Panel) and rotate the pivot so that Z-Axis (blue) points forward, the Y-Axis points upwards and the X-Axis points to the side (left side). Then in the FBX export dialog choose "Z-Up" under "Axis Conversion". This way, it's very close to the Unity system – only the X axis is mirrored.

I've already my roads most of the time hovering above the terrain but still sometimes the terrain temporarily "shines" through depending on distance and view angle. I guess it's due the terrain's LOD, so some polys might become higher than intended on some LOD levels.

Terrain and roads intersection

In Virtools there is something called "Render Priority": a per-object settings that can be adjusted in the hierarchy manager. It can help for these kind of situations. I was looking for something similar in Unity. The editor itself doesn't seem to have anything related but the shader framework, called ShaderLab, itself has.

So you have to download the built-in shader sources, and create a derivate. First I thought it's the SubShader RenderQueue-Tag, but that didn't had any visual impact. You have to adjust/bias the z/depth buffer value via the Offset state.

Less intersection due Offsetting the depth

In my case I went through the "diffuse" shader and added an "Offset -1,-1" to any spot where RenderStates where set. Like you can see from the image above, it helped a lot. Unfortunately it's not perfect, I am still having tiny but annoying cracks here and there when driving or flying along the roads:

still some small artefacts

I guess I've no choice and adjust further the terrain heights manually to get rid of them…

Last week I digged into the topic of exporting a lightmapped, vertex-colored scene from 3ds max to Unity. Unity3D does not come with special exporters but exports to standard formats like FBX and COLLADA. When exporting to FBX, 3ds max Shell Materials do not get converted automatically to a lightmapped shader upon import. No wonder as FBX (= Filmbox which became later MotionBuilder) is not specially targeted towards game content. Therefore you have to manually assign the shader and the second texture. Of course it would better if this could be automatized!

Here are two pictures from a test scene with vertex-colored houses we created once for Virtools-based projects. The houses are currently using only dummy lightmaps, but that's the result without any manual shader or texture assignments.

Raw 3ds max scene Result in Unity 3D

So, here is how I do it.

Preparations inside 3ds max with Maxscripting (MXS)

Unity allows to hook into the assets import pipeline via custom scripts. This is very cool concept and is similar to something we did for our Virtools Assets&Build pipeline which we called BogBuilder btw. The key concept is therefore to *somehow* pass hints to a assets post processor script. What I do is to tag material names inside 3ds max, for example using __lm__ to indicate that the material is a lightmapped one. I use two underscores on each side because it reduces the probability that the original name accidentally contains such a sequence of letters.

I did not found a way to extract the names of lightmap texture from FBX files inside a Unity post processor script. So I actually add the texture name to the material name itself too! Here is an example of how a material inside 3ds max can look like after preprocessing

wandputz-tex__lm__S_4_WaendeCompleteMap_ambient-schlagschattenMulti100.tga

Pretty long, hehe. But it helps!

The custom maxscript does thus the following for every shell material

  • take the texture from baked material and put it into the original material's self-illumination slot
  • add the lightmap tag to the original material name (if it's not already there)
  • add the lightmap texture filename (including extension) to the material name
  • assign the original material back onto the geometry

Don't forget to check if the original or baked material is of type multi-material and handle it accordingly. Another issue I *sometimes* have is with special German characters like öäü. Unity sometimes replaces those upon import with some other symbols and may therefore break your postprocessor scripts when they will look for the lightmap textures. I created two more custom maxscripts that check and replaces those characters in material and texture names. (For object names it would be good, too, I guess). As a little hint, in order to access easily all bitmap-materials inside 3ds max you can use the following maxscript snippet:

local maps = getClassInstances bitmaptexture

Using enumerateFiles or usedMaps() only gives you strings and might turn things more complicated. As some of our meshes use Vertex Colors, I check that too and tag material then with __lmc__ instead of __lm__. To detect the use of vertex colors you can do the following

local tmesh = snapshotAsMesh myObjectNode
if ( getNumCPVVerts tmesh > 0 ) then

Using AssetPostprocessor

There are several types of asset postprocessors. To create one, you have to place/create your script inside a project folder called "Editor". It's not created by default, so create one if you can't find it. Using Javascript you usually start like this

class AssetPost_ShadersByPostfix extends AssetPostprocessor
{    …

and then you implement a static function depending into which kind of event you want to hook into.

OnAssignMaterialModel gets triggered each time a material has to be imported. In this callback you have the control if, where and how you create the new material. If you organize your project in a way that you cluster all materials in specific directories rather to have them close to the geometry assets, then this works fine. Otherwise this isn't the best callback to use as you don't get any hint where, inside the project directory hierarchy, the imported FBX is. Usually on FBX import a "Materials" folder is created on the same level, something you can't do easily with OnAssignMaterialModel. Alternatively you can use

OnPostprocessAllAssets: The benefit of this callback hook is, that the assets creation is automatically done for you and you get the target directory paths as array. To detect materials you can simply do something like this

        for (var aFile: String in importedAssets)
        {
            // identify materials by .mat extension
            if( aFile.ToLower().EndsWith(".mat") )
            {
               …

This works pretty good. But also with this there is a scenario where it's not the best fit. If you use the FBX exporter option "embed Media" that includes all textures inside the FBX file, then it does not import the lightmap textures during the first import/refresh activation. They get imported if you do a refresh or if you switch to another app and back. As result, your OnPostprocessorAllAssets may not find the lightmap textures because it's called during the first run, when the materials are created (and only diffuse textures get imported) and the lightmaps are added in the second run to the project.

So what I do is calling manually a custom ScriptableWizard inside Unity after import. It's therefore not totally automatic, but quite robust and only something like 3 clicks.

Somehow I miss some built-in functionality to deal with project things inside Unity but you can parse through all material assets inside your project using standard DotNet, like this

import System;
import System.IO;

var matFiles : String[] = Directory.GetFiles(Application.dataPath, "*.mat", SearchOption.AllDirectories);

for(var aMatFile : String in matFiles)
{     …

The rest is quite straight forward: the Wizard iterates through all project materials, checks if they contain any shader tags in their names, assigns the corresponding shader, extracts the lightmap texture name, finds the texture and assigns it as second texture to the shader.

Well, that's it. I hope this helps you to setup a better pipeline for importing assets with lightmaps from 3ds max. Of course the key concept can be used for anything else too! 

Just a little hint for new Unity users on the PC platform. The SciTe/Scintilla editor that comes with the PC version is probably a lot better than the smultron editor that comes for the Mac version. Still it's a complete different level if you use Visual Studio.

Visual C# Express 2008 is a free development environment and it's very good. Besides standards like Syntax-Highlighting it has good refactoring tools and a pretty good intellisense (intelligent auto-completion).

Visual C Sharp for Unity

In order to use Visual C# Express, you need to add references to the Unity DLLs inside a new project. On the PC you can grab them from the installation folder

…\Unity\Editor\Data\lib\

The DLLs are

UnityEditor.dll
UnityEngine.dll

If you also add all other DLLs your code depends on, you can even compile your code for verification. If you don't copy your .cs file but use the same that is referenced by the unity project, then each time you save the file in Visual Express, Unity will notice the change and reload and compile it using Mono.

Visual Web Developer 2008 Express says that it has "JavaScript IntelliSense" – I haven't tried it but if you prefer JS than you should give it a try!

Aw, this was getting another draft starting to remain forever a draft. So certainly no news for many of you, but for the rest, here we go:

More and more people are involved into interactive real-time 3D. Actually not so few articles of mine (like this one here) are dealing with this aspect, so I am kinda repeating myself … I hope you don't mind too much, hehe

πŸ˜‰ 8)

Interactive real-time 3D is getting easier to use and even produce – games are driving the hardware and software industry intensively. Like other technologies that are initially only affordable for few, over years things may become part of the everyday life of many people.

Besides products and platforms of big companies, solutions like Torque and Unity3D from smaller companies are playing an interesting role in all this … 

Gamasutra reported early this month that Criterion Co-Founder Lau-Kee joined the Unity3D team as adviser. He says:

The last several years has brought a plethora of entrants into the video game tools & middleware sector, but Unity is the only company I have found that has the technology, the people and the strategy to be truly transformational

Moreover

Mark my words, the democratization of the games industry has begun

For additional information you can read this interview or David's blog, where he also states

[…] our userbase tripled, there’s probably more than 10 times more games out with Unity now than in 2007 […] we could afford to more than double the team […]

There is another interesting interview at developmag, entitled 3D ehr One-For-All.

πŸ˜‰

I like this passage:

[…] they absolutely understand that they are answerable to the community of Unity users. You just need to take a look at the Unity forums – what you see there is a true community, vibrant, thriving and creative. […]

[…] in this sense Unity is more like using, say, Photoshop than a game engine […]

This is also visible in Unity3D IRC user channel as it peaks now at 50 people! Compare this to #virtoolsdev's peak which was around 16!

On Virtools forum someone once said, that real-time 3d tech is not like i.e. photoshop. But if you consider where Autodesk is aiming for, we will probably have more real-time 3d applications that will be like i.e. photshop! In Silverlight/Blend 3D is one type of asset like any other. Real-time 3D slowly becomes a standard media asset like video or photos!

Harrison from Atari said last year:

[…] from an Atari perspective… I think we would want to work with creators of all types, and that's why I'm so interested in Unity, because it does democratize development

He also says:

Managing the funnel of recruitment, training, educating, and getting the skills shortage, skills gap closed, is kind of an industry-wide problem…

This is interesting, because I had the same idea for a while about Virtools as I thought that Virtools once was in the position to do the same. Although I intentionally started  to post less suggestions, feedbacks, bug-reports etc. – due my frustrations of how one-sided this all turned out to be – I still suggested Dassault Systemes on their board last summer to use Virtools to get people in the boat, for that there is a recruitment pool for 3DVia mp!
You know, just the idea of democratizing 3D via mass and not premium markets – basically what the user-base actually understood under 3D-For-All!

The GarageGame guys share the vision:

In 1999, myself and my partners started GarageGames with the goal of democratizing development, and brought a low cost game engine to market. We started calling shareware authors Indies, and changed the landscape of Indie and low end development.

I already mentioned InstantAction, the web3D game portal. It's something that once would have been possible with Virtools too – in theory – but the vision lacked and pricing model was not permitting 3rd party teams to do so. Now InstantAction has

[…] managed to cross the 1 million members mark only 9 months after we covered their launch […]

[…] 2009 will be a big year for this service. IA will increasingly become a great place for Indies to make money

Currently there is a Unity multi-day conference in Copenhagen called Unite. One guy blogged about some announcements:

  • next Editor release will run on Windows too
  • one day Linux/Unix will be supported, too. There is a cooperation with Novell
  • iPhone add-on now available
  • FusionFall, a MMO project for CartoonNetwork, was intended to use GameBryo but now uses Unity for the client
  • new features that were added to the MMO project will be included
  • the Editor was completely rewritten in C# and comes now with docking panes, tabs and more scriptable interfaces
  • 3d snapping inside viewports

Last year I hoped that they would release the PC-Editor this year – i.e. at this conference. With all the new platforms (iPhone and Wii) they added I got doubts. Thus it's great to hear that it's not sooo far away anymore … The windows release will certainly boost them once more.

Interesting times ahead… :)