CinemachineFreeLookEditor.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using UnityEngine;
  2. using UnityEditor;
  3. using Cinemachine.Editor;
  4. using System.Collections.Generic;
  5. using Cinemachine.Utility;
  6. namespace Cinemachine
  7. {
  8. [CustomEditor(typeof(CinemachineFreeLook))]
  9. [CanEditMultipleObjects]
  10. internal sealed class CinemachineFreeLookEditor
  11. : CinemachineVirtualCameraBaseEditor<CinemachineFreeLook>
  12. {
  13. /// <summary>Get the property names to exclude in the inspector.</summary>
  14. /// <param name="excluded">Add the names to this list</param>
  15. protected override void GetExcludedPropertiesInInspector(List<string> excluded)
  16. {
  17. base.GetExcludedPropertiesInInspector(excluded);
  18. excluded.Add(FieldPath(x => x.m_Orbits));
  19. if (!Target.m_CommonLens)
  20. excluded.Add(FieldPath(x => x.m_Lens));
  21. if (Target.m_BindingMode == CinemachineTransposer.BindingMode.SimpleFollowWithWorldUp)
  22. {
  23. excluded.Add(FieldPath(x => x.m_Heading));
  24. excluded.Add(FieldPath(x => x.m_RecenterToTargetHeading));
  25. }
  26. }
  27. protected override void OnEnable()
  28. {
  29. base.OnEnable();
  30. Target.UpdateInputAxisProvider();
  31. }
  32. protected override void OnDisable()
  33. {
  34. base.OnDisable();
  35. // Must destroy child editors or we get exceptions
  36. if (m_editors != null)
  37. foreach (UnityEditor.Editor e in m_editors)
  38. if (e != null)
  39. UnityEngine.Object.DestroyImmediate(e);
  40. }
  41. public override void OnInspectorGUI()
  42. {
  43. Target.m_XAxis.ValueRangeLocked
  44. = (Target.m_BindingMode == CinemachineTransposer.BindingMode.SimpleFollowWithWorldUp);
  45. // Ordinary properties
  46. BeginInspector();
  47. DrawHeaderInInspector();
  48. DrawPropertyInInspector(FindProperty(x => x.m_Priority));
  49. DrawTargetsInInspector(FindProperty(x => x.m_Follow), FindProperty(x => x.m_LookAt));
  50. DrawRemainingPropertiesInInspector();
  51. // Orbits
  52. EditorGUI.BeginChangeCheck();
  53. SerializedProperty orbits = FindProperty(x => x.m_Orbits);
  54. for (int i = 0; i < CinemachineFreeLook.RigNames.Length; ++i)
  55. {
  56. Rect rect = EditorGUILayout.GetControlRect(true);
  57. SerializedProperty orbit = orbits.GetArrayElementAtIndex(i);
  58. InspectorUtility.MultiPropertyOnLine(rect,
  59. new GUIContent(CinemachineFreeLook.RigNames[i]),
  60. new [] { orbit.FindPropertyRelative(() => Target.m_Orbits[i].m_Height),
  61. orbit.FindPropertyRelative(() => Target.m_Orbits[i].m_Radius) },
  62. null);
  63. }
  64. if (EditorGUI.EndChangeCheck())
  65. serializedObject.ApplyModifiedProperties();
  66. // Rigs
  67. if (Selection.objects.Length == 1)
  68. {
  69. UpdateRigEditors();
  70. for (int i = 0; i < m_editors.Length; ++i)
  71. {
  72. if (m_editors[i] == null)
  73. continue;
  74. EditorGUILayout.Separator();
  75. EditorGUILayout.BeginVertical(GUI.skin.box);
  76. EditorGUILayout.LabelField(RigNames[i], EditorStyles.boldLabel);
  77. ++EditorGUI.indentLevel;
  78. m_editors[i].OnInspectorGUI();
  79. --EditorGUI.indentLevel;
  80. EditorGUILayout.EndVertical();
  81. }
  82. }
  83. // Extensions
  84. DrawExtensionsWidgetInInspector();
  85. }
  86. string[] RigNames;
  87. CinemachineVirtualCameraBase[] m_rigs;
  88. UnityEditor.Editor[] m_editors;
  89. void UpdateRigEditors()
  90. {
  91. RigNames = CinemachineFreeLook.RigNames;
  92. if (m_rigs == null)
  93. m_rigs = new CinemachineVirtualCameraBase[RigNames.Length];
  94. if (m_editors == null)
  95. m_editors = new UnityEditor.Editor[RigNames.Length];
  96. for (int i = 0; i < RigNames.Length; ++i)
  97. {
  98. CinemachineVirtualCamera rig = Target.GetRig(i);
  99. if (rig == null || rig != m_rigs[i])
  100. {
  101. m_rigs[i] = rig;
  102. if (m_editors[i] != null)
  103. UnityEngine.Object.DestroyImmediate(m_editors[i]);
  104. m_editors[i] = null;
  105. if (rig != null)
  106. CreateCachedEditor(rig, null, ref m_editors[i]);
  107. }
  108. }
  109. }
  110. /// <summary>
  111. /// Register with CinemachineFreeLook to create the pipeline in an undo-friendly manner
  112. /// </summary>
  113. [InitializeOnLoad]
  114. class CreateRigWithUndo
  115. {
  116. static CreateRigWithUndo()
  117. {
  118. CinemachineFreeLook.CreateRigOverride
  119. = (CinemachineFreeLook vcam, string name, CinemachineVirtualCamera copyFrom) =>
  120. {
  121. // Create a new rig with default components
  122. GameObject go = InspectorUtility.CreateGameObject(name);
  123. Undo.RegisterCreatedObjectUndo(go, "created rig");
  124. Undo.SetTransformParent(go.transform, vcam.transform, "parenting rig");
  125. CinemachineVirtualCamera rig = Undo.AddComponent<CinemachineVirtualCamera>(go);
  126. Undo.RecordObject(rig, "creating rig");
  127. if (copyFrom != null)
  128. ReflectionHelpers.CopyFields(copyFrom, rig);
  129. else
  130. {
  131. go = rig.GetComponentOwner().gameObject;
  132. Undo.RecordObject(Undo.AddComponent<CinemachineOrbitalTransposer>(go), "creating rig");
  133. Undo.RecordObject(Undo.AddComponent<CinemachineComposer>(go), "creating rig");
  134. }
  135. return rig;
  136. };
  137. CinemachineFreeLook.DestroyRigOverride = (GameObject rig) =>
  138. {
  139. Undo.DestroyObjectImmediate(rig);
  140. };
  141. }
  142. }
  143. [DrawGizmo(GizmoType.Active | GizmoType.Selected, typeof(CinemachineFreeLook))]
  144. private static void DrawFreeLookGizmos(CinemachineFreeLook vcam, GizmoType selectionType)
  145. {
  146. // Standard frustum and logo
  147. CinemachineBrainEditor.DrawVirtualCameraBaseGizmos(vcam, selectionType);
  148. Color originalGizmoColour = Gizmos.color;
  149. bool isActiveVirtualCam = CinemachineCore.Instance.IsLive(vcam);
  150. Gizmos.color = isActiveVirtualCam
  151. ? CinemachineSettings.CinemachineCoreSettings.ActiveGizmoColour
  152. : CinemachineSettings.CinemachineCoreSettings.InactiveGizmoColour;
  153. if (vcam.Follow != null)
  154. {
  155. Vector3 pos = vcam.Follow.position;
  156. Vector3 up = vcam.State.ReferenceUp;
  157. var MiddleRig = vcam.GetRig(1).GetCinemachineComponent<CinemachineOrbitalTransposer>();
  158. if (MiddleRig != null)
  159. {
  160. Quaternion orient = MiddleRig.GetReferenceOrientation(up);
  161. up = orient * Vector3.up;
  162. float rotation = vcam.m_XAxis.Value + vcam.m_Heading.m_Bias;
  163. orient = Quaternion.AngleAxis(rotation, up) * orient;
  164. CinemachineOrbitalTransposerEditor.DrawCircleAtPointWithRadius(
  165. pos + up * vcam.m_Orbits[0].m_Height, orient, vcam.m_Orbits[0].m_Radius);
  166. CinemachineOrbitalTransposerEditor.DrawCircleAtPointWithRadius(
  167. pos + up * vcam.m_Orbits[1].m_Height, orient, vcam.m_Orbits[1].m_Radius);
  168. CinemachineOrbitalTransposerEditor.DrawCircleAtPointWithRadius(
  169. pos + up * vcam.m_Orbits[2].m_Height, orient, vcam.m_Orbits[2].m_Radius);
  170. DrawCameraPath(pos, orient, vcam);
  171. }
  172. }
  173. Gizmos.color = originalGizmoColour;
  174. }
  175. private static void DrawCameraPath(Vector3 atPos, Quaternion orient, CinemachineFreeLook vcam)
  176. {
  177. Matrix4x4 prevMatrix = Gizmos.matrix;
  178. Gizmos.matrix = Matrix4x4.TRS(atPos, orient, Vector3.one);
  179. const int kNumSteps = 20;
  180. Vector3 currPos = vcam.GetLocalPositionForCameraFromInput(0f);
  181. for (int i = 1; i < kNumSteps + 1; ++i)
  182. {
  183. float t = (float)i / (float)kNumSteps;
  184. Vector3 nextPos = vcam.GetLocalPositionForCameraFromInput(t);
  185. Gizmos.DrawLine(currPos, nextPos);
  186. currPos = nextPos;
  187. }
  188. Gizmos.matrix = prevMatrix;
  189. }
  190. }
  191. }