Unity3d Static class.

Unity3d golden rule. if you really need a static/singleton class, that isn’t just a library, that needs to interact with other objects or scripts, don’t actually make it a static class, you idiot.

say you have a class that has some variables or methods, that change or do something either at the start or during run-time, e.g stuff in update(), and you want this class to be accessible by all other scripts in the game.
why not make it static, as there will only be one instance of it, and you don’t have to call Gameobject.find().getcomponent<>(); in every class that needs to talk to it.
So you make the class inherit from base c# “object” rather than “Gameobject”, make it static and call it “TheMasterClass”, now at any point in your code, you cam just call TheMasterClass.DoSomeWickedCoolStuff(rad_Data);

sounds good?
well don’t do it anyway.


Static object classes cannot inherit from gameobject, so they cannot be applied as components to objects in the scene.
This means you get no update(),awake(),start(),onGui()…etc.
Could you just initiate them from the class constructor?
yes,…constructors do get called… at some point between your program starting and the year 90’000. You could try messing about with the execution order, but it has no effect.
Ah, but then..
Could I create a normal component class, attach it to a normal game object, and in it’s awake() function, initialize any static class, and also do the same for update()?
Yes, this would actual
ly work. So you have gone out of your way to have some class abstracted out of the game, so it can’t be instantiated, and then to get it to function like a class that can be instantiated, you created another class just to babysit your static class,and imagine if someone else saw your code.
But I have done this in other project/languages..
Unity is wack. DealWithIt.jpg
What should static class be for?
If you have some methods that don’t have anything to do with your game and will never change, that are READ-ONLY, e.g some extra maths or array iterator functions. Then they would be well suited for an abstract static object class, called something like “helper”, that you can call throughout your scripts.
What about static variables?
they have actual uses, for example having a variable that is shared between all your enemy npcs, which can be written to by any of them, and this variable only effects enemy npcs, then it would be the ideal use of a static variable in the enemy npc class.
There are always odd cases when you just need a class to hold some really funky data and/Or your name is Mr. Edge Case, then go ahead, it will work, make it a generic object class, but your overall design method needs to be thought over again Mr. Edge

Now this is a story

Now this is a story all about how

My Unity project got flipped-turned upside down

And I liked to take a minute just sit right there

And tell you how I ended up submitting a bug report.

So after an initial learning curve to get the basics of the unity editor down. I begun doing some real prototyping for a game idea. What Interested me in unity is the “terrain object” basically the engine and editor have built in support for making these big terrain things (Picture a minecraft map, but smooth, and not infinite). In the editor you can create a flat one, add geometry and texture to it, hit play and with a simple script you can be walking around it. NEAT!

What worried me about unity is when you have a very WYSIWYG (lookitup) platform like unity, it makes me think this is a “Game creater” rather than engine, where you use the inbuilt features to crate a game and go “EY MAH, LOOKIT I DONE CREATED A GAME”. However this is not the case,

Anything* you can do in the Unity editor, can be done with code during runtime, so you never really have to use the editor, you can just tweak variables.
However, this is the land behind the red curtains and the documentation in this area is sparse and broken, so be prepared for work.

*Probably not that much really, it’s quite bad.

This is paramount to Me as I Need procedural generation of terrain, when the game runs. So this is the task I spent a week on.

Day 1

So firstly, I have a flat terrain, in the editor. Now to get it to generate geometry onto it, randomly, when the game runs.
But first I must (invent the universe) make something that produces the random data. So I called up my pal notch and he told me about this mysterious man called Perlin who has what I need. After a long chase scene in a grimey underground train station I found him. However he didn’t go down without a fight, I had to do some heavy conversion and reverse engineering to get it to work with unities c# methods.
See the Perlin script here 
Q, why not use the built in random value function?
A, look here, imagine this is the height map, white being mountain peaks, and black ,the ground
So  I have random data, now to apply that to the terrain

Day 2 

Finally got this working, how does it work?
The terrain is a map of points, these points contain a height value.
the value is between 0.0 and 1.0, 1 being the highest possible height.
So what you do is you loop through the terrain just like an array and set the heights to be that of the output of the Perlin script.
Now for the first of many awkward problems. the terrain bed or “Slab” is not infinite, you can walk off the edge, it can also be placed anywhere you want, so the coordinate system is wack. Let me explain
Imagine for the sake of argument that the terrain “slab” is 10x10 units big. You place it so the bottom left corner of the slab is in the WORLD COORDINATE(-5, -5) so if you spawn in the world at WC(0,0) you would be standing in the center of the slab of terrain.

daigram 1you get me? 

So If I moved the terrain to WC(1,1), and you spawned at WC(0,0) you would just fall.
2 like that
 So now the awkward bit. That slab of terrain can be placed anywhere right? and inside it is a huge array of points yeah? So how can I tell where each point inside the slab is in the world co-ordianate system? I have to convert between the two systems, but how? like this!

function WorldToTerrainPosition(terrain : Terrain , mapRes : int ,worldPos : Vector3) {

var terrainPos : Vector3  = terrain.transform.position;
var sizeOfTerrain : Vector3  = terrain.terrainData.size;
var relativePos : Vector3  = worldPos - terrainPos;

var terrainX : float = relativePos.x/sizeOfTerrain.x*terrain.terrainData.heightmapWidth;

var terrainY : float = relativePos.y/sizeOfTerrain.y*terrain.terrainData.heightmapWidth;

var terrainZ : float = relativePos.z/sizeOfTerrain.z*terrain.terrainData.heightmapHeight;

return new Vector3(terrainX, terrainY, terrainZ);

So then, if your a future thinker, you can probably guess this is going to bite me in the ass later on. My sore ass tips it’s hat to you sir.

So where were we, we have the random data, applied to the terrain.
It looked crap, so a little bit of tweaking the algorithm and it looks like this: (click 4 bigger yo)

Day 3

So, the terrain slab contains the height ‘Pixels’, it also contains the data for the textures that are applied to the whole slab. How this worked is that the slab can have any number of textures assigned to it, let’s say 3 for now. A grass texture, a dirt/sand texture and a rocky texture. At any point in the slab you can have a mixture between any two of the assigned textures (YOU CANNOT BLEND MORE THAN TWO) So say where the landscape is really low, you have the grass texture painted there, and as it get’s a little higher it fades into the sand texture, eventually it’s just strait up sand. Then as it get’s a bit higher it starts to fade into the rock texture, until at like the peaks of the hills it’s strait up rock texture. The hard part of this is where the sand is, you have to make sure at no point are you trying to blend a little bit of grass with sand along with a little bit of rock.
and if you do it right, it looks like this 

The Next post will contain where it all went wrong.

Well it would have it I had remembered to write it while I still remembered all this

I’ll try to remember:

Something regarding the textures went wrong, and I ended up assuming it was a bug. Here is the report I submitted

1) What happened

The Terrain Texture Included within a TerrainData object does not Instantize in the same way as the Terrain Geometry in the same object. 
It’s hard to explain,  the Attached project demostrates the problem

2) How can we reproduce it using the example you attached

1. Open the project
#The code demonstrating the problem is”mainscript”
2. Start the game (play button)
3. The camera scrolls left, right, forward and backwards as the mouse moves close to the repective edge of the screen. The scroll wheel controls vertical movement.
The following keys have been setup to step through the functions in order, to demostrate the problem. R,T,Y,U,I,O
4. press:
R  = generate geometry on the terrain
T =  flatten the geometry
Y = Apply Texture to the terrain ( texture calcualted by height)

U= Add a grid of terrains to the scene
I  = apply random geometry to the grid
O = apply textures to the grid

The last step is where the problem lies. In the code listing each step is documented more for further explanation.

What should happen when O is pressed, is that textures are applied to all 9 terrains in the grid in turn, the texture depends on the height of the geometry. What actually happens is, when the texture for one terrain is calculated and applied, the same texture map is applied to all the terrains in the grid also, resulting in only one (the last grid terrain calculated) having the correct texture map applied. In the code comments I explain why I asusmed this was a bug rather than me not coding it correctly.

Thanks for reading.


The file I submitted to show the error is here

After that, I moved onto other stuff and completely forgot about this project, sorry, but I hope some day this post is of use to someone.