A Unity editor script for enabling pre-2018.x scene view camera behaviour for arrow keys.
using UnityEngine; | |
using UnityEditor; | |
using System.Collections.Generic; | |
/// <summary> | |
/// Re-enables pre-2018.x scene view camera behaviour for arrow keys. | |
/// Allows the user to move the scene view camera on a horizontal plane. | |
/// </summary> | |
public static class ClassicEditorArrowMovement | |
{ | |
public static float speed = 10f; | |
public static float shiftSpeed = 30f; | |
private static bool up; | |
private static bool down; | |
private static bool left; | |
private static bool right; | |
private static bool shift; | |
private static SceneView previousSceneView; | |
private static double lastEditorTime; | |
[InitializeOnLoadMethod] | |
private static void Initialize() | |
{ | |
SceneView.onSceneGUIDelegate += OnSceneGUI; | |
EditorApplication.update += UpdateSceneViews; | |
} | |
private static void OnSceneGUI(SceneView sceneView) | |
{ | |
if (sceneView != previousSceneView) return; | |
var e = Event.current; | |
if (e.type == EventType.KeyDown || e.type == EventType.KeyUp) | |
{ | |
if (HandleArrowKey(e.keyCode, sceneView, e.type == EventType.KeyDown)) | |
{ | |
e.Use(); | |
} | |
} | |
shift = e.shift; | |
} | |
/// <summary> | |
/// Sets this class's bools depending on which arrow key was pressed or released. | |
/// Returns true if the keyCode was an arrow key, false otherwise. | |
/// </summary> | |
private static bool HandleArrowKey(KeyCode keyCode, SceneView sceneView, bool pressed) | |
{ | |
switch (keyCode) | |
{ | |
case KeyCode.UpArrow: | |
up = pressed; | |
return true; | |
case KeyCode.DownArrow: | |
down = pressed; | |
return true; | |
case KeyCode.LeftArrow: | |
left = pressed; | |
return true; | |
case KeyCode.RightArrow: | |
right = pressed; | |
return true; | |
default: | |
return false; | |
} | |
} | |
private static void UpdateSceneViews() | |
{ | |
var activeSceneView = SceneView.lastActiveSceneView; | |
if(activeSceneView != previousSceneView) | |
{ | |
ResetDirection(); | |
} | |
if(activeSceneView) | |
{ | |
ApplyCameraMovement(activeSceneView); | |
} | |
previousSceneView = activeSceneView; | |
} | |
private static void ResetDirection() | |
{ | |
up = down = left = right = shift = false; | |
} | |
/// <summary> | |
/// Moves the camera of the given SceneView depending on the class's bools. | |
/// </summary> | |
private static void ApplyCameraMovement(SceneView sceneView) | |
{ | |
var deltaTime = (float)(EditorApplication.timeSinceStartup - lastEditorTime); | |
lastEditorTime = EditorApplication.timeSinceStartup; | |
var direction = GetHorizontalDirectionRelativeTo(sceneView.camera.transform); | |
direction = Vector3.ClampMagnitude(direction, 1); | |
sceneView.pivot += direction | |
* (shift ? shiftSpeed : speed) | |
* deltaTime; | |
} | |
/// <summary> | |
/// Gets a horizontal Vector3 (y = 0) that is the direction as defined by the up/down/left/right bools, | |
/// aligned to the rotation of the given Transform. | |
/// </summary> | |
private static Vector3 GetHorizontalDirectionRelativeTo(Transform t) | |
{ | |
var result = Vector3.zero; | |
result += GetHorizontalOrZero(t.forward, up); | |
result += GetHorizontalOrZero(-t.forward, down); | |
result += GetHorizontalOrZero(-t.right, left); | |
result += GetHorizontalOrZero(t.right, right); | |
if (result != Vector3.zero) | |
{ | |
result = result.normalized; | |
} | |
return result; | |
} | |
private static Vector3 GetHorizontalOrZero(Vector3 v, bool notZero) | |
{ | |
if (!notZero) | |
{ | |
return Vector3.zero; | |
} | |
v.y = 0; | |
return v; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment