Isometric Camera with Unity

Share:Tweet about this on TwitterShare on RedditPin on PinterestShare on FacebookShare on LinkedInShare on Google+

 
I like real time cameras subject so much that I already made a post on real time cameras (here) specifically on third person cameras. This time I will show you how I set up a simple isometric camera for a game prototype I made in Unity.

 

The isometric camera

Basically an isometric camera has an isometric view in which the perspectives are avoided, it’s like having a “zero-point” perspective instead of the three-point perspective you normally have on a classic first or third person camera. As you can see, there are no perspective deformations on what the camera sees, for example, with isometric view, all the edges of the cube are parallel. Technically, by having a an isometric view, the camera is already isometric, but on top of that, in games this view is classically used used with a 45° degree rotation.

This type of camera was used a lot in the past (especially on the 16-bit era) in games like Q Bert, this first Diablo, the first Fallout and Age of Empires, mainly to give more sense of three dimensional space with a minimal computational effort. Lately it is used for nostalgic reasons and for specific artistic or design choices in games like Monument Valley.

 

The camera script

The only thing you have to do it in order to use my simple isometric camera is to add this script to a Gameobject. Since the script require a Camera, it will add it for you. When the script starts, it creates all the things needed to run an isometric camera, which essentially are a target to look to and some other Gameobjects used for camera movements (which I will show you in a minute).

Then the most important part is camera settings and rotation. The camera has (obviously) to be orthographic otherwise we have perspective involved and we don’t want it. For the rotation of the camera, I chose to make the camera a child of the target and to rotate the target instead of rotating the camera itself, just because it seems more logical to me to apply the further movements and rotations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void Awake()
{
    //Objects creation
    GameObject target = new GameObject("Camera Target");
    GameObject movableRef = new GameObject("ISO Camera Movement");
    movableRef.transform.localEulerAngles = new Vector3(0, 0, 0);
    m_IsoMov = movableRef.AddComponent<IsoMovementController>();
    m_IsoMov.init(speed, limits, invertedXAxis, invertedYAxis);

    //Camera settings
    m_Camera = GetComponent<Camera>();
    m_Camera.orthographic = true;
    m_Camera.tag = "MainCamera";
    m_Camera.orthographicSize = 20f;
    m_Camera.backgroundColor = new Color(.3f, .3f, .3f);

    //Camera positioning and objects parenting
    GetComponent<Camera>().transform.position = new Vector3(0f, 0f, -50);
    GetComponent<Camera>().transform.parent = target.transform;
    target.transform.parent = movableRef.transform;
    target.transform.localEulerAngles = new Vector3(45, 45, 0);
}

 

Camera motion

While creating this camera, I wanted to add a little bit of movements and even a rotation. To do this, I created a second script and attached to the parent of the camera target, the controller. In this way the controller rotates and moves the target (in real time), and the target has rotated (and keeps the rotation of) the camera. That’s the reason of all of those objects in camera creation.

Movements

For the movements I just taken the vertical and horizontal axis and translate accordingly but within a certain limits (setted in the inspector), in this way we can’t get outside of a certain scene or environment.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void FixedUpdate ()
{
    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");

    if(!h.Equals(0f) || !v.Equals(0f))
    {  
        Vector3 trans = new Vector3(h*.5f + v*.5f, 0, v*.5f - h*.5f);
        transform.Translate(trans * speed *  Time.deltaTime, transform);

        Vector3 pos = transform.position;
        pos.x = Mathf.Clamp(pos.x, -limits.max_X, limits.max_X);
        pos.y = Mathf.Clamp(pos.y, -limits.max_Y, limits.max_Y);
        pos.z = Mathf.Clamp(pos.z, -limits.max_Z, limits.max_Z);
        transform.position = pos;
    }
}

 

Rotation

As a reference for the rotations I took the camera from the game Anno 2070, which can rotate towards the target (on the horizontal plane) of a certain angle. I wanted something similar but more defined: I wanted the rotation step to be 90°. In this way when the camera has finished rotating, you are still in a isometric view but you are looking at another side of the scene. This concept of having a rotation step I saw it on Fez, which is a 2D game, where you can rotate the camera, 90° degree at the time. It is actually a 3D game. Here’s the code for the rotations.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void FixedUpdate ()
{
    if (Input.GetButtonDown("Jump"))
    {
       
        if (!m_IsRotating)
        {
            float c_rot = Input.GetAxis("Jump");
            Debug.Log(c_rot);

            m_IsRotating = true;
            m_DesiredRot = transform.rotation;
            m_DesiredRot *= Quaternion.Euler(0, 90*Math.Sign(c_rot), 0);
        }
    }
}

[...]

void Update()
{
    if (m_IsRotating)
    {
        m_RotationData.rot_value = Mathf.Lerp(m_RotationData.rot_value, m_RotationData.rot_sp_max, Time.deltaTime);
        transform.rotation = Quaternion.Slerp(transform.rotation, m_DesiredRot, Time.deltaTime * m_RotationData.rot_value);
        if((m_DesiredRot.eulerAngles - transform.rotation.eulerAngles).sqrMagnitude < 0.1)
        {
            m_RotationData.reset();
            transform.rotation = m_DesiredRot;
            m_IsRotating = false;
        }
    }
}

 

Final results

This camera works great (with some adjustments), for example for infinite runners or strategic games that need to have a top view of the “game board”. In order to work properly, however, the 3D models you put in the scene have to be created for an isometric view.

You can find the full Unity project right here (with a beautiful voxel model I made) feel free to use it and modify it.

Unity Project

Game developer & designer. Unity 3D lover. Movie fanatic.

Game developer & designer. Unity 3D lover. Movie fanatic.