CinemachineConfinerEditor.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #if !UNITY_2019_3_OR_NEWER
  2. #define CINEMACHINE_PHYSICS
  3. #define CINEMACHINE_PHYSICS_2D
  4. #endif
  5. using UnityEngine;
  6. using UnityEditor;
  7. using System;
  8. using System.Collections.Generic;
  9. namespace Cinemachine.Editor
  10. {
  11. #if CINEMACHINE_PHYSICS || CINEMACHINE_PHYSICS_2D
  12. [CustomEditor(typeof(CinemachineConfiner))]
  13. [CanEditMultipleObjects]
  14. internal sealed class CinemachineConfinerEditor : BaseEditor<CinemachineConfiner>
  15. {
  16. /// <summary>Get the property names to exclude in the inspector.</summary>
  17. /// <param name="excluded">Add the names to this list</param>
  18. protected override void GetExcludedPropertiesInInspector(List<string> excluded)
  19. {
  20. base.GetExcludedPropertiesInInspector(excluded);
  21. CinemachineBrain brain = CinemachineCore.Instance.FindPotentialTargetBrain(Target.VirtualCamera);
  22. bool ortho = brain != null ? brain.OutputCamera.orthographic : false;
  23. if (!ortho)
  24. excluded.Add(FieldPath(x => x.m_ConfineScreenEdges));
  25. #if CINEMACHINE_PHYSICS && CINEMACHINE_PHYSICS_2D
  26. if (Target.m_ConfineMode == CinemachineConfiner.Mode.Confine2D)
  27. excluded.Add(FieldPath(x => x.m_BoundingVolume));
  28. else
  29. excluded.Add(FieldPath(x => x.m_BoundingShape2D));
  30. #endif
  31. }
  32. public override void OnInspectorGUI()
  33. {
  34. BeginInspector();
  35. #if CINEMACHINE_PHYSICS && CINEMACHINE_PHYSICS_2D
  36. if (Target.m_ConfineMode == CinemachineConfiner.Mode.Confine2D)
  37. {
  38. #endif
  39. #if CINEMACHINE_PHYSICS_2D
  40. if (Target.m_BoundingShape2D == null)
  41. EditorGUILayout.HelpBox("A Bounding Shape is required.", MessageType.Warning);
  42. else if (Target.m_BoundingShape2D.GetType() != typeof(PolygonCollider2D)
  43. && Target.m_BoundingShape2D.GetType() != typeof(CompositeCollider2D))
  44. {
  45. EditorGUILayout.HelpBox(
  46. "Must be a PolygonCollider2D or CompositeCollider2D.",
  47. MessageType.Warning);
  48. }
  49. else if (Target.m_BoundingShape2D.GetType() == typeof(CompositeCollider2D))
  50. {
  51. CompositeCollider2D poly = Target.m_BoundingShape2D as CompositeCollider2D;
  52. if (poly.geometryType != CompositeCollider2D.GeometryType.Polygons)
  53. {
  54. EditorGUILayout.HelpBox(
  55. "CompositeCollider2D geometry type must be Polygons",
  56. MessageType.Warning);
  57. }
  58. }
  59. #endif
  60. #if CINEMACHINE_PHYSICS && CINEMACHINE_PHYSICS_2D
  61. }
  62. else
  63. {
  64. #endif
  65. #if CINEMACHINE_PHYSICS
  66. if (Target.m_BoundingVolume == null)
  67. EditorGUILayout.HelpBox("A Bounding Volume is required.", MessageType.Warning);
  68. else if (Target.m_BoundingVolume.GetType() != typeof(BoxCollider)
  69. && Target.m_BoundingVolume.GetType() != typeof(SphereCollider)
  70. && Target.m_BoundingVolume.GetType() != typeof(CapsuleCollider))
  71. {
  72. EditorGUILayout.HelpBox(
  73. "Must be a BoxCollider, SphereCollider, or CapsuleCollider.",
  74. MessageType.Warning);
  75. }
  76. #endif
  77. #if CINEMACHINE_PHYSICS && CINEMACHINE_PHYSICS_2D
  78. }
  79. #endif
  80. DrawRemainingPropertiesInInspector();
  81. }
  82. [DrawGizmo(GizmoType.Active | GizmoType.Selected, typeof(CinemachineConfiner))]
  83. private static void DrawColliderGizmos(CinemachineConfiner confiner, GizmoType type)
  84. {
  85. CinemachineVirtualCameraBase vcam = (confiner != null) ? confiner.VirtualCamera : null;
  86. if (vcam != null && confiner.IsValid)
  87. {
  88. Matrix4x4 oldMatrix = Gizmos.matrix;
  89. Color oldColor = Gizmos.color;
  90. Gizmos.color = Color.yellow;
  91. #if CINEMACHINE_PHYSICS && CINEMACHINE_PHYSICS_2D
  92. if (confiner.m_ConfineMode == CinemachineConfiner.Mode.Confine3D)
  93. {
  94. #endif
  95. #if CINEMACHINE_PHYSICS
  96. Transform t = confiner.m_BoundingVolume.transform;
  97. Gizmos.matrix = Matrix4x4.TRS(t.position, t.rotation, t.lossyScale);
  98. Type colliderType = confiner.m_BoundingVolume.GetType();
  99. if (colliderType == typeof(BoxCollider))
  100. {
  101. BoxCollider c = confiner.m_BoundingVolume as BoxCollider;
  102. Gizmos.DrawWireCube(c.center, c.size);
  103. }
  104. else if (colliderType == typeof(SphereCollider))
  105. {
  106. SphereCollider c = confiner.m_BoundingVolume as SphereCollider;
  107. Gizmos.DrawWireSphere(c.center, c.radius);
  108. }
  109. else if (colliderType == typeof(CapsuleCollider))
  110. {
  111. CapsuleCollider c = confiner.m_BoundingVolume as CapsuleCollider;
  112. Vector3 size = Vector3.one * c.radius * 2;
  113. switch (c.direction)
  114. {
  115. case 0: size.x = c.height; break;
  116. case 1: size.y = c.height; break;
  117. case 2: size.z = c.height; break;
  118. }
  119. Gizmos.DrawWireCube(c.center, size);
  120. }
  121. else if (colliderType == typeof(MeshCollider))
  122. {
  123. MeshCollider c = confiner.m_BoundingVolume as MeshCollider;
  124. Gizmos.DrawWireMesh(c.sharedMesh);
  125. }
  126. else
  127. {
  128. // Just draw an AABB - not very nice!
  129. Gizmos.matrix = oldMatrix;
  130. Bounds bounds = confiner.m_BoundingVolume.bounds;
  131. Gizmos.DrawWireCube(t.position, bounds.extents * 2);
  132. }
  133. #endif
  134. #if CINEMACHINE_PHYSICS && CINEMACHINE_PHYSICS_2D
  135. }
  136. else
  137. {
  138. #endif
  139. #if CINEMACHINE_PHYSICS_2D
  140. Transform t = confiner.m_BoundingShape2D.transform;
  141. Gizmos.matrix = Matrix4x4.TRS(t.position, t.rotation, t.lossyScale);
  142. Type colliderType = confiner.m_BoundingShape2D.GetType();
  143. if (colliderType == typeof(PolygonCollider2D))
  144. {
  145. PolygonCollider2D poly = confiner.m_BoundingShape2D as PolygonCollider2D;
  146. for (int i = 0; i < poly.pathCount; ++i)
  147. DrawPath(poly.GetPath(i), -1);
  148. }
  149. else if (colliderType == typeof(CompositeCollider2D))
  150. {
  151. CompositeCollider2D poly = confiner.m_BoundingShape2D as CompositeCollider2D;
  152. Vector2[] path = new Vector2[poly.pointCount];
  153. Vector2 revertCompositeColliderScale = new Vector2(1f / t.lossyScale.x, 1f / t.lossyScale.y);
  154. for (int i = 0; i < poly.pathCount; ++i)
  155. {
  156. int numPoints = poly.GetPath(i, path);
  157. for (int j = 0; j < path.Length; ++j)
  158. {
  159. path[j] *= revertCompositeColliderScale;
  160. }
  161. DrawPath(path, numPoints);
  162. }
  163. }
  164. #endif
  165. #if CINEMACHINE_PHYSICS && CINEMACHINE_PHYSICS_2D
  166. }
  167. #endif
  168. Gizmos.color = oldColor;
  169. Gizmos.matrix = oldMatrix;
  170. }
  171. }
  172. static void DrawPath(Vector2[] path, int numPoints)
  173. {
  174. if (numPoints < 0)
  175. numPoints = path.Length;
  176. if (numPoints > 0)
  177. {
  178. Vector2 v0 = path[numPoints-1];
  179. for (int j = 0; j < numPoints; ++j)
  180. {
  181. Vector2 v = path[j];
  182. Gizmos.DrawLine(v0, v);
  183. v0 = v;
  184. }
  185. }
  186. }
  187. }
  188. #endif
  189. }