Made script to control editor camera with keyboard

I made this script to make it easier to move the camera in the editor through use of the keyboard. Thought some of you might want it also. If you have an object selected, the camera will align to it, if you have multiple objects selected, the camera will align to a median point of all selected objects and if you have nothing selected, the camera will align to a point just in front of it.

Must be placed in a folder called “Editor” anywhere inside your assets folder.

The controls are Alt+1/2/3/4/5. 5 toggles orthographic.

EDIT: Updated code

using System.Collections;
using UnityEngine;
using UnityEditor;

[InitializeOnLoad]
public static class CameraKeyboardControlsEDITOR
{
    enum CameraView
    {
        ISOMETRIC, ABOVE, FRONT, RIGHT
    }

    [MenuItem("Camera/Top &1")]
    static void MenuSetCameraFront()
    {
        MenuSetCameraForBoard(CameraView.FRONT);
    }

    [MenuItem("Camera/Right &2")]
    static void MenuSetCameraRight()
    {
        MenuSetCameraForBoard(CameraView.RIGHT);
    }

    [MenuItem("Camera/Above &3")]
    static void MenuSetCameraAbove()
    {
        MenuSetCameraForBoard(CameraView.ABOVE);
    }

    [MenuItem("Camera/Isometric &4")]
    static void MenuSetCameraInGame()
    {
        MenuSetCameraForBoard(CameraView.ISOMETRIC);
    }

    [MenuItem("Camera/Toggle Orthographic &5")]
    static void MenuSetCameraOrthographic()
    {
        var scene_view = UnityEditor.SceneView.lastActiveSceneView;
        scene_view.orthographic = !scene_view.orthographic;
    }

    static void MenuSetCameraForBoard(CameraView view)
    {
        bool usedTemp = false, gotMedianForMultipleObjects = false;
        GameObject go = null;
        var scene_view = UnityEditor.SceneView.lastActiveSceneView;

        if (Selection.gameObjects.Length == 1)
        {
            go = Selection.gameObjects[0];
        }
        else if (Selection.gameObjects.Length > 1)
        {
            Vector3 pos = GetMedianPointOfSelection();

            // create a dummy to act as focus point
            go = new GameObject("<temp>");
            go.transform.position = pos;
            usedTemp = true;
            gotMedianForMultipleObjects = true;
        }

        if (go == null)
        {
            // create a dummy to act as focus point
            go = new GameObject("<temp>");
            go.transform.position = scene_view.camera.transform.position + (scene_view.camera.transform.forward * 5f);
            usedTemp = true;
        }

        // aligning view in perspective mode makes the camera zoom in way to far.
        // To fix, switch to ortho temporarily.
        bool ortho = scene_view.orthographic;
        scene_view.orthographic = true;

        SetCameraView(go.transform.position, view);

        scene_view.orthographic = ortho; // reset

        if (usedTemp)
        {
            GameObject.DestroyImmediate(go);
            if (!gotMedianForMultipleObjects)
            {
                Selection.activeGameObject = null; // clear selection
            }
        }
    }

    static Vector3 GetMedianPointOfSelection()
    {
        GameObject[] gos = Selection.gameObjects;
        var bounds = new Bounds(gos[0].transform.position, Vector3.zero);
        for (var i = 1; i < gos.Length; i++)
            bounds.Encapsulate(gos[i].transform.position);
        return bounds.center;
    }

    static void SetCameraView(Vector3 cam_position, CameraView view)
    {
        EditorApplication.ExecuteMenuItem("Window/Scene");

        var scene_view = UnityEditor.SceneView.lastActiveSceneView;
        if (scene_view != null)
        {
            var target = scene_view.camera;
            target.transform.position = cam_position;

            if (view == CameraView.ABOVE)
            {
                target.transform.rotation = Quaternion.LookRotation(Vector3.down);
            }
            else if (view == CameraView.FRONT)
            {
                target.transform.rotation = Quaternion.LookRotation(Vector3.forward);
            }
            else if (view == CameraView.RIGHT)
            {
                target.transform.rotation = Quaternion.LookRotation(Vector3.left);
            }
            else if (view == CameraView.ISOMETRIC)
            {
                target.transform.rotation = Quaternion.Euler(new Vector3(45f, -45f, 0));
            }

            scene_view.AlignViewToObject(target.transform);
        }
    }
}
1 Like

This is actually pretty useful. I spent a while simplifying the code (and testing it and fixing it and simplifying more), and I rather like how it came out. I believe it does essentially the same thing, but puts them as shortcuts you can bind under Scene View, rather than menu items.

(I guess I changed the order and default keys too, I didn’t like isometric so close to orthographic, I hit it by accident.)

using UnityEngine;
using UnityEditor;
using UnityEditor.ShortcutManagement;

#pragma warning disable IDE0051 // Stop warnings about unused functions, they are actually used because of Unity attributes

public static class FocusCam
{
    private static Vector3 isometric = new Vector3(-1f, -1f, 1f).normalized;

    [Shortcut("Scene View/Look at selection, isometric", KeyCode.Alpha1, ShortcutModifiers.Alt)]
    static void SetCameraIsometric()
    {
        SetCameraView(isometric);
    }

    [Shortcut("Scene View/Look at selection, from behind", KeyCode.Alpha2, ShortcutModifiers.Alt)]
    static void SetCameraBehind()
    {
        SetCameraView(Vector3.forward);
    }

    [Shortcut("Scene View/Look at selection, from top", KeyCode.Alpha3, ShortcutModifiers.Alt)]
    static void SetCameraTop()
    {
        SetCameraView(Vector3.down);
    }

    [Shortcut("Scene View/Look at selection, from right side", KeyCode.Alpha4, ShortcutModifiers.Alt)]
    static void SetCameraRight()
    {
        SetCameraView(-Vector3.right);
    }

    [Shortcut("Scene View/Toggle Orthographic", KeyCode.Alpha5, ShortcutModifiers.Alt)]
    static void ToggleOrthographic()
    {
        SceneView.lastActiveSceneView.orthographic = !SceneView.lastActiveSceneView.orthographic;
    }

    static void SetCameraView(Vector3 viewFromDirection)
    {
        var view = SceneView.lastActiveSceneView;
        if (view != null)
        {
            view.LookAt(view.pivot, Quaternion.LookRotation(viewFromDirection));    //gets the angle right (without teleporting there)
            view.FrameSelected(false);      //frames the selection and gets the distance right, order on these is important, unless lockView == true, in which case buggy
        }
    }
}