You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1670 lines
48 KiB

/**
* 7/8/2013
*/
#define PRO
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Reflection;
using System;
using System.Linq;
namespace ProGrids
{
[InitializeOnLoad]
public static class pg_Initializer
{
/**
* When opening Unity, remember whether or not ProGrids was open when Unity was shut down last.
*/
static pg_Initializer()
{
if (EditorPrefs.GetBool(pg_Constant.ProGridsIsEnabled))
{
if (pg_Editor.instance == null)
pg_Editor.InitProGrids();
else
EditorApplication.delayCall += pg_Editor.instance.Initialize;
}
}
}
public class pg_Editor : ScriptableObject, ISerializationCallbackReceiver
{
#region MEMBERS
public static pg_Editor instance
{
get
{
if (_instance == null)
{
pg_Editor[] editor = Resources.FindObjectsOfTypeAll<pg_Editor>();
if (editor != null && editor.Length > 0)
{
_instance = editor[0];
for (int i = 1; i < editor.Length; i++)
{
GameObject.DestroyImmediate(editor[i]);
}
}
}
return _instance;
}
set
{
_instance = value;
}
}
private static pg_Editor _instance;
Color oldColor;
private bool useAxisConstraints
{
get { return EditorPrefs.GetBool(pg_Constant.UseAxisConstraints); }
set { EditorPrefs.SetBool(pg_Constant.UseAxisConstraints, value); }
}
[SerializeField]
private bool snapEnabled = true;
[SerializeField]
private SnapUnit snapUnit = SnapUnit.Meter;
#if PRO
private float snapValue = 1f; // the actual snap value, taking into account unit size
private float t_snapValue = 1f; // what the user sees
#else
private float snapValue = .25f;
private float t_snapValue = .25f;
#endif
private bool drawGrid = true;
private bool drawAngles = false;
public float angleValue = 45f;
private bool gridRepaint = true;
public bool predictiveGrid = true;
private bool _snapAsGroup = true;
public bool snapAsGroup
{
get
{
return EditorPrefs.HasKey(pg_Constant.SnapAsGroup) ? EditorPrefs.GetBool(pg_Constant.SnapAsGroup) : true;
}
set
{
_snapAsGroup = value;
EditorPrefs.SetBool(pg_Constant.SnapAsGroup, _snapAsGroup);
}
}
public bool fullGrid { get; private set; }
private bool _scaleSnapEnabled = false;
public bool ScaleSnapEnabled
{
get
{
return EditorPrefs.HasKey(pg_Constant.SnapScale) ? EditorPrefs.GetBool(pg_Constant.SnapScale) : false;
}
set
{
_scaleSnapEnabled = value;
EditorPrefs.SetBool(pg_Constant.SnapScale, _scaleSnapEnabled);
}
}
private KeyCode m_IncreaseGridSizeShortcut = KeyCode.Equals;
private KeyCode m_DecreaseGridSizeShortcut = KeyCode.Minus;
private KeyCode m_NudgePerspectiveBackwardShortcut = KeyCode.LeftBracket;
private KeyCode m_NudgePerspectiveForwardShortcut = KeyCode.RightBracket;
private KeyCode m_NudgePerspectiveResetShortcut = KeyCode.Alpha0;
private KeyCode m_CyclePerspectiveShortcut = KeyCode.Backslash;
bool lockGrid = false;
private Axis renderPlane = Axis.Y;
#if PG_DEBUG
private GameObject _pivotGo;
public GameObject pivotGo
{
get
{
if(_pivotGo == null)
{
GameObject find = GameObject.Find("PG_PIVOT_CUBE");
if(find == null)
{
_pivotGo = GameObject.CreatePrimitive(PrimitiveType.Cube);
_pivotGo.name = "PG_PIVOT_CUBE";
}
else
_pivotGo = find;
}
return _pivotGo;
}
set
{
_pivotGo = value;
}
}
#endif
#endregion
#region CONSTANT
const int VERSION = 22;
#if PRO
const int WINDOW_HEIGHT = 240;
#else
const int WINDOW_HEIGHT = 260;
#endif
const int DEFAULT_SNAP_MULTIPLIER = 2048;
const int MAX_LINES = 150; // the maximum amount of lines to display on screen in either direction
public static float alphaBump; // Every tenth line gets an alpha bump by this amount
const int BUTTON_SIZE = 46;
private Texture2D icon_extendoClose, icon_extendoOpen;
[SerializeField]
private pg_ToggleContent gc_SnapToGrid = new pg_ToggleContent("Snap", "", "Snaps all selected objects to grid.");
[SerializeField]
private pg_ToggleContent gc_GridEnabled = new pg_ToggleContent("Hide", "Show", "Toggles drawing of guide lines on or off. Note that object snapping is not affected by this setting.");
[SerializeField]
private pg_ToggleContent gc_SnapEnabled = new pg_ToggleContent("On", "Off", "Toggles snapping on or off.");
[SerializeField]
private pg_ToggleContent gc_LockGrid = new pg_ToggleContent("Lock", "Unlck", "Lock the perspective grid center in place.");
[SerializeField]
private pg_ToggleContent gc_AngleEnabled = new pg_ToggleContent("> On", "> Off", "If on, ProGrids will draw angled line guides. Angle is settable in degrees.");
[SerializeField]
private pg_ToggleContent gc_RenderPlaneX = new pg_ToggleContent("X", "X", "Renders a grid on the X plane.");
[SerializeField]
private pg_ToggleContent gc_RenderPlaneY = new pg_ToggleContent("Y", "Y", "Renders a grid on the Y plane.");
[SerializeField]
private pg_ToggleContent gc_RenderPlaneZ = new pg_ToggleContent("Z", "Z", "Renders a grid on the Z plane.");
[SerializeField]
private pg_ToggleContent gc_RenderPerspectiveGrid = new pg_ToggleContent("Full", "Plane", "Renders a 3d grid in perspective mode.");
[SerializeField]
private GUIContent gc_ExtendMenu = new GUIContent("", "Show or hide the scene view menu.");
[SerializeField]
private GUIContent gc_SnapIncrement = new GUIContent("", "Set the snap increment.");
#endregion
#region PREFERENCES
/** Settings **/
public Color gridColorX, gridColorY, gridColorZ;
public Color gridColorX_primary, gridColorY_primary, gridColorZ_primary;
// private bool lockOrthographic;
public void LoadPreferences()
{
if ((EditorPrefs.HasKey(pg_Constant.PGVersion) ? EditorPrefs.GetInt(pg_Constant.PGVersion) : 0) != VERSION)
{
EditorPrefs.SetInt(pg_Constant.PGVersion, VERSION);
pg_Preferences.ResetPrefs();
}
if (EditorPrefs.HasKey(pg_Constant.SnapEnabled))
{
snapEnabled = EditorPrefs.GetBool(pg_Constant.SnapEnabled);
}
menuOpen = EditorPrefs.GetBool(pg_Constant.ProGridsIsExtended, true);
SetSnapValue(
EditorPrefs.HasKey(pg_Constant.GridUnit) ? (SnapUnit)EditorPrefs.GetInt(pg_Constant.GridUnit) : SnapUnit.Meter,
EditorPrefs.HasKey(pg_Constant.SnapValue) ? EditorPrefs.GetFloat(pg_Constant.SnapValue) : 1,
EditorPrefs.HasKey(pg_Constant.SnapMultiplier) ? EditorPrefs.GetInt(pg_Constant.SnapMultiplier) : DEFAULT_SNAP_MULTIPLIER
);
m_IncreaseGridSizeShortcut = EditorPrefs.HasKey("pg_Editor::IncreaseGridSize")
? (KeyCode)EditorPrefs.GetInt("pg_Editor::IncreaseGridSize")
: KeyCode.Equals;
m_DecreaseGridSizeShortcut = EditorPrefs.HasKey("pg_Editor::DecreaseGridSize")
? (KeyCode)EditorPrefs.GetInt("pg_Editor::DecreaseGridSize")
: KeyCode.Minus;
m_NudgePerspectiveBackwardShortcut = EditorPrefs.HasKey("pg_Editor::NudgePerspectiveBackward")
? (KeyCode)EditorPrefs.GetInt("pg_Editor::NudgePerspectiveBackward")
: KeyCode.LeftBracket;
m_NudgePerspectiveForwardShortcut = EditorPrefs.HasKey("pg_Editor::NudgePerspectiveForward")
? (KeyCode)EditorPrefs.GetInt("pg_Editor::NudgePerspectiveForward")
: KeyCode.RightBracket;
m_NudgePerspectiveResetShortcut = EditorPrefs.HasKey("pg_Editor::NudgePerspectiveReset")
? (KeyCode)EditorPrefs.GetInt("pg_Editor::NudgePerspectiveReset")
: KeyCode.Alpha0;
m_CyclePerspectiveShortcut = EditorPrefs.HasKey("pg_Editor::CyclePerspective")
? (KeyCode)EditorPrefs.GetInt("pg_Editor::CyclePerspective")
: KeyCode.Backslash;
lockGrid = EditorPrefs.GetBool(pg_Constant.LockGrid);
if (lockGrid)
{
if (EditorPrefs.HasKey(pg_Constant.LockedGridPivot))
{
string piv = EditorPrefs.GetString(pg_Constant.LockedGridPivot);
string[] pivsplit = piv.Replace("(", "").Replace(")", "").Split(',');
float x, y, z;
if (!float.TryParse(pivsplit[0], out x)) goto NoParseForYou;
if (!float.TryParse(pivsplit[1], out y)) goto NoParseForYou;
if (!float.TryParse(pivsplit[2], out z)) goto NoParseForYou;
pivot.x = x;
pivot.y = y;
pivot.z = z;
NoParseForYou:
; // appease the compiler
}
}
fullGrid = EditorPrefs.GetBool(pg_Constant.PerspGrid);
renderPlane = EditorPrefs.HasKey(pg_Constant.GridAxis) ? (Axis)EditorPrefs.GetInt(pg_Constant.GridAxis) : Axis.Y;
alphaBump = (EditorPrefs.HasKey("pg_alphaBump")) ? EditorPrefs.GetFloat("pg_alphaBump") : pg_Preferences.ALPHA_BUMP;
gridColorX = (EditorPrefs.HasKey("gridColorX")) ? pg_Util.ColorWithString(EditorPrefs.GetString("gridColorX")) : pg_Preferences.GRID_COLOR_X;
gridColorX_primary = new Color(gridColorX.r, gridColorX.g, gridColorX.b, gridColorX.a + alphaBump);
gridColorY = (EditorPrefs.HasKey("gridColorY")) ? pg_Util.ColorWithString(EditorPrefs.GetString("gridColorY")) : pg_Preferences.GRID_COLOR_Y;
gridColorY_primary = new Color(gridColorY.r, gridColorY.g, gridColorY.b, gridColorY.a + alphaBump);
gridColorZ = (EditorPrefs.HasKey("gridColorZ")) ? pg_Util.ColorWithString(EditorPrefs.GetString("gridColorZ")) : pg_Preferences.GRID_COLOR_Z;
gridColorZ_primary = new Color(gridColorZ.r, gridColorZ.g, gridColorZ.b, gridColorZ.a + alphaBump);
drawGrid = (EditorPrefs.HasKey("showgrid")) ? EditorPrefs.GetBool("showgrid") : pg_Preferences.SHOW_GRID;
predictiveGrid = EditorPrefs.HasKey(pg_Constant.PredictiveGrid) ? EditorPrefs.GetBool(pg_Constant.PredictiveGrid) : true;
_snapAsGroup = snapAsGroup;
_scaleSnapEnabled = ScaleSnapEnabled;
}
private GUISkin sixBySevenSkin;
#endregion
#region MENU
[MenuItem("Tools/ProGrids/About", false, 0)]
public static void MenuAboutProGrids()
{
pg_AboutWindow.Init("Assets/ProCore/ProGrids/About/pc_AboutEntry_ProGrids.txt", true);
}
[MenuItem("Tools/ProGrids/ProGrids Window", false, 15)]
public static void InitProGrids()
{
if (instance == null)
{
EditorPrefs.SetBool(pg_Constant.ProGridsIsEnabled, true);
instance = ScriptableObject.CreateInstance<pg_Editor>();
instance.hideFlags = HideFlags.DontSave;
EditorApplication.delayCall += instance.Initialize;
}
else
{
CloseProGrids();
}
SceneView.RepaintAll();
}
[MenuItem("Tools/ProGrids/Close ProGrids", true, 200)]
public static bool VerifyCloseProGrids()
{
return instance != null || Resources.FindObjectsOfTypeAll<pg_Editor>().Length > 0;
}
[MenuItem("Tools/ProGrids/Close ProGrids")]
public static void CloseProGrids()
{
foreach (pg_Editor editor in Resources.FindObjectsOfTypeAll<pg_Editor>())
editor.Close();
}
[MenuItem("Tools/ProGrids/Cycle SceneView Projection", false, 101)]
public static void CyclePerspective()
{
if (instance == null) return;
SceneView scnvw = SceneView.lastActiveSceneView;
if (scnvw == null) return;
int nextOrtho = EditorPrefs.GetInt(pg_Constant.LastOrthoToggledRotation);
switch (nextOrtho)
{
case 0:
scnvw.orthographic = true;
scnvw.LookAt(scnvw.pivot, Quaternion.Euler(Vector3.zero));
nextOrtho++;
break;
case 1:
scnvw.orthographic = true;
scnvw.LookAt(scnvw.pivot, Quaternion.Euler(Vector3.up * -90f));
nextOrtho++;
break;
case 2:
scnvw.orthographic = true;
scnvw.LookAt(scnvw.pivot, Quaternion.Euler(Vector3.right * 90f));
nextOrtho++;
break;
case 3:
scnvw.orthographic = false;
scnvw.LookAt(scnvw.pivot, new Quaternion(-0.1f, 0.9f, -0.2f, -0.4f));
nextOrtho = 0;
break;
}
EditorPrefs.SetInt(pg_Constant.LastOrthoToggledRotation, nextOrtho);
}
[MenuItem("Tools/ProGrids/Cycle SceneView Projection", true, 101)]
[MenuItem("Tools/ProGrids/Increase Grid Size", true, 203)]
[MenuItem("Tools/ProGrids/Decrease Grid Size", true, 202)]
public static bool VerifyGridSizeAdjustment()
{
return instance != null;
}
[MenuItem("Tools/ProGrids/Decrease Grid Size", false, 202)]
public static void DecreaseGridSize()
{
if (instance == null) return;
int multiplier = EditorPrefs.HasKey(pg_Constant.SnapMultiplier) ? EditorPrefs.GetInt(pg_Constant.SnapMultiplier) : DEFAULT_SNAP_MULTIPLIER;
float val = EditorPrefs.HasKey(pg_Constant.SnapValue) ? EditorPrefs.GetFloat(pg_Constant.SnapValue) : 1f;
if (multiplier > 1)
multiplier /= 2;
instance.SetSnapValue(instance.snapUnit, val, multiplier);
SceneView.RepaintAll();
}
[MenuItem("Tools/ProGrids/Increase Grid Size", false, 203)]
public static void IncreaseGridSize()
{
if (instance == null) return;
int multiplier = EditorPrefs.HasKey(pg_Constant.SnapMultiplier) ? EditorPrefs.GetInt(pg_Constant.SnapMultiplier) : DEFAULT_SNAP_MULTIPLIER;
float val = EditorPrefs.HasKey(pg_Constant.SnapValue) ? EditorPrefs.GetFloat(pg_Constant.SnapValue) : 1f;
if (multiplier < int.MaxValue / 2)
multiplier *= 2;
instance.SetSnapValue(instance.snapUnit, val, multiplier);
SceneView.RepaintAll();
}
[MenuItem("Tools/ProGrids/Nudge Perspective Backward", true, 304)]
[MenuItem("Tools/ProGrids/Nudge Perspective Forward", true, 305)]
[MenuItem("Tools/ProGrids/Reset Perspective Nudge", true, 306)]
public static bool VerifyMenuNudgePerspective()
{
return instance != null && !instance.fullGrid && !instance.ortho && instance.lockGrid;
}
[MenuItem("Tools/ProGrids/Nudge Perspective Backward", false, 304)]
public static void MenuNudgePerspectiveBackward()
{
if (!instance.lockGrid) return;
instance.offset -= instance.snapValue;
instance.gridRepaint = true;
SceneView.RepaintAll();
}
[MenuItem("Tools/ProGrids/Nudge Perspective Forward", false, 305)]
public static void MenuNudgePerspectiveForward()
{
if (!instance.lockGrid) return;
instance.offset += instance.snapValue;
instance.gridRepaint = true;
SceneView.RepaintAll();
}
[MenuItem("Tools/ProGrids/Reset Perspective Nudge", false, 306)]
public static void MenuNudgePerspectiveReset()
{
if (!instance.lockGrid) return;
instance.offset = 0;
instance.gridRepaint = true;
SceneView.RepaintAll();
}
public static void ForceRepaint()
{
if (instance != null)
{
instance.gridRepaint = true;
SceneView.RepaintAll();
}
}
#endregion
#region INITIALIZATION / SERIALIZATION
public void OnBeforeSerialize() { }
public void OnAfterDeserialize()
{
instance = this;
SceneView.onSceneGUIDelegate += OnSceneGUI;
EditorApplication.update += Update;
EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
}
void OnEnable()
{
instance.LoadGUIResources();
#if !UNITY_4_6 && !UNITY_4_7 && !UNITY_5_0 && !UNITY_5_1
Selection.selectionChanged += OnSelectionChange;
#endif
}
public void Initialize()
{
SceneView.onSceneGUIDelegate -= OnSceneGUI;
EditorApplication.update -= Update;
EditorApplication.hierarchyWindowChanged -= HierarchyWindowChanged;
SceneView.onSceneGUIDelegate += OnSceneGUI;
EditorApplication.update += Update;
EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
LoadGUIResources();
LoadPreferences();
instance = this;
pg_GridRenderer.Init();
SetMenuIsExtended(menuOpen);
lastTime = Time.realtimeSinceStartup;
// reset colors without changing anything
menuOpen = !menuOpen;
ToggleMenuVisibility();
if (drawGrid)
pg_Util.SetUnityGridEnabled(false);
gridRepaint = true;
RepaintSceneView();
}
void OnDestroy()
{
this.Close(true);
}
public void Close()
{
EditorPrefs.SetBool(pg_Constant.ProGridsIsEnabled, false);
GameObject.DestroyImmediate(this);
#if !UNITY_4_6 && !UNITY_4_7 && !UNITY_5_0 && !UNITY_5_1
Selection.selectionChanged -= OnSelectionChange;
#endif
}
public void Close(bool isBeingDestroyed)
{
pg_GridRenderer.Destroy();
SceneView.onSceneGUIDelegate -= OnSceneGUI;
EditorApplication.update -= Update;
EditorApplication.hierarchyWindowChanged -= HierarchyWindowChanged;
instance = null;
foreach (System.Action<bool> listener in toolbarEventSubscribers)
listener(false);
pg_Util.SetUnityGridEnabled(true);
SceneView.RepaintAll();
}
private void LoadGUIResources()
{
if (gc_GridEnabled.image_on == null)
gc_GridEnabled.image_on = pg_IconUtility.LoadIcon("ProGrids2_GUI_Vis_On.png");
if (gc_GridEnabled.image_off == null)
gc_GridEnabled.image_off = pg_IconUtility.LoadIcon("ProGrids2_GUI_Vis_Off.png");
if (gc_SnapEnabled.image_on == null)
gc_SnapEnabled.image_on = pg_IconUtility.LoadIcon("ProGrids2_GUI_Snap_On.png");
if (gc_SnapEnabled.image_off == null)
gc_SnapEnabled.image_off = pg_IconUtility.LoadIcon("ProGrids2_GUI_Snap_Off.png");
if (gc_SnapToGrid.image_on == null)
gc_SnapToGrid.image_on = pg_IconUtility.LoadIcon("ProGrids2_GUI_PushToGrid_Normal.png");
if (gc_LockGrid.image_on == null)
gc_LockGrid.image_on = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_Lock_On.png");
if (gc_LockGrid.image_off == null)
gc_LockGrid.image_off = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_Lock_Off.png");
if (gc_AngleEnabled.image_on == null)
gc_AngleEnabled.image_on = pg_IconUtility.LoadIcon("ProGrids2_GUI_AngleVis_On.png");
if (gc_AngleEnabled.image_off == null)
gc_AngleEnabled.image_off = pg_IconUtility.LoadIcon("ProGrids2_GUI_AngleVis_Off.png");
if (gc_RenderPlaneX.image_on == null)
gc_RenderPlaneX.image_on = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_X_On.png");
if (gc_RenderPlaneX.image_off == null)
gc_RenderPlaneX.image_off = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_X_Off.png");
if (gc_RenderPlaneY.image_on == null)
gc_RenderPlaneY.image_on = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_Y_On.png");
if (gc_RenderPlaneY.image_off == null)
gc_RenderPlaneY.image_off = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_Y_Off.png");
if (gc_RenderPlaneZ.image_on == null)
gc_RenderPlaneZ.image_on = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_Z_On.png");
if (gc_RenderPlaneZ.image_off == null)
gc_RenderPlaneZ.image_off = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_Z_Off.png");
if (gc_RenderPerspectiveGrid.image_on == null)
gc_RenderPerspectiveGrid.image_on = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_3D_On.png");
if (gc_RenderPerspectiveGrid.image_off == null)
gc_RenderPerspectiveGrid.image_off = pg_IconUtility.LoadIcon("ProGrids2_GUI_PGrid_3D_Off.png");
if (icon_extendoOpen == null)
icon_extendoOpen = pg_IconUtility.LoadIcon("ProGrids2_MenuExtendo_Open.png");
if (icon_extendoClose == null)
icon_extendoClose = pg_IconUtility.LoadIcon("ProGrids2_MenuExtendo_Close.png");
}
#endregion
#region INTERFACE
GUIStyle gridButtonStyle = new GUIStyle();
GUIStyle extendoStyle = new GUIStyle();
GUIStyle gridButtonStyleBlank = new GUIStyle();
GUIStyle backgroundStyle = new GUIStyle();
bool guiInitialized = false;
public float GetSnapIncrement()
{
return t_snapValue;
}
public void SetSnapIncrement(float inc)
{
SetSnapValue(snapUnit, Mathf.Max(inc, .001f), DEFAULT_SNAP_MULTIPLIER);
}
void RepaintSceneView()
{
SceneView.RepaintAll();
}
int MENU_HIDDEN { get { return menuIsOrtho ? -192 : -173; } }
const int MENU_EXTENDED = 8;
const int PAD = 3;
Rect r = new Rect(8, MENU_EXTENDED, 42, 16);
Rect backgroundRect = new Rect(00, 0, 0, 0);
Rect extendoButtonRect = new Rect(0, 0, 0, 0);
bool menuOpen = true;
float menuStart = MENU_EXTENDED;
const float MENU_SPEED = 500f;
float deltaTime = 0f;
float lastTime = 0f;
const float FADE_SPEED = 2.5f;
float backgroundFade = 1f;
bool mouseOverMenu = false;
Color menuBackgroundColor = new Color(0f, 0f, 0f, .5f);
Color extendoNormalColor = new Color(.9f, .9f, .9f, .7f);
Color extendoHoverColor = new Color(0f, 1f, .4f, 1f);
bool extendoButtonHovering = false;
bool menuIsOrtho = false;
void Update()
{
deltaTime = Time.realtimeSinceStartup - lastTime;
lastTime = Time.realtimeSinceStartup;
if ((menuOpen && menuStart < MENU_EXTENDED) || (!menuOpen && menuStart > MENU_HIDDEN))
{
menuStart += deltaTime * MENU_SPEED * (menuOpen ? 1f : -1f);
menuStart = Mathf.Clamp(menuStart, MENU_HIDDEN, MENU_EXTENDED);
RepaintSceneView();
}
float a = menuBackgroundColor.a;
backgroundFade = (mouseOverMenu || !menuOpen) ? FADE_SPEED : -FADE_SPEED;
menuBackgroundColor.a = Mathf.Clamp(menuBackgroundColor.a + backgroundFade * deltaTime, 0f, .5f);
extendoNormalColor.a = menuBackgroundColor.a;
extendoHoverColor.a = (menuBackgroundColor.a / .5f);
if (!Mathf.Approximately(menuBackgroundColor.a, a))
RepaintSceneView();
}
void DrawSceneGUI()
{
GUI.backgroundColor = menuBackgroundColor;
backgroundRect.x = r.x - 4;
backgroundRect.y = 0;
backgroundRect.width = r.width + 8;
backgroundRect.height = r.y + r.height + PAD;
GUI.Box(backgroundRect, "", backgroundStyle);
// when hit testing mouse for showing the background, add some leeway
backgroundRect.width += 32f;
backgroundRect.height += 32f;
GUI.backgroundColor = Color.white;
if (!guiInitialized)
{
extendoStyle.normal.background = menuOpen ? icon_extendoClose : icon_extendoOpen;
extendoStyle.hover.background = menuOpen ? icon_extendoClose : icon_extendoOpen;
guiInitialized = true;
backgroundStyle.normal.background = EditorGUIUtility.whiteTexture;
Texture2D icon_button_normal = pg_IconUtility.LoadIcon("ProGrids2_Button_Normal.png");
Texture2D icon_button_hover = pg_IconUtility.LoadIcon("ProGrids2_Button_Hover.png");
if (icon_button_normal == null)
{
gridButtonStyleBlank = new GUIStyle("button");
}
else
{
gridButtonStyleBlank.normal.background = icon_button_normal;
gridButtonStyleBlank.hover.background = icon_button_hover;
gridButtonStyleBlank.normal.textColor = icon_button_normal != null ? Color.white : Color.black;
gridButtonStyleBlank.hover.textColor = new Color(.7f, .7f, .7f, 1f);
}
gridButtonStyleBlank.padding = new RectOffset(1, 2, 1, 2);
gridButtonStyleBlank.alignment = TextAnchor.MiddleCenter;
}
r.y = menuStart;
gc_SnapIncrement.text = t_snapValue.ToString("#.####");
if (GUI.Button(r, gc_SnapIncrement, gridButtonStyleBlank))
{
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
// On Mac ShowAsDropdown and ShowAuxWindow both throw stack pop exceptions when initialized.
pg_ParameterWindow options = EditorWindow.GetWindow<pg_ParameterWindow>(true, "ProGrids Settings", true);
Rect screenRect = SceneView.lastActiveSceneView.position;
options.editor = this;
options.position = new Rect(screenRect.x + r.x + r.width + PAD,
screenRect.y + r.y + 24,
256,
174);
#else
pg_ParameterWindow options = ScriptableObject.CreateInstance<pg_ParameterWindow>();
Rect screenRect = SceneView.lastActiveSceneView.position;
options.editor = this;
options.ShowAsDropDown(new Rect(screenRect.x + r.x + r.width + PAD,
screenRect.y + r.y + 24,
0,
0),
new Vector2(256, 174));
#endif
}
r.y += r.height + PAD;
// Draw grid
if (pg_ToggleContent.ToggleButton(r, gc_GridEnabled, drawGrid, gridButtonStyle, EditorStyles.miniButton))
SetGridEnabled(!drawGrid);
r.y += r.height + PAD;
// Snap enabled
if (pg_ToggleContent.ToggleButton(r, gc_SnapEnabled, snapEnabled, gridButtonStyle, EditorStyles.miniButton))
SetSnapEnabled(!snapEnabled);
r.y += r.height + PAD;
// Push to grid
if (pg_ToggleContent.ToggleButton(r, gc_SnapToGrid, true, gridButtonStyle, EditorStyles.miniButton))
SnapToGrid(Selection.transforms);
r.y += r.height + PAD;
// Lock grid
if (pg_ToggleContent.ToggleButton(r, gc_LockGrid, lockGrid, gridButtonStyle, EditorStyles.miniButton))
{
lockGrid = !lockGrid;
EditorPrefs.SetBool(pg_Constant.LockGrid, lockGrid);
EditorPrefs.SetString(pg_Constant.LockedGridPivot, pivot.ToString());
// if we've modified the nudge value, reset the pivot here
if (!lockGrid)
offset = 0f;
gridRepaint = true;
RepaintSceneView();
}
if (menuIsOrtho)
{
r.y += r.height + PAD;
if (pg_ToggleContent.ToggleButton(r, gc_AngleEnabled, drawAngles, gridButtonStyle, EditorStyles.miniButton))
SetDrawAngles(!drawAngles);
}
/**
* Perspective Toggles
*/
r.y += r.height + PAD + 4;
if (pg_ToggleContent.ToggleButton(r, gc_RenderPlaneX, (renderPlane & Axis.X) == Axis.X && !fullGrid, gridButtonStyle, EditorStyles.miniButton))
SetRenderPlane(Axis.X);
r.y += r.height + PAD;
if (pg_ToggleContent.ToggleButton(r, gc_RenderPlaneY, (renderPlane & Axis.Y) == Axis.Y && !fullGrid, gridButtonStyle, EditorStyles.miniButton))
SetRenderPlane(Axis.Y);
r.y += r.height + PAD;
if (pg_ToggleContent.ToggleButton(r, gc_RenderPlaneZ, (renderPlane & Axis.Z) == Axis.Z && !fullGrid, gridButtonStyle, EditorStyles.miniButton))
SetRenderPlane(Axis.Z);
r.y += r.height + PAD;
if (pg_ToggleContent.ToggleButton(r, gc_RenderPerspectiveGrid, fullGrid, gridButtonStyle, EditorStyles.miniButton))
{
fullGrid = !fullGrid;
gridRepaint = true;
EditorPrefs.SetBool(pg_Constant.PerspGrid, fullGrid);
RepaintSceneView();
}
r.y += r.height + PAD;
extendoButtonRect.x = r.x;
extendoButtonRect.y = r.y;
extendoButtonRect.width = r.width;
extendoButtonRect.height = r.height;
GUI.backgroundColor = extendoButtonHovering ? extendoHoverColor : extendoNormalColor;
gc_ExtendMenu.text = icon_extendoOpen == null ? (menuOpen ? "Close" : "Open") : "";
if (GUI.Button(r, gc_ExtendMenu, icon_extendoOpen ? extendoStyle : gridButtonStyleBlank))
{
ToggleMenuVisibility();
extendoButtonHovering = false;
}
GUI.backgroundColor = Color.white;
}
void ToggleMenuVisibility()
{
menuOpen = !menuOpen;
EditorPrefs.SetBool(pg_Constant.ProGridsIsExtended, menuOpen);
extendoStyle.normal.background = menuOpen ? icon_extendoClose : icon_extendoOpen;
extendoStyle.hover.background = menuOpen ? icon_extendoClose : icon_extendoOpen;
foreach (System.Action<bool> listener in toolbarEventSubscribers)
listener(menuOpen);
RepaintSceneView();
}
// skip color fading and stuff
void SetMenuIsExtended(bool isExtended)
{
menuOpen = isExtended;
menuIsOrtho = ortho;
menuStart = menuOpen ? MENU_EXTENDED : MENU_HIDDEN;
menuBackgroundColor.a = 0f;
extendoNormalColor.a = menuBackgroundColor.a;
extendoHoverColor.a = (menuBackgroundColor.a / .5f);
extendoStyle.normal.background = menuOpen ? icon_extendoClose : icon_extendoOpen;
extendoStyle.hover.background = menuOpen ? icon_extendoClose : icon_extendoOpen;
foreach (System.Action<bool> listener in toolbarEventSubscribers)
listener(menuOpen);
EditorPrefs.SetBool(pg_Constant.ProGridsIsExtended, menuOpen);
}
private void OpenProGridsPopup()
{
if (EditorUtility.DisplayDialog(
"Upgrade to ProGrids", // Title
"Enables all kinds of super-cool features, like different snap values, more units of measurement, and angles.", // Message
"Upgrade", // Okay
"Cancel" // Cancel
))
// #if UNITY_4
// AssetStore.OpenURL(pg_Constant.ProGridsUpgradeURL);
// #else
Application.OpenURL(pg_Constant.ProGridsUpgradeURL);
// #endif
}
#endregion
#region ONSCENEGUI
private Transform lastTransform;
const string AXIS_CONSTRAINT_KEY = "s";
const string TEMP_DISABLE_KEY = "d";
private bool toggleAxisConstraint = false;
private bool toggleTempSnap = false;
private Vector3 lastPosition = Vector3.zero;
// private Vector3 lastRotation = Vector3.zero;
private Vector3 lastScale = Vector3.one;
private Vector3 pivot = Vector3.zero, lastPivot = Vector3.zero;
private Vector3 camDir = Vector3.zero, prevCamDir = Vector3.zero;
// Distance from camera to pivot at the last time the grid mesh was updated.
private float lastDistance = 0f;
public float offset = 0f;
private bool firstMove = true;
#if PROFILE_TIMES
pb_Profiler profiler = new pb_Profiler();
#endif
public bool ortho { get; private set; }
private bool prevOrtho = false;
float planeGridDrawDistance = 0f;
public void OnSceneGUI(SceneView scnview)
{
bool isCurrentView = scnview == SceneView.lastActiveSceneView;
if (isCurrentView)
{
Handles.BeginGUI();
DrawSceneGUI();
Handles.EndGUI();
}
// don't snap stuff in play mode
if (EditorApplication.isPlayingOrWillChangePlaymode)
return;
Event e = Event.current;
// repaint scene gui if mouse is near controls
if (isCurrentView && e.type == EventType.MouseMove)
{
bool tmp = extendoButtonHovering;
extendoButtonHovering = extendoButtonRect.Contains(e.mousePosition);
if (extendoButtonHovering != tmp)
RepaintSceneView();
mouseOverMenu = backgroundRect.Contains(e.mousePosition);
}
if (e.Equals(Event.KeyboardEvent(AXIS_CONSTRAINT_KEY)))
{
toggleAxisConstraint = true;
}
if (e.Equals(Event.KeyboardEvent(TEMP_DISABLE_KEY)))
{
toggleTempSnap = true;
}
if (e.isKey)
{
toggleAxisConstraint = false;
toggleTempSnap = false;
bool used = true;
if (e.keyCode == m_IncreaseGridSizeShortcut)
{
if (e.type == EventType.KeyUp)
IncreaseGridSize();
}
else if (e.keyCode == m_DecreaseGridSizeShortcut)
{
if (e.type == EventType.KeyUp)
DecreaseGridSize();
}
else if (e.keyCode == m_NudgePerspectiveBackwardShortcut)
{
if (e.type == EventType.KeyUp && VerifyMenuNudgePerspective())
MenuNudgePerspectiveBackward();
}
else if (e.keyCode == m_NudgePerspectiveForwardShortcut)
{
if (e.type == EventType.KeyUp && VerifyMenuNudgePerspective())
MenuNudgePerspectiveForward();
}
else if (e.keyCode == m_NudgePerspectiveResetShortcut)
{
if (e.type == EventType.KeyUp && VerifyMenuNudgePerspective())
MenuNudgePerspectiveReset();
}
else if (e.keyCode == m_CyclePerspectiveShortcut)
{
if (e.type == EventType.KeyUp)
CyclePerspective();
}
else
{
used = false;
}
if (used)
e.Use();
}
Camera cam = Camera.current;
if (cam == null)
return;
ortho = cam.orthographic && IsRounded(scnview.rotation.eulerAngles.normalized);
camDir = pg_Util.CeilFloor(pivot - cam.transform.position);
if (ortho && !prevOrtho || ortho != menuIsOrtho)
OnSceneBecameOrtho(isCurrentView);
if (!ortho && prevOrtho)
OnSceneBecamePersp(isCurrentView);
prevOrtho = ortho;
float camDistance = Vector3.Distance(cam.transform.position, lastPivot); // distance from camera to pivot
if (fullGrid)
{
pivot = lockGrid || Selection.activeTransform == null ? pivot : Selection.activeTransform.position;
}
else
{
Vector3 sceneViewPlanePivot = pivot;
Ray ray = new Ray(cam.transform.position, cam.transform.forward);
Plane plane = new Plane(Vector3.up, pivot);
float dist;
// the only time a locked grid should ever move is if it's pivot is out
// of the camera's frustum.
if ((lockGrid && !cam.InFrustum(pivot)) || !lockGrid || scnview != SceneView.lastActiveSceneView)
{
if (plane.Raycast(ray, out dist))
sceneViewPlanePivot = ray.GetPoint(Mathf.Min(dist, planeGridDrawDistance / 2f));
else
sceneViewPlanePivot = ray.GetPoint(Mathf.Min(cam.farClipPlane / 2f, planeGridDrawDistance / 2f));
}
if (lockGrid)
{
pivot = pg_Enum.InverseAxisMask(sceneViewPlanePivot, renderPlane) + pg_Enum.AxisMask(pivot, renderPlane);
}
else
{
pivot = Selection.activeTransform == null ? pivot : Selection.activeTransform.position;
if (Selection.activeTransform == null || !cam.InFrustum(pivot))
{
pivot = pg_Enum.InverseAxisMask(sceneViewPlanePivot, renderPlane) + pg_Enum.AxisMask(Selection.activeTransform == null ? pivot : Selection.activeTransform.position, renderPlane);
}
}
}
#if PG_DEBUG
pivotGo.transform.position = pivot;
#endif
if (drawGrid)
{
if (ortho)
{
// ortho don't care about pivots
DrawGridOrthographic(cam);
}
else
{
#if PROFILE_TIMES
profiler.LogStart("DrawGridPerspective");
#endif
if (gridRepaint || pivot != lastPivot || Mathf.Abs(camDistance - lastDistance) > lastDistance / 2 || camDir != prevCamDir)
{
prevCamDir = camDir;
gridRepaint = false;
lastPivot = pivot;
lastDistance = camDistance;
if (fullGrid)
{
// if perspective and 3d, use pivot like normal
pg_GridRenderer.DrawGridPerspective(cam, pivot, snapValue, new Color[3] { gridColorX, gridColorY, gridColorZ }, alphaBump);
}
else
{
if ((renderPlane & Axis.X) == Axis.X)
planeGridDrawDistance = pg_GridRenderer.DrawPlane(cam, pivot + Vector3.right * offset, Vector3.up, Vector3.forward, snapValue, gridColorX, alphaBump);
if ((renderPlane & Axis.Y) == Axis.Y)
planeGridDrawDistance = pg_GridRenderer.DrawPlane(cam, pivot + Vector3.up * offset, Vector3.right, Vector3.forward, snapValue, gridColorY, alphaBump);
if ((renderPlane & Axis.Z) == Axis.Z)
planeGridDrawDistance = pg_GridRenderer.DrawPlane(cam, pivot + Vector3.forward * offset, Vector3.up, Vector3.right, snapValue, gridColorZ, alphaBump);
}
}
#if PROFILE_TIMES
profiler.LogFinish("DrawGridPerspective");
#endif
}
}
// Always keep track of the selection
if (!Selection.transforms.Contains(lastTransform))
{
if (Selection.activeTransform)
{
lastTransform = Selection.activeTransform;
lastPosition = Selection.activeTransform.position;
lastScale = Selection.activeTransform.localScale;
}
}
if (e.type == EventType.MouseUp)
firstMove = true;
if (!snapEnabled || GUIUtility.hotControl < 1)
return;
// Bugger.SetKey("Toggle Snap Off", toggleTempSnap);
/**
* Snapping (for all the junk in PG, this method is literally the only code that actually affects anything).
*/
if (Selection.activeTransform && pg_Util.SnapIsEnabled(Selection.activeTransform))
{
if (!FuzzyEquals(lastTransform.position, lastPosition))
{
Transform selected = lastTransform;
if (!toggleTempSnap)
{
Vector3 old = selected.position;
Vector3 mask = old - lastPosition;
bool constraintsOn = toggleAxisConstraint ? !useAxisConstraints : useAxisConstraints;
if (constraintsOn)
selected.position = pg_Util.SnapValue(old, mask, snapValue);
else
selected.position = pg_Util.SnapValue(old, snapValue);
Vector3 offset = selected.position - old;
if (predictiveGrid && firstMove && !fullGrid)
{
firstMove = false;
Axis dragAxis = pg_Util.CalcDragAxis(offset, scnview.camera);
if (dragAxis != Axis.None && dragAxis != renderPlane)
SetRenderPlane(dragAxis);
}
if (_snapAsGroup)
{
OffsetTransforms(Selection.transforms, selected, offset);
}
else
{
foreach (Transform t in Selection.transforms)
t.position = constraintsOn ? pg_Util.SnapValue(t.position, mask, snapValue) : pg_Util.SnapValue(t.position, snapValue);
}
}
lastPosition = selected.position;
}
if (!FuzzyEquals(lastTransform.localScale, lastScale) && _scaleSnapEnabled)
{
if (!toggleTempSnap)
{
Vector3 old = lastTransform.localScale;
Vector3 mask = old - lastScale;
if (predictiveGrid)
{
Axis dragAxis = pg_Util.CalcDragAxis(Selection.activeTransform.TransformDirection(mask), scnview.camera);
if (dragAxis != Axis.None && dragAxis != renderPlane)
SetRenderPlane(dragAxis);
}
foreach (Transform t in Selection.transforms)
t.localScale = pg_Util.SnapValue(t.localScale, mask, snapValue);
lastScale = lastTransform.localScale;
}
}
}
}
void OnSelectionChange()
{
// Means we don't have to wait for script reloads
// to respect IgnoreSnap attribute, and keeps the
// cache small.
pg_Util.ClearSnapEnabledCache();
}
void OnSceneBecameOrtho(bool isCurrentView)
{
pg_GridRenderer.Destroy();
if (isCurrentView && ortho != menuIsOrtho)
SetMenuIsExtended(menuOpen);
}
void OnSceneBecamePersp(bool isCurrentView)
{
if (isCurrentView && ortho != menuIsOrtho)
SetMenuIsExtended(menuOpen);
}
#endregion
#region GRAPHICS
GameObject go;
private void DrawGridOrthographic(Camera cam)
{
Axis camAxis = AxisWithVector(Camera.current.transform.TransformDirection(Vector3.forward).normalized);
if (drawGrid)
{
switch (camAxis)
{
case Axis.X:
case Axis.NegX:
DrawGridOrthographic(cam, camAxis, gridColorX_primary, gridColorX);
break;
case Axis.Y:
case Axis.NegY:
DrawGridOrthographic(cam, camAxis, gridColorY_primary, gridColorY);
break;
case Axis.Z:
case Axis.NegZ:
DrawGridOrthographic(cam, camAxis, gridColorZ_primary, gridColorZ);
break;
}
}
}
int PRIMARY_COLOR_INCREMENT = 10;
Color previousColor;
private void DrawGridOrthographic(Camera cam, Axis camAxis, Color primaryColor, Color secondaryColor)
{
previousColor = Handles.color;
Handles.color = primaryColor;
Vector3 bottomLeft = pg_Util.SnapToFloor(cam.ScreenToWorldPoint(Vector2.zero), snapValue);
Vector3 bottomRight = pg_Util.SnapToFloor(cam.ScreenToWorldPoint(new Vector2(cam.pixelWidth, 0f)), snapValue);
Vector3 topLeft = pg_Util.SnapToFloor(cam.ScreenToWorldPoint(new Vector2(0f, cam.pixelHeight)), snapValue);
Vector3 topRight = pg_Util.SnapToFloor(cam.ScreenToWorldPoint(new Vector2(cam.pixelWidth, cam.pixelHeight)), snapValue);
Vector3 axis = VectorWithAxis(camAxis);
float width = Vector3.Distance(bottomLeft, bottomRight);
float height = Vector3.Distance(bottomRight, topRight);
// Shift lines to 10m forward of the camera
bottomLeft += axis * 10f;
topRight += axis * 10f;
bottomRight += axis * 10f;
topLeft += axis * 10f;
/**
* Draw Vertical Lines
*/
Vector3 cam_right = cam.transform.right;
Vector3 cam_up = cam.transform.up;
float _snapVal = snapValue;
int segs = (int)Mathf.Ceil(width / _snapVal) + 2;
float n = 2f;
while (segs > MAX_LINES)
{
_snapVal = _snapVal * n;
segs = (int)Mathf.Ceil(width / _snapVal) + 2;
n++;
}
/// Screen start and end
Vector3 bl = cam_right.Sum() > 0 ? pg_Util.SnapToFloor(bottomLeft, cam_right, _snapVal * PRIMARY_COLOR_INCREMENT) : pg_Util.SnapToCeil(bottomLeft, cam_right, _snapVal * PRIMARY_COLOR_INCREMENT);
Vector3 start = bl - cam_up * (height + _snapVal * 2);
Vector3 end = bl + cam_up * (height + _snapVal * 2);
segs += PRIMARY_COLOR_INCREMENT;
/// The current line start and end
Vector3 line_start = Vector3.zero;
Vector3 line_end = Vector3.zero;
for (int i = -1; i < segs; i++)
{
line_start = start + (i * (cam_right * _snapVal));
line_end = end + (i * (cam_right * _snapVal));
Handles.color = i % PRIMARY_COLOR_INCREMENT == 0 ? primaryColor : secondaryColor;
Handles.DrawLine(line_start, line_end);
}
/**
* Draw Horizontal Lines
*/
segs = (int)Mathf.Ceil(height / _snapVal) + 2;
n = 2;
while (segs > MAX_LINES)
{
_snapVal = _snapVal * n;
segs = (int)Mathf.Ceil(height / _snapVal) + 2;
n++;
}
Vector3 tl = cam_up.Sum() > 0 ? pg_Util.SnapToCeil(topLeft, cam_up, _snapVal * PRIMARY_COLOR_INCREMENT) : pg_Util.SnapToFloor(topLeft, cam_up, _snapVal * PRIMARY_COLOR_INCREMENT);
start = tl - cam_right * (width + _snapVal * 2);
end = tl + cam_right * (width + _snapVal * 2);
segs += (int)PRIMARY_COLOR_INCREMENT;
for (int i = -1; i < segs; i++)
{
line_start = start + (i * (-cam_up * _snapVal));
line_end = end + (i * (-cam_up * _snapVal));
Handles.color = i % PRIMARY_COLOR_INCREMENT == 0 ? primaryColor : secondaryColor;
Handles.DrawLine(line_start, line_end);
}
#if PRO
if (drawAngles)
{
Vector3 cen = pg_Util.SnapValue(((topRight + bottomLeft) / 2f), snapValue);
float half = (width > height) ? width : height;
float opposite = Mathf.Tan(Mathf.Deg2Rad * angleValue) * half;
Vector3 up = cam.transform.up * opposite;
Vector3 right = cam.transform.right * half;
Vector3 bottomLeftAngle = cen - (up + right);
Vector3 topRightAngle = cen + (up + right);
Vector3 bottomRightAngle = cen + (right - up);
Vector3 topLeftAngle = cen + (up - right);
Handles.color = primaryColor;
// y = 1x+1
Handles.DrawLine(bottomLeftAngle, topRightAngle);
// y = -1x-1
Handles.DrawLine(topLeftAngle, bottomRightAngle);
}
#endif
Handles.color = previousColor;
}
#endregion
#region ENUM UTILITY
public SnapUnit SnapUnitWithString(string str)
{
foreach (SnapUnit su in SnapUnit.GetValues(typeof(SnapUnit)))
{
if (su.ToString() == str)
return su;
}
return (SnapUnit)0;
}
public Axis AxisWithVector(Vector3 val)
{
Vector3 v = new Vector3(Mathf.Abs(val.x), Mathf.Abs(val.y), Mathf.Abs(val.z));
if (v.x > v.y && v.x > v.z)
{
if (val.x > 0)
return Axis.X;
else
return Axis.NegX;
}
else
if (v.y > v.x && v.y > v.z)
{
if (val.y > 0)
return Axis.Y;
else
return Axis.NegY;
}
else
{
if (val.z > 0)
return Axis.Z;
else
return Axis.NegZ;
}
}
public Vector3 VectorWithAxis(Axis axis)
{
switch (axis)
{
case Axis.X:
return Vector3.right;
case Axis.Y:
return Vector3.up;
case Axis.Z:
return Vector3.forward;
case Axis.NegX:
return -Vector3.right;
case Axis.NegY:
return -Vector3.up;
case Axis.NegZ:
return -Vector3.forward;
default:
return Vector3.forward;
}
}
public bool IsRounded(Vector3 v)
{
return (Mathf.Approximately(v.x, 1f) || Mathf.Approximately(v.y, 1f) || Mathf.Approximately(v.z, 1f)) || v == Vector3.zero;
}
public Vector3 RoundAxis(Vector3 v)
{
return VectorWithAxis(AxisWithVector(v));
}
#endregion
#region MOVING TRANSFORMS
static bool FuzzyEquals(Vector3 lhs, Vector3 rhs)
{
return Mathf.Abs(lhs.x - rhs.x) < .001f && Mathf.Abs(lhs.y - rhs.y) < .001f && Mathf.Abs(lhs.z - rhs.z) < .001f;
}
public void OffsetTransforms(Transform[] trsfrms, Transform ignore, Vector3 offset)
{
foreach (Transform t in trsfrms)
{
if (t != ignore)
t.position += offset;
}
}
void HierarchyWindowChanged()
{
if (Selection.activeTransform != null)
lastPosition = Selection.activeTransform.position;
}
#endregion
#region SETTINGS
public void SetSnapEnabled(bool enable)
{
EditorPrefs.SetBool(pg_Constant.SnapEnabled, enable);
if (Selection.activeTransform)
{
lastTransform = Selection.activeTransform;
lastPosition = Selection.activeTransform.position;
}
snapEnabled = enable;
gridRepaint = true;
RepaintSceneView();
}
public void SetSnapValue(SnapUnit su, float val, int multiplier)
{
int clamp_multiplier = (int)(Mathf.Min(Mathf.Max(1, multiplier), int.MaxValue));
float value_multiplier = clamp_multiplier / (float)DEFAULT_SNAP_MULTIPLIER;
/**
* multiplier is a value modifies the snap val. 100 = no change,
* 50 is half val, 200 is double val, etc.
*/
snapValue = pg_Enum.SnapUnitValue(su) * val * value_multiplier;
RepaintSceneView();
EditorPrefs.SetInt(pg_Constant.GridUnit, (int)su);
EditorPrefs.SetFloat(pg_Constant.SnapValue, val);
EditorPrefs.SetInt(pg_Constant.SnapMultiplier, clamp_multiplier);
// update gui (only necessary when calling with editorpref values)
t_snapValue = val * value_multiplier;
snapUnit = su;
switch (su)
{
case SnapUnit.Inch:
PRIMARY_COLOR_INCREMENT = 12; // blasted imperial units
break;
case SnapUnit.Foot:
PRIMARY_COLOR_INCREMENT = 3;
break;
default:
PRIMARY_COLOR_INCREMENT = 10;
break;
}
if (EditorPrefs.GetBool(pg_Constant.SyncUnitySnap, true))
{
EditorPrefs.SetFloat("MoveSnapX", snapValue);
EditorPrefs.SetFloat("MoveSnapY", snapValue);
EditorPrefs.SetFloat("MoveSnapZ", snapValue);
if (EditorPrefs.GetBool(pg_Constant.SnapScale, true))
EditorPrefs.SetFloat("ScaleSnap", snapValue);
// If Unity snap sync is enabled, refresh the Snap Settings window if it's open.
Type snapSettings = typeof(EditorWindow).Assembly.GetType("UnityEditor.SnapSettings");
if (snapSettings != null)
{
FieldInfo snapInitialized = snapSettings.GetField("s_Initialized", BindingFlags.NonPublic | BindingFlags.Static);
if (snapInitialized != null)
{
snapInitialized.SetValue(null, (object)false);
EditorWindow win = Resources.FindObjectsOfTypeAll<EditorWindow>().FirstOrDefault(x => x.ToString().Contains("SnapSettings"));
if (win != null)
win.Repaint();
}
}
}
gridRepaint = true;
}
public void SetRenderPlane(Axis axis)
{
offset = 0f;
fullGrid = false;
renderPlane = axis;
EditorPrefs.SetBool(pg_Constant.PerspGrid, fullGrid);
EditorPrefs.SetInt(pg_Constant.GridAxis, (int)renderPlane);
gridRepaint = true;
RepaintSceneView();
}
public void SetGridEnabled(bool enable)
{
drawGrid = enable;
if (!drawGrid)
pg_GridRenderer.Destroy();
else
pg_Util.SetUnityGridEnabled(false);
EditorPrefs.SetBool("showgrid", enable);
gridRepaint = true;
RepaintSceneView();
}
public void SetDrawAngles(bool enable)
{
drawAngles = enable;
gridRepaint = true;
RepaintSceneView();
}
private void SnapToGrid(Transform[] transforms)
{
Undo.RecordObjects(transforms as UnityEngine.Object[], "Snap to Grid");
foreach (Transform t in transforms)
t.position = pg_Util.SnapValue(t.position, snapValue);
gridRepaint = true;
PushToGrid(snapValue);
}
#endregion
#region GLOBAL SETTING
internal bool GetUseAxisConstraints() { return toggleAxisConstraint ? !useAxisConstraints : useAxisConstraints; }
internal float GetSnapValue() { return snapValue; }
internal bool GetSnapEnabled() { return (toggleTempSnap ? !snapEnabled : snapEnabled); }
/**
* Returns the value of useAxisConstraints, accounting for the shortcut key toggle.
*/
public static bool UseAxisConstraints()
{
return instance != null ? instance.GetUseAxisConstraints() : false;
}
/**
* Return the current snap value.
*/
public static float SnapValue()
{
return instance != null ? instance.GetSnapValue() : 0f;
}
/**
* Return true if snapping is enabled, false otherwise.
*/
public static bool SnapEnabled()
{
return instance == null ? false : instance.GetSnapEnabled();
}
public static void AddPushToGridListener(System.Action<float> listener)
{
pushToGridListeners.Add(listener);
}
public static void RemovePushToGridListener(System.Action<float> listener)
{
pushToGridListeners.Remove(listener);
}
public static void AddToolbarEventSubscriber(System.Action<bool> listener)
{
toolbarEventSubscribers.Add(listener);
}
public static void RemoveToolbarEventSubscriber(System.Action<bool> listener)
{
toolbarEventSubscribers.Remove(listener);
}
public static bool SceneToolbarActive()
{
return instance != null;
}
[SerializeField]
static List<System.Action<float>> pushToGridListeners = new List<System.Action<float>>();
[SerializeField]
static List<System.Action<bool>> toolbarEventSubscribers = new List<System.Action<bool>>();
private void PushToGrid(float snapValue)
{
foreach (System.Action<float> listener in pushToGridListeners)
listener(snapValue);
}
public static void OnHandleMove(Vector3 worldDirection)
{
if (instance != null)
instance.OnHandleMove_Internal(worldDirection);
}
private void OnHandleMove_Internal(Vector3 worldDirection)
{
if (predictiveGrid && firstMove && !fullGrid)
{
firstMove = false;
Axis dragAxis = pg_Util.CalcDragAxis(worldDirection, SceneView.lastActiveSceneView.camera);
if (dragAxis != Axis.None && dragAxis != renderPlane)
SetRenderPlane(dragAxis);
}
}
#endregion
}
}