As you may know, we are currently working on ROTE Revolution, which is a 3D game with an Isometric camera and a top down view. In this new version we decided to add 3d elements and sceneries to our puzzle. That idea looked cool, but little did we know that we were running straight into a wall.
Here are some tips for you, in order to avoid having the same issues as we encountered, and also how to improve the look of your game!
At first, let’s talk about Isometric render; Isometric render was very popular back in the days with 2D games. In fact it was a cheap way to show a “3D” world with a 2D game engine.
Here is an example of two games released before 2000:
Isometric render is not visually accurate, but our brain could reconstruct the space, giving us the feeling to explore a full 3d environment. The basic rule, is that 1 feet displayed on screen will always have the same size anywhere on the screen. It’s commonly used for strategy games and classic RPG.
Let’s verify that rule of equal size by highlighting the grid of Landstalker. As you may notice, the grid is fitting perfectly, elements are spread across the grid. To show the height, Climax uses cubes over the grid, and the characters represent 1 unit on the floor with a height of 4 units.
It’s with the representation of the height that it get fishy. On Landstalker, it’s quite accurate, although the character looks terribly big compared to evergreen trees.
If the height was correct in isometric games, most of the time, you would only see the head and feet of your little fellow, just like in the first GTA and GTA 2.
Nowadays, to represent Isometric worlds, we tend to use the 3D engines rather than 2D engines (at least render the floor).That was already the case with Grandia in 1999; Complex elements were in 2d, and the floor was in 3D.
In a 3D isometric world, using 2D sprite to represent complex elements is a good idea. Indeed, as the sprite face the camera you can still cheat with heights.
With fully rendered 3D worlds, it is more difficult to cheat with height.
Indeed, the 3D engine render all elements with the correct size. So the artist can’t cheat, at least that’s what we thought.
Alundra 2 1999 (left) and Grandia 1999 (right)
While designing our new game ROTE revolution, we also encounter this “heights” problem. In the background of our game, we have wind turbines, but since they looked up to the camera they seemed really short like some sorts of dwarf turbines (see the picture on the right compared to the perspective view on the left)
That’s why we got the idea tilting all tall elements, to give this illusion of tallness.
Here is a few lines of C# for Unity3D (Apply It to the GameObject)
using UnityEngine; using System.Collections; public class IsoFix : MonoBehaviour { public bool fix = true; //If active is set to true, The fix will be applied at each frame, useful if the camera rotate public bool active = false; public Vector3 fixPosition = new Vector3(-45f, 0f, 0f); private void OnEnable () { Fix (); } private void Update () { if (active) Fix (); } private void Fix() { if (fix) this.transform.rotation = Quaternion.LookRotation( Camera.main.transform.forward ) * Quaternion.Euler (fixPosition); } }
Note that If you set the “active” boolean to “true” of IsoFix, it will follow your camera constantly:
After looking for a better solution, we stumbled upon an interview of Hiromasa Shikata about Zelda, where they revealed their tricks:
We went through a lot of trial and error with the top-down view. If you looked straight down from the top, all you could see was Link’s hat. So it looked like some mysterious green object moving around!
And Iwata also says :
A true top-down view actually has lots of problems. If you make it truthfully, it doesn’t look interesting at all. So you have to fake it-but in a good way.
That was a confirmation that we were not wrong about this “tilting tip” 🙂
Another Tip, is that we often tend to reuse the same asset over and over. We came up with a small script that randomizes it a bit for each model, so that each of them looks unique. (Left: Without the randomization, Right: Same assets, with the Randomizer script)
Here is our RandomizeObject script, it’s adapted to LowPoly objects with one color per 3d element.
using UnityEngine; using System.Collections; public class RandomizeObject : MonoBehaviour { public bool randomizeRotation = true; // This is necessary if you import your models from 3ds public bool rotationFix = false; public bool randomizeColor = false; public Color randomColor1; public Color randomColor2; public bool randomizeScale = true; public bool uniformScale = true; public float minScale = 0.8f; public float maxScale = 1.2f; void Start () { // Rotate the model if (randomizeRotation) { float fix = 0; if (rotationFix) { fix = -90; } this.transform.localRotation = Quaternion.Euler (this.transform.rotation.x + fix, this.transform.rotation.y, Random.Range (0, 360)); } // change a bit the seize of the model. if (randomizeScale) { if(uniformScale) { float v = Random.Range (minScale, maxScale); this.transform.localScale = new Vector3 (v, v, v); } else { float vX = Random.Range (minScale, maxScale); float vY = Random.Range (minScale, maxScale); float vZ = Random.Range (minScale, maxScale); this.transform.localScale = new Vector3 (vX, vY, vZ); } } // change a bit the colors. if (randomizeColor && randomColor1 != randomColor2) { this.gameObject.GetComponent<MeshRenderer> ().material.color = Color.Lerp(randomColor1, randomColor2, Random.value); } } }
I hope you liked this kind of articles, don’t hesitate to comment either below, or on our Twitter (@eXiin). If we get positive feedback, we might do more of them 🙂
That’s it for today!