using System; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif public abstract class SpaceNavigator : IDisposable { // Public runtime API public static Vector3 Translation { get { return Instance.GetTranslation(); } } public static Quaternion Rotation { get { return Instance.GetRotation(); } } public static Quaternion RotationInLocalCoordSys(Transform coordSys) { return coordSys.rotation * Rotation * Quaternion.Inverse(coordSys.rotation); } public static void SetTranslationSensitivity(float newPlayTransSens) { Instance.PlayTransSens = newPlayTransSens; } public static void SetRotationSensitivity(float newPlayRotSens) { Instance.PlayRotSens = newPlayRotSens; } /// /// Locking can be disabled by the SpaceNavigatorWindow; /// public static bool LockTranslationX { // At runtime we don't want to limit the output of the driver, its up to the game scripts to do that. get { return _lockTranslationX && !Application.isPlaying; } set { _lockTranslationX = value; } } public static bool LockTranslationY { // At runtime we don't want to limit the output of the driver, its up to the game scripts to do that. get { return _lockTranslationY && !Application.isPlaying; } set { _lockTranslationY = value; } } public static bool LockTranslationZ { // At runtime we don't want to limit the output of the driver, its up to the game scripts to do that. get { return _lockTranslationZ && !Application.isPlaying; } set { _lockTranslationZ = value; } } public static bool LockTranslationAll { // At runtime we don't want to limit the output of the driver, its up to the game scripts to do that. get { return _lockTranslationAll && !Application.isPlaying; } set { _lockTranslationAll = value; } } public static bool LockRotationX { // At runtime we don't want to limit the output of the driver, its up to the game scripts to do that. get { return _lockRotationX && !Application.isPlaying; } set { _lockRotationX = value; } } public static bool LockRotationY { // At runtime we don't want to limit the output of the driver, its up to the game scripts to do that. get { return _lockRotationY && !Application.isPlaying; } set { _lockRotationY = value; } } public static bool LockRotationZ { // At runtime we don't want to limit the output of the driver, its up to the game scripts to do that. get { return _lockRotationZ && !Application.isPlaying; } set { _lockRotationZ = value; } } public static bool LockRotationAll { // At runtime we don't want to limit the output of the driver, its up to the game scripts to do that. get { return _lockRotationAll && !Application.isPlaying; } set { _lockRotationAll = value; } } private static bool _lockTranslationX; private static bool _lockTranslationY; private static bool _lockTranslationZ; private static bool _lockTranslationAll; private static bool _lockRotationX; private static bool _lockRotationY; private static bool _lockRotationZ; private static bool _lockRotationAll; // Abstract members public abstract Vector3 GetTranslation(); public abstract Quaternion GetRotation(); // Sensitivity settings private int Gears = 3; public int CurrentGear = 1; public const float TransSensScale = 0.001f, RotSensScale = 0.0015f; public const float TransSensDefault = 1f, TransSensMinDefault = 0.1f, TransSensMaxDefault = 10f; public float PlayTransSens = TransSensDefault; public List TransSens = new List { 0.05f, 1, 50 }; public List TransSensMin = new List() { 0, 0, 0 }; public List TransSensMax = new List() { 1, 10, 100 }; public const float RotSensDefault = 1, RotSensMinDefault = 0, RotSensMaxDefault = 5f; public float PlayRotSens = RotSensDefault; public float RotSens = RotSensDefault; public float RotSensMin = RotSensMinDefault; public float RotSensMax = RotSensMaxDefault; // Setting storage keys private const string TransSensKey = "Translation sensitivity"; private const string TransSensMinKey = "Translation sensitivity minimum"; private const string TransSensMaxKey = "Translation sensitivity maximum"; private const string LockTranslationAllKey = "Translation lock all"; private const string LockTranslationXKey = "Translation lock X"; private const string LockTranslationYKey = "Translation lock Y"; private const string LockTranslationZKey = "Translation lock Z"; private const string RotSensKey = "Rotation sensitivity"; private const string RotSensMinKey = "Rotation sensitivity minimum"; private const string RotSensMaxKey = "Rotation sensitivity maximum"; private const string LockRotationAllKey = "Rotation lock all"; private const string LockRotationXKey = "Rotation lock X"; private const string LockRotationYKey = "Rotation lock Y"; private const string LockRotationZKey = "Rotation lock Z"; #region - Singleton - public static SpaceNavigator Instance { get { if (_instance == null) { switch (Application.platform) { case RuntimePlatform.OSXEditor: case RuntimePlatform.OSXPlayer: Debug.LogError("Mac version of the SpaceNavigator driver is not yet implemented, sorry"); _instance = SpaceNavigatorNoDevice.SubInstance; break; case RuntimePlatform.WindowsEditor: case RuntimePlatform.WindowsPlayer: _instance = SpaceNavigatorWindows.SubInstance; break; } } return _instance; } set { _instance = value; } } private static SpaceNavigator _instance; #endregion - Singleton - #region - IDisposable - public abstract void Dispose(); #endregion - IDisposable - public virtual void OnGUI() { #if UNITY_EDITOR #region - Locking - #region - Translation - GUILayout.BeginHorizontal(); _lockTranslationAll = GUILayout.Toggle(_lockTranslationAll, "Translation\t"); GUI.enabled = !_lockTranslationAll; _lockTranslationX = GUILayout.Toggle(_lockTranslationX, "X"); _lockTranslationY = GUILayout.Toggle(_lockTranslationY, "Y"); _lockTranslationZ = GUILayout.Toggle(_lockTranslationZ, "Z"); GUI.enabled = true; GUILayout.EndHorizontal(); #endregion - Translation - #region - Rotation - GUILayout.BeginHorizontal(); _lockRotationAll = GUILayout.Toggle(_lockRotationAll, "Rotation\t\t"); GUI.enabled = !_lockRotationAll; _lockRotationX = GUILayout.Toggle(_lockRotationX, "X"); _lockRotationY = GUILayout.Toggle(_lockRotationY, "Y"); _lockRotationZ = GUILayout.Toggle(_lockRotationZ, "Z"); GUI.enabled = true; GUILayout.EndHorizontal(); #endregion - Rotation - #endregion - Locking - GUILayout.Space(10); #region - Sensitivity + gearbox - GUILayout.BeginHorizontal(); #region - Sensitivity - GUILayout.BeginVertical(); GUILayout.Label("Sensitivity"); GUILayout.Space(4); #region - Translation + rotation - GUILayout.BeginVertical(); #region - Translation - GUILayout.BeginHorizontal(); GUILayout.Label("Translation", GUILayout.Width(67)); TransSens[CurrentGear] = EditorGUILayout.FloatField(TransSens[CurrentGear], GUILayout.Width(30)); TransSensMin[CurrentGear] = EditorGUILayout.FloatField(TransSensMin[CurrentGear], GUILayout.Width(30)); TransSens[CurrentGear] = GUILayout.HorizontalSlider(TransSens[CurrentGear], TransSensMin[CurrentGear], TransSensMax[CurrentGear]); TransSensMax[CurrentGear] = EditorGUILayout.FloatField(TransSensMax[CurrentGear], GUILayout.Width(30)); GUILayout.EndHorizontal(); #endregion - Translation - #region - Rotation - GUILayout.BeginHorizontal(); GUILayout.Label("Rotation", GUILayout.Width(67)); RotSens = EditorGUILayout.FloatField(RotSens, GUILayout.Width(30)); RotSensMin = EditorGUILayout.FloatField(RotSensMin, GUILayout.Width(30)); RotSens = GUILayout.HorizontalSlider(RotSens, RotSensMin, RotSensMax); RotSensMax = EditorGUILayout.FloatField(RotSensMax, GUILayout.Width(30)); GUILayout.EndHorizontal(); #endregion - Rotation - GUILayout.EndVertical(); #endregion - Translation + rotation - GUILayout.EndVertical(); #endregion - Sensitivity - #region - Gearbox - GUILayout.BeginVertical(); GUILayout.Label("Scale", GUILayout.Width(65)); GUIContent[] modes = new GUIContent[] { new GUIContent("Huge", "Galactic scale"), new GUIContent("Human", "What people consider 'normal'"), new GUIContent("Minuscule", "Itsy-bitsy-scale") }; CurrentGear = GUILayout.SelectionGrid(CurrentGear, modes, 1, GUILayout.Width(67)); GUILayout.EndVertical(); #endregion - Gearbox - GUILayout.EndHorizontal(); #endregion - Sensitivity + gearbox - #endif } #region - Settings - /// /// Reads the settings. /// public void ReadSettings() { for (int gear = 0; gear < Gears; gear++) { TransSens[gear] = PlayerPrefs.GetFloat(TransSensKey + gear, TransSensDefault); TransSensMin[gear] = PlayerPrefs.GetFloat(TransSensMinKey + gear, TransSensMinDefault); TransSensMax[gear] = PlayerPrefs.GetFloat(TransSensMaxKey + gear, TransSensMaxDefault); } _lockTranslationAll = PlayerPrefs.GetInt(LockTranslationAllKey, 0) == 1; _lockTranslationX = PlayerPrefs.GetInt(LockTranslationXKey, 0) == 1; _lockTranslationY = PlayerPrefs.GetInt(LockTranslationYKey, 0) == 1; _lockTranslationZ = PlayerPrefs.GetInt(LockTranslationZKey, 0) == 1; RotSens = PlayerPrefs.GetFloat(RotSensKey, RotSensDefault); RotSensMin = PlayerPrefs.GetFloat(RotSensMinKey, RotSensMinDefault); RotSensMax = PlayerPrefs.GetFloat(RotSensMaxKey, RotSensMaxDefault); _lockRotationAll = PlayerPrefs.GetInt(LockRotationAllKey, 0) == 1; _lockRotationX = PlayerPrefs.GetInt(LockRotationXKey, 0) == 1; _lockRotationY = PlayerPrefs.GetInt(LockRotationYKey, 0) == 1; _lockRotationZ = PlayerPrefs.GetInt(LockRotationZKey, 0) == 1; } /// /// Writes the settings. /// public void WriteSettings() { for (int gear = 0; gear < Gears; gear++) { PlayerPrefs.SetFloat(TransSensKey + gear, TransSens[gear]); PlayerPrefs.SetFloat(TransSensMinKey + gear, TransSensMin[gear]); PlayerPrefs.SetFloat(TransSensMaxKey + gear, TransSensMax[gear]); } PlayerPrefs.SetInt(LockTranslationAllKey, _lockTranslationAll ? 1 : 0); PlayerPrefs.SetInt(LockTranslationXKey, _lockTranslationX ? 1 : 0); PlayerPrefs.SetInt(LockTranslationYKey, _lockTranslationY ? 1 : 0); PlayerPrefs.SetInt(LockTranslationZKey, _lockTranslationZ ? 1 : 0); PlayerPrefs.SetFloat(RotSensKey, RotSens); PlayerPrefs.SetFloat(RotSensMinKey, RotSensMin); PlayerPrefs.SetFloat(RotSensMaxKey, RotSensMax); PlayerPrefs.SetInt(LockRotationAllKey, _lockRotationAll ? 1 : 0); PlayerPrefs.SetInt(LockRotationXKey, _lockRotationX ? 1 : 0); PlayerPrefs.SetInt(LockRotationYKey, _lockRotationY ? 1 : 0); PlayerPrefs.SetInt(LockRotationZKey, _lockRotationZ ? 1 : 0); } #endregion - Settings - }