| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773 |
- #if UNITY_2021_2_OR_NEWER
- using System;
- using System.Collections.Generic;
- using Cinemachine.Utility;
- using UnityEditor;
- using UnityEditor.EditorTools;
- using UnityEngine;
- namespace Cinemachine.Editor
- {
- /// <summary>
- /// Static class that manages Cinemachine Tools. It knows which tool is active,
- /// and ensures that exclusive tools are not active at the same time.
- /// The tools and editors requiring tools register/unregister themselves here.
- /// </summary>
- static class CinemachineSceneToolUtility
- {
- #if UNITY_2022_1_OR_NEWER
- /// <summary>
- /// Checks whether tool is the currently active exclusive tool.
- /// </summary>
- /// <param name="tool">Tool to check.</param>
- /// <returns>True, when the tool is the active exclusive tool. False, otherwise.</returns>
- public static bool IsToolActive(Type tool)
- {
- return s_ActiveExclusiveTool == tool;
- }
- static Type s_ActiveExclusiveTool;
- /// <summary>
- /// Register your Type from the editor script's OnEnable function.
- /// This way CinemachineTools will know which tools to display.
- /// </summary>
- /// <param name="tool">Tool to register</param>
- public static void RegisterTool(Type tool)
- {
- if (s_RequiredTools.ContainsKey(tool))
- {
- s_RequiredTools[tool]++;
- }
- else
- {
- s_RequiredTools.Add(tool, 1);
- }
- s_TriggerToolBarRefresh = true;
- }
-
- /// <summary>
- /// Unregister your Type from the editor script's OnDisable function.
- /// This way CinemachineTools will know which tools to display.
- /// </summary>
- /// <param name="tool">Tool to register</param>
- public static void UnregisterTool(Type tool)
- {
- if (s_RequiredTools.ContainsKey(tool))
- {
- s_RequiredTools[tool]--;
- if (s_RequiredTools[tool] <= 0)
- {
- s_RequiredTools.Remove(tool);
- }
- }
- s_TriggerToolBarRefresh = true;
- }
- internal static bool IsToolRequired(Type tool)
- {
- return s_RequiredTools.ContainsKey(tool);
- }
- static Dictionary<Type, int> s_RequiredTools;
-
- internal static void SetTool(bool active, Type tool)
- {
- if (active)
- {
- s_ActiveExclusiveTool = tool;
- }
- else
- {
- s_ActiveExclusiveTool = s_ActiveExclusiveTool == tool ? null : s_ActiveExclusiveTool;
- }
-
- s_TriggerToolBarRefresh = true;
- }
- static CinemachineSceneToolUtility()
- {
- s_RequiredTools = new Dictionary<Type, int>();
- EditorApplication.update += RefreshToolbar;
- }
- static bool s_TriggerToolBarRefresh;
- static void RefreshToolbar()
- {
- if (s_TriggerToolBarRefresh)
- {
- #if UNITY_2022_2_OR_NEWER
- ToolManager.RefreshAvailableTools();
- #else
- // The following is a hack to refresh the toolbars
- foreach (var scene in SceneView.sceneViews)
- {
- if (((SceneView)scene).TryGetOverlay("unity-transform-toolbar", out var tools))
- {
- if (tools.displayed)
- {
- tools.displayed = false;
- tools.displayed = true;
- break;
- }
- }
- }
- #endif
- s_TriggerToolBarRefresh = false;
- }
- }
- #else
- /// <summary>
- /// Checks whether tool is the currently active exclusive tool.
- /// </summary>
- /// <param name="tool">Tool to check.</param>
- /// <returns>True, when the tool is the active exclusive tool. False, otherwise.</returns>
- public static bool IsToolActive(Type tool)
- {
- return s_ActiveExclusiveTool == tool;
- }
- static Type s_ActiveExclusiveTool;
- /// <summary>
- /// Register your Type from the editor script's OnEnable function.
- /// This way CinemachineTools will know which tools to display.
- /// </summary>
- /// <param name="tool">Tool to register</param>
- public static void RegisterTool(Type tool)
- {
- if (s_RequiredTools.ContainsKey(tool))
- {
- s_RequiredTools[tool]++;
- }
- else
- {
- s_RequiredTools.Add(tool, 1);
- }
- }
-
- /// <summary>
- /// Unregister your Type from the editor script's OnDisable function.
- /// This way CinemachineTools will know which tools to display.
- /// </summary>
- /// <param name="tool">Tool to register</param>
- public static void UnregisterTool(Type tool)
- {
- if (s_RequiredTools.ContainsKey(tool))
- {
- s_RequiredTools[tool]--;
- if (s_RequiredTools[tool] <= 0)
- {
- s_RequiredTools.Remove(tool);
- }
- }
- }
- static Dictionary<Type, int> s_RequiredTools;
- public delegate void ToolHandler(bool v);
- struct CinemachineSceneToolDelegates
- {
- public ToolHandler ToggleSetter;
- public ToolHandler IsDisplayedSetter;
- }
- static Dictionary<Type, CinemachineSceneToolDelegates> s_ExclusiveTools; // tools that can't be active at the same time
- static Dictionary<Type, CinemachineSceneToolDelegates> s_Tools; // tools without restrictions
-
- /// <summary>
- /// Use for registering tool handlers for tools that are exclusive with each other,
- /// meaning they cannot be active at the same time.
- /// </summary>
- /// <param name="tool">The tool to register.</param>
- /// <param name="toggleSetter">The tool's toggle value setter.</param>
- /// <param name="isDisplayedSetter">The tool's isDisplayed setter.</param>
- internal static void RegisterExclusiveToolHandlers(Type tool, ToolHandler toggleSetter, ToolHandler isDisplayedSetter)
- {
- RegisterToolHandlers(ref s_ExclusiveTools, tool, toggleSetter, isDisplayedSetter);
- }
-
- /// <summary>
- /// Use for registering tool handlers for tools that can be active anytime
- /// without taking other tools into consideration.
- /// </summary>
- /// <param name="tool">The tool to register.</param>
- /// <param name="toggleSetter">The tool's toggle value setter.</param>
- /// <param name="isDisplayedSetter">The tool's isDisplayed setter.</param>
- internal static void RegisterToolHandlers(Type tool, ToolHandler toggleSetter, ToolHandler isDisplayedSetter)
- {
- RegisterToolHandlers(ref s_Tools, tool, toggleSetter, isDisplayedSetter);
- }
- static void RegisterToolHandlers(ref Dictionary<Type, CinemachineSceneToolDelegates> tools,
- Type tool, ToolHandler toggleSetter, ToolHandler isDisplayedSetter)
- {
- if (tools.ContainsKey(tool))
- {
- tools.Remove(tool);
- }
-
- tools.Add(tool, new CinemachineSceneToolDelegates
- {
- ToggleSetter = toggleSetter,
- IsDisplayedSetter = isDisplayedSetter,
- });
- }
-
- internal delegate bool ToolbarHandler();
- static ToolbarHandler s_ToolBarIsDisplayed;
- internal static void RegisterToolbarIsDisplayedHandler(ToolbarHandler handler)
- {
- s_ToolBarIsDisplayed = handler;
- }
- static bool s_ToolbarTurnOffByMe;
- internal delegate bool ToolbarTurnOnOffHandler(bool on);
- static ToolbarTurnOnOffHandler s_ToolBarDisplay;
- internal static void RegisterToolbarDisplayHandler(ToolbarTurnOnOffHandler handler)
- {
- s_ToolBarDisplay = handler;
- }
- internal static void SetTool(bool active, Type tool)
- {
- if (active)
- {
- s_ActiveExclusiveTool = tool;
- EnsureCinemachineToolsAreExclusiveWithUnityTools();
- }
- else
- {
- s_ActiveExclusiveTool = s_ActiveExclusiveTool == tool ? null : s_ActiveExclusiveTool;
- }
- }
- static void EnsureCinemachineToolsAreExclusiveWithUnityTools()
- {
- foreach (var toolHandle in s_ExclusiveTools)
- {
- toolHandle.Value.ToggleSetter(toolHandle.Key == s_ActiveExclusiveTool);
- }
- if (s_ActiveExclusiveTool != null)
- {
- Tools.current = Tool.None; // Cinemachine tools are exclusive with unity tools
- }
- }
-
- static CinemachineSceneToolUtility()
- {
- s_ExclusiveTools = new Dictionary<Type, CinemachineSceneToolDelegates>();
- s_Tools = new Dictionary<Type, CinemachineSceneToolDelegates>();
- s_RequiredTools = new Dictionary<Type, int>();
- EditorApplication.update += () =>
- {
- if (s_RequiredTools.Count <= 0)
- {
- s_ToolbarTurnOffByMe |= s_ToolBarDisplay(false);
- }
- else if (s_ToolbarTurnOffByMe)
- {
- s_ToolBarDisplay(true);
- s_ToolbarTurnOffByMe = false;
- }
-
- var cmToolbarIsHidden = !s_ToolBarIsDisplayed();
- // if a unity tool is selected or cmToolbar is hidden, unselect our tools.
- if (s_ActiveExclusiveTool != null && (Tools.current != Tool.None || cmToolbarIsHidden))
- {
- SetTool(true, null);
- }
- if (!cmToolbarIsHidden)
- {
- // only display cm tools that are relevant for the current selection
- foreach (var toolHandle in s_ExclusiveTools)
- {
- toolHandle.Value.IsDisplayedSetter(s_RequiredTools.ContainsKey(toolHandle.Key));
- }
- foreach (var toolHandle in s_Tools)
- {
- toolHandle.Value.IsDisplayedSetter(s_RequiredTools.ContainsKey(toolHandle.Key));
- }
- }
- };
- }
- #endif
- }
-
- static class CinemachineSceneToolHelpers
- {
- public const float LineThickness = 2f;
- public static readonly Color HelperLineDefaultColor = new Color(255, 255, 255, 25);
- const float k_DottedLineSpacing = 4f;
- static GUIStyle s_LabelStyle = new GUIStyle
- {
- normal =
- {
- background = AssetDatabase.LoadAssetAtPath<Texture2D>(ScriptableObjectUtility.
- CinemachineRealativeInstallPath + "/Editor/EditorResources/SceneToolsLabelBackground.png"),
- textColor = Handles.selectedColor,
- },
- fontStyle = FontStyle.Bold,
- padding = new RectOffset(5, 0, 5, 0)
- };
-
- public static float SliderHandleDelta(Vector3 newPos, Vector3 oldPos, Vector3 forward)
- {
- var delta = newPos - oldPos;
- return Mathf.Sign(Vector3.Dot(delta, forward)) * delta.magnitude;
- }
- /// <summary>
- /// Calculate delta and discard imprecision.
- /// </summary>
- public static Vector3 PositionHandleDelta(Quaternion rot, Vector3 newPos, Vector3 oldPos)
- {
- var delta =
- Quaternion.Inverse(rot) * (newPos - oldPos);
- delta = new Vector3(
- Mathf.Abs(delta.x) < UnityVectorExtensions.Epsilon ? 0 : delta.x,
- Mathf.Abs(delta.y) < UnityVectorExtensions.Epsilon ? 0 : delta.y,
- Mathf.Abs(delta.z) < UnityVectorExtensions.Epsilon ? 0 : delta.z);
- return delta;
- }
-
- public static void DrawLabel(Vector3 position, string text)
- {
- var labelOffset = HandleUtility.GetHandleSize(position) / 5f;
- Handles.Label(position + new Vector3(0, -labelOffset, 0), text, s_LabelStyle);
- }
- public static float CubeHandleCapSize(Vector3 position) => HandleUtility.GetHandleSize(position) / 10f;
- static int s_ScaleSliderHash = "ScaleSliderHash".GetHashCode();
- static float s_FOVAfterLastToolModification;
- public static void FovToolHandle(CinemachineVirtualCameraBase vcam, SerializedProperty lensProperty,
- in LensSettings lens, bool isLensHorizontal)
- {
- var orthographic = lens.Orthographic;
- if (GUIUtility.hotControl == 0)
- {
- s_FOVAfterLastToolModification = orthographic ? lens.OrthographicSize : lens.FieldOfView;
- }
- var originalColor = Handles.color;
- Handles.color = Handles.preselectionColor;
-
- var camPos = vcam.State.FinalPosition;
- var camRot = vcam.State.FinalOrientation;
- var camForward = camRot * Vector3.forward;
-
- EditorGUI.BeginChangeCheck();
- #if UNITY_2022_2_OR_NEWER
- var fovHandleId = GUIUtility.GetControlID(s_ScaleSliderHash, FocusType.Passive);
- var newFov = Handles.ScaleSlider(fovHandleId, s_FOVAfterLastToolModification,
- camPos, camForward, camRot, HandleUtility.GetHandleSize(camPos), 0.1f);
- #else
- var fovHandleId = GUIUtility.GetControlID(s_ScaleSliderHash, FocusType.Passive) + 1;
- var newFov = Handles.ScaleSlider(
- s_FOVAfterLastToolModification, camPos, camForward, camRot, HandleUtility.GetHandleSize(camPos), 0.1f);
- #endif
- if (EditorGUI.EndChangeCheck())
- {
- if (orthographic)
- {
- lensProperty.FindPropertyRelative("OrthographicSize").floatValue +=
- (s_FOVAfterLastToolModification - newFov);
- }
- else
- {
- lensProperty.FindPropertyRelative("FieldOfView").floatValue +=
- (s_FOVAfterLastToolModification - newFov);
- lensProperty.FindPropertyRelative("FieldOfView").floatValue =
- Mathf.Clamp(lensProperty.FindPropertyRelative("FieldOfView").floatValue, 1f, 179f);
- }
- lensProperty.serializedObject.ApplyModifiedProperties();
- }
- s_FOVAfterLastToolModification = newFov;
- var fovHandleDraggedOrHovered =
- GUIUtility.hotControl == fovHandleId || HandleUtility.nearestControl == fovHandleId;
- if (fovHandleDraggedOrHovered)
- {
- var labelPos = camPos + camForward * HandleUtility.GetHandleSize(camPos);
- if (lens.IsPhysicalCamera)
- {
- DrawLabel(labelPos, "Focal Length (" +
- Camera.FieldOfViewToFocalLength(lens.FieldOfView, lens.SensorSize.y).ToString("F1") + ")");
- }
- else if (orthographic)
- {
- DrawLabel(labelPos, "Orthographic Size (" +
- lens.OrthographicSize.ToString("F1") + ")");
- }
- else if (isLensHorizontal)
- {
- DrawLabel(labelPos, "Horizontal FOV (" +
- Camera.VerticalToHorizontalFieldOfView(lens.FieldOfView, lens.Aspect).ToString("F1") + ")");
- }
- else
- {
- DrawLabel(labelPos, "Vertical FOV (" +
- lens.FieldOfView.ToString("F1") + ")");
- }
- }
-
- Handles.color = fovHandleDraggedOrHovered ? Handles.selectedColor : HelperLineDefaultColor;
- var vcamLocalToWorld = Matrix4x4.TRS(camPos, camRot, Vector3.one);
- DrawFrustum(vcamLocalToWorld, lens);
-
- SoloOnDrag(GUIUtility.hotControl == fovHandleId, vcam, fovHandleId);
- Handles.color = originalColor;
- }
- public static void NearFarClipHandle(CinemachineVirtualCameraBase vcam, SerializedProperty lens)
- {
- var originalColor = Handles.color;
- Handles.color = Handles.preselectionColor;
-
- var vcamState = vcam.State;
- var camPos = vcamState.FinalPosition;
- var camRot = vcamState.FinalOrientation;
- var camForward = camRot * Vector3.forward;
- var nearClipPlane = lens.FindPropertyRelative("NearClipPlane");
- var farClipPlane = lens.FindPropertyRelative("FarClipPlane");
- var nearClipPos = camPos + camForward * nearClipPlane.floatValue;
- var farClipPos = camPos + camForward * farClipPlane.floatValue;
- var vcamLens = vcamState.Lens;
-
- EditorGUI.BeginChangeCheck();
- var ncHandleId = GUIUtility.GetControlID(FocusType.Passive);
- var newNearClipPos = Handles.Slider(ncHandleId, nearClipPos, camForward,
- CubeHandleCapSize(nearClipPos), Handles.CubeHandleCap, 0.5f);
- var fcHandleId = GUIUtility.GetControlID(FocusType.Passive);
- var newFarClipPos = Handles.Slider(fcHandleId, farClipPos, camForward,
- CubeHandleCapSize(farClipPos), Handles.CubeHandleCap, 0.5f);
- if (EditorGUI.EndChangeCheck())
- {
- nearClipPlane.floatValue +=
- SliderHandleDelta(newNearClipPos, nearClipPos, camForward);
- if (!vcamLens.Orthographic)
- {
- nearClipPlane.floatValue = Mathf.Max(0.01f, nearClipPlane.floatValue);
- }
- farClipPlane.floatValue +=
- SliderHandleDelta(newFarClipPos, farClipPos, camForward);
- lens.serializedObject.ApplyModifiedProperties();
- }
-
- var vcamLocalToWorld = Matrix4x4.TRS(camPos, camRot, Vector3.one);
- Handles.color = HelperLineDefaultColor;
- DrawFrustum(vcamLocalToWorld, vcamLens);
- if (GUIUtility.hotControl == ncHandleId || HandleUtility.nearestControl == ncHandleId)
- {
- DrawPreFrustum(vcamLocalToWorld, vcamLens);
- DrawLabel(nearClipPos, "Near Clip Plane (" + nearClipPlane.floatValue.ToString("F1") + ")");
- }
- if (GUIUtility.hotControl == fcHandleId || HandleUtility.nearestControl == fcHandleId)
- {
- DrawPreFrustum(vcamLocalToWorld, vcamLens);
- DrawLabel(farClipPos, "Far Clip Plane (" + farClipPlane.floatValue.ToString("F1") + ")");
- }
-
- SoloOnDrag(GUIUtility.hotControl == ncHandleId || GUIUtility.hotControl == fcHandleId,
- vcam, Mathf.Min(ncHandleId, fcHandleId));
- Handles.color = originalColor;
- }
- static void DrawPreFrustum(Matrix4x4 transform, LensSettings lens)
- {
- if (!lens.Orthographic && lens.NearClipPlane >= 0)
- {
- DrawPerspectiveFrustum(transform, lens.FieldOfView,
- lens.NearClipPlane, 0, lens.Aspect, true);
- }
- }
- static void DrawFrustum(Matrix4x4 transform, LensSettings lens)
- {
- if (lens.Orthographic)
- {
- DrawOrthographicFrustum(transform, lens.OrthographicSize,
- lens.FarClipPlane, lens.NearClipPlane, lens.Aspect);
- }
- else
- {
- DrawPerspectiveFrustum(transform, lens.FieldOfView,
- lens.FarClipPlane, lens.NearClipPlane, lens.Aspect, false);
- }
- }
- static void DrawOrthographicFrustum(Matrix4x4 transform,
- float orthographicSize, float farClipPlane, float nearClipRange, float aspect)
- {
- var originalMatrix = Handles.matrix;
- Handles.matrix = transform;
-
- var size = new Vector3(aspect * orthographicSize * 2,
- orthographicSize * 2, farClipPlane - nearClipRange);
- Handles.DrawWireCube(new Vector3(0, 0, (size.z / 2) + nearClipRange), size);
-
- Handles.matrix = originalMatrix;
- }
-
- static void DrawPerspectiveFrustum(Matrix4x4 transform,
- float fov, float farClipPlane, float nearClipRange, float aspect, bool dottedLine)
- {
- var originalMatrix = Handles.matrix;
- Handles.matrix = transform;
-
- fov = fov * 0.5f * Mathf.Deg2Rad;
- var tanfov = Mathf.Tan(fov);
- var farEnd = new Vector3(0, 0, farClipPlane);
- var endSizeX = new Vector3(farClipPlane * tanfov * aspect, 0, 0);
- var endSizeY = new Vector3(0, farClipPlane * tanfov, 0);
- Vector3 s1, s2, s3, s4;
- var e1 = farEnd + endSizeX + endSizeY;
- var e2 = farEnd - endSizeX + endSizeY;
- var e3 = farEnd - endSizeX - endSizeY;
- var e4 = farEnd + endSizeX - endSizeY;
- if (nearClipRange <= 0.0f)
- {
- s1 = s2 = s3 = s4 = Vector3.zero;
- }
- else
- {
- var startSizeX = new Vector3(nearClipRange * tanfov * aspect, 0, 0);
- var startSizeY = new Vector3(0, nearClipRange * tanfov, 0);
- var startPoint = new Vector3(0, 0, nearClipRange);
- s1 = startPoint + startSizeX + startSizeY;
- s2 = startPoint - startSizeX + startSizeY;
- s3 = startPoint - startSizeX - startSizeY;
- s4 = startPoint + startSizeX - startSizeY;
- if (dottedLine)
- {
- Handles.DrawDottedLine(s1, s2, k_DottedLineSpacing);
- Handles.DrawDottedLine(s2, s3, k_DottedLineSpacing);
- Handles.DrawDottedLine(s3, s4, k_DottedLineSpacing);
- Handles.DrawDottedLine(s4, s1, k_DottedLineSpacing);
- }
- else
- {
- Handles.DrawLine(s1, s2);
- Handles.DrawLine(s2, s3);
- Handles.DrawLine(s3, s4);
- Handles.DrawLine(s4, s1);
- }
- }
- if (dottedLine)
- {
- Handles.DrawDottedLine(e1, e2, k_DottedLineSpacing);
- Handles.DrawDottedLine(e2, e3, k_DottedLineSpacing);
- Handles.DrawDottedLine(e3, e4, k_DottedLineSpacing);
- Handles.DrawDottedLine(e4, e1, k_DottedLineSpacing);
- Handles.DrawDottedLine(s1, e1, k_DottedLineSpacing);
- Handles.DrawDottedLine(s2, e2, k_DottedLineSpacing);
- Handles.DrawDottedLine(s3, e3, k_DottedLineSpacing);
- Handles.DrawDottedLine(s4, e4, k_DottedLineSpacing);
- }
- else
- {
- Handles.DrawLine(e1, e2);
- Handles.DrawLine(e2, e3);
- Handles.DrawLine(e3, e4);
- Handles.DrawLine(e4, e1);
- Handles.DrawLine(s1, e1);
- Handles.DrawLine(s2, e2);
- Handles.DrawLine(s3, e3);
- Handles.DrawLine(s4, e4);
- }
- Handles.matrix = originalMatrix;
- }
- public static void TrackedObjectOffsetTool(
- CinemachineComponentBase cmComponent, SerializedProperty trackedObjectOffset)
- {
- var originalColor = Handles.color;
-
- var lookAtPos = cmComponent.LookAtTargetPosition;
- var lookAtRot = cmComponent.LookAtTargetRotation;
- var trackedObjectPos = lookAtPos + lookAtRot * trackedObjectOffset.vector3Value;
- EditorGUI.BeginChangeCheck();
- #if UNITY_2022_2_OR_NEWER
- var tooHandleIds = Handles.PositionHandleIds.@default;
- var newTrackedObjectPos = Handles.PositionHandle(tooHandleIds, trackedObjectPos, lookAtRot);
- var tooHandleMinId = tooHandleIds.x - 1;
- var tooHandleMaxId = tooHandleIds.xyz + 1;
- #else
- var tooHandleMinId = GUIUtility.GetControlID(FocusType.Passive);
- var newTrackedObjectPos = Handles.PositionHandle(trackedObjectPos, lookAtRot);
- var tooHandleMaxId = GUIUtility.GetControlID(FocusType.Passive);
- #endif
- if (EditorGUI.EndChangeCheck())
- {
- trackedObjectOffset.vector3Value +=
- PositionHandleDelta(lookAtRot, newTrackedObjectPos, trackedObjectPos);
- trackedObjectOffset.serializedObject.ApplyModifiedProperties();
- }
- var trackedObjectOffsetHandleIsDragged =
- tooHandleMinId < GUIUtility.hotControl && GUIUtility.hotControl < tooHandleMaxId;
- var trackedObjectOffsetHandleIsUsedOrHovered = trackedObjectOffsetHandleIsDragged ||
- tooHandleMinId < HandleUtility.nearestControl && HandleUtility.nearestControl < tooHandleMaxId;
- if (trackedObjectOffsetHandleIsUsedOrHovered)
- {
- DrawLabel(trackedObjectPos, "(" + cmComponent.Stage + ") Tracked Object Offset "
- + trackedObjectOffset.vector3Value.ToString("F1"));
- }
-
- Handles.color = trackedObjectOffsetHandleIsUsedOrHovered ?
- Handles.selectedColor : HelperLineDefaultColor;
- Handles.DrawDottedLine(lookAtPos, trackedObjectPos, k_DottedLineSpacing);
- Handles.DrawLine(trackedObjectPos, cmComponent.VcamState.FinalPosition);
- SoloOnDrag(trackedObjectOffsetHandleIsDragged, cmComponent.VirtualCamera, tooHandleMaxId);
-
- Handles.color = originalColor;
- }
- public static void TransposerFollowOffsetTool(CinemachineTransposer cmComponent)
- {
- var originalColor = Handles.color;
-
- var brain = CinemachineCore.Instance.FindPotentialTargetBrain(cmComponent.VirtualCamera);
- var up = brain != null ? brain.DefaultWorldUp : Vector3.up;
- var camPos = cmComponent.GetTargetCameraPosition(up);
- var camRot = cmComponent.GetReferenceOrientation(up);
- EditorGUI.BeginChangeCheck();
- #if UNITY_2022_2_OR_NEWER
- var foHandleIds = Handles.PositionHandleIds.@default;
- var newPos = Handles.PositionHandle(foHandleIds, camPos, camRot);
- var foHandleMinId = foHandleIds.x - 1;
- var foHandleMaxId = foHandleIds.xyz + 1;
- #else
- var foHandleMinId = GUIUtility.GetControlID(FocusType.Passive);
- var newPos = Handles.PositionHandle(camPos, camRot);
- var foHandleMaxId = GUIUtility.GetControlID(FocusType.Passive);
- #endif
- if (EditorGUI.EndChangeCheck())
- {
- var so = new SerializedObject(cmComponent);
- var followOffset = so.FindProperty(() => cmComponent.m_FollowOffset);
- followOffset.vector3Value += PositionHandleDelta(camRot, newPos, camPos);
- so.ApplyModifiedProperties();
- followOffset.vector3Value = cmComponent.EffectiveOffset;
- so.ApplyModifiedProperties();
- }
- var followOffsetHandleIsDragged =
- foHandleMinId < GUIUtility.hotControl && GUIUtility.hotControl < foHandleMaxId;
- var followOffsetHandleIsDraggedOrHovered = followOffsetHandleIsDragged ||
- foHandleMinId < HandleUtility.nearestControl && HandleUtility.nearestControl < foHandleMaxId;
- if (followOffsetHandleIsDraggedOrHovered)
- {
- DrawLabel(camPos, "Follow offset " + cmComponent.m_FollowOffset.ToString("F1"));
- }
- Handles.color = followOffsetHandleIsDraggedOrHovered ? Handles.selectedColor : HelperLineDefaultColor;
- Handles.DrawDottedLine(cmComponent.FollowTargetPosition, camPos, k_DottedLineSpacing);
-
- SoloOnDrag(followOffsetHandleIsDragged, cmComponent.VirtualCamera, foHandleMaxId);
-
- Handles.color = originalColor;
- }
-
- /// <summary>
- /// Draws Orbit handles (e.g. for freelook)
- /// </summary>
- /// <returns>Index of the rig being edited, or -1 if none</returns>
- public static int OrbitControlHandle(
- CinemachineVirtualCameraBase vcam, SerializedProperty orbits)
- {
- var originalColor = Handles.color;
- var followPos = vcam.Follow.position;
- var draggedRig = -1;
- var minIndex = 1;
- for (var rigIndex = 0; rigIndex < orbits.arraySize; ++rigIndex)
- {
- var orbit = orbits.GetArrayElementAtIndex(rigIndex);
- var orbitHeight = orbit.FindPropertyRelative("m_Height");
- var orbitRadius = orbit.FindPropertyRelative("m_Radius");
- Handles.color = Handles.preselectionColor;
- EditorGUI.BeginChangeCheck();
-
- var heightHandleId = GUIUtility.GetControlID(FocusType.Passive);
- var heightHandlePos = followPos + Vector3.up * orbitHeight.floatValue;
- var newHeightHandlePos = Handles.Slider(heightHandleId, heightHandlePos, Vector3.up,
- CubeHandleCapSize(heightHandlePos), Handles.CubeHandleCap, 0.5f);
-
- var radiusHandleOffset = Vector3.right;
- var radiusHandleId = GUIUtility.GetControlID(FocusType.Passive);
- var radiusHandlePos = followPos + Vector3.up * orbitHeight.floatValue
- + radiusHandleOffset * orbitRadius.floatValue;
- var newRadiusHandlePos = Handles.Slider(radiusHandleId, radiusHandlePos, radiusHandleOffset,
- CubeHandleCapSize(radiusHandlePos), Handles.CubeHandleCap, 0.5f);
- if (EditorGUI.EndChangeCheck())
- {
- orbitHeight.floatValue +=
- SliderHandleDelta(newHeightHandlePos, heightHandlePos, Vector3.up);
- orbitRadius.floatValue +=
- SliderHandleDelta(newRadiusHandlePos, radiusHandlePos, radiusHandleOffset);
- orbits.serializedObject.ApplyModifiedProperties();
- }
- var isDragged = GUIUtility.hotControl == heightHandleId || GUIUtility.hotControl == radiusHandleId;
- Handles.color = isDragged || HandleUtility.nearestControl == heightHandleId ||
- HandleUtility.nearestControl == radiusHandleId ? Handles.selectedColor : HelperLineDefaultColor;
- if (GUIUtility.hotControl == heightHandleId || HandleUtility.nearestControl == heightHandleId)
- {
- DrawLabel(heightHandlePos, "Height: " + orbitHeight.floatValue);
- }
- if (GUIUtility.hotControl == radiusHandleId || HandleUtility.nearestControl == radiusHandleId)
- {
- DrawLabel(radiusHandlePos, "Radius: " + orbitRadius.floatValue);
- }
- Handles.DrawWireDisc(newHeightHandlePos, Vector3.up, orbitRadius.floatValue);
- if (isDragged)
- {
- draggedRig = rigIndex;
- minIndex = Mathf.Min(Mathf.Min(heightHandleId), radiusHandleId);
- }
- }
- SoloOnDrag(draggedRig != -1, vcam, minIndex);
- Handles.color = originalColor;
- return draggedRig;
- }
-
- static bool s_IsDragging;
- static ICinemachineCamera s_UserSolo;
- public static void SoloOnDrag(bool isDragged, ICinemachineCamera vcam, int handleMaxId)
- {
- if (isDragged)
- {
- if (!s_IsDragging)
- {
- s_UserSolo = CinemachineBrain.SoloCamera;
- s_IsDragging = true;
- }
- CinemachineBrain.SoloCamera = vcam;
- }
- else if (s_IsDragging && handleMaxId != -1) // Handles sometimes return -1 as id, ignore those frames
- {
- CinemachineBrain.SoloCamera = s_UserSolo;
- InspectorUtility.RepaintGameView();
- s_IsDragging = false;
- s_UserSolo = null;
- }
- }
- }
- }
- #endif
|