CinemachineTriggerActionEditor.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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.Collections.Generic;
  8. using UnityEngine.Playables;
  9. namespace Cinemachine.Editor
  10. {
  11. #if CINEMACHINE_PHYSICS || CINEMACHINE_PHYSICS_2D
  12. [CustomEditor(typeof(CinemachineTriggerAction))]
  13. internal class CinemachineTriggerActionEditor : BaseEditor<CinemachineTriggerAction>
  14. {
  15. const int vSpace = 2;
  16. CinemachineTriggerAction.ActionSettings def
  17. = new CinemachineTriggerAction.ActionSettings(); // to access name strings
  18. static bool mEnterExpanded;
  19. static bool mExitExpanded;
  20. SerializedProperty[] mRepeatProperties = new SerializedProperty[2];
  21. GUIContent mRepeatLabel;
  22. GUIContent[] mRepeatSubLabels = new GUIContent[2];
  23. GUIStyle mFoldoutStyle;
  24. private void OnEnable()
  25. {
  26. mRepeatProperties[0] = FindProperty(x => x.m_SkipFirst);
  27. mRepeatProperties[1] = FindProperty(x => x.m_Repeating);
  28. mRepeatLabel = new GUIContent(
  29. mRepeatProperties[0].displayName, mRepeatProperties[0].tooltip);
  30. mRepeatSubLabels[0] = GUIContent.none;
  31. mRepeatSubLabels[1] = new GUIContent(
  32. mRepeatProperties[1].displayName, mRepeatProperties[1].tooltip);
  33. }
  34. /// <summary>Get the property names to exclude in the inspector.</summary>
  35. /// <param name="excluded">Add the names to this list</param>
  36. protected override void GetExcludedPropertiesInInspector(List<string> excluded)
  37. {
  38. base.GetExcludedPropertiesInInspector(excluded);
  39. excluded.Add(FieldPath(x => x.m_SkipFirst));
  40. excluded.Add(FieldPath(x => x.m_Repeating));
  41. excluded.Add(FieldPath(x => x.m_OnObjectEnter));
  42. excluded.Add(FieldPath(x => x.m_OnObjectExit));
  43. }
  44. public override void OnInspectorGUI()
  45. {
  46. BeginInspector();
  47. DrawRemainingPropertiesInInspector();
  48. InspectorUtility.MultiPropertyOnLine(
  49. EditorGUILayout.GetControlRect(), mRepeatLabel,
  50. mRepeatProperties, mRepeatSubLabels);
  51. EditorGUILayout.Space();
  52. mEnterExpanded = DrawActionSettings(FindProperty(x => x.m_OnObjectEnter), mEnterExpanded);
  53. mExitExpanded = DrawActionSettings(FindProperty(x => x.m_OnObjectExit), mExitExpanded);
  54. }
  55. bool DrawActionSettings(SerializedProperty property, bool expanded)
  56. {
  57. if (mFoldoutStyle == null)
  58. mFoldoutStyle = new GUIStyle(EditorStyles.foldout) { fontStyle = FontStyle.Bold };
  59. Rect r = EditorGUILayout.GetControlRect();
  60. expanded = EditorGUI.Foldout(r, expanded, property.displayName, true, mFoldoutStyle);
  61. if (expanded)
  62. {
  63. SerializedProperty actionProp = property.FindPropertyRelative(() => def.m_Action);
  64. EditorGUILayout.PropertyField(actionProp);
  65. SerializedProperty targetProp = property.FindPropertyRelative(() => def.m_Target);
  66. bool isCustom = (actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Custom);
  67. if (!isCustom)
  68. EditorGUILayout.PropertyField(targetProp);
  69. bool isBoost = actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.PriorityBoost;
  70. if (isBoost)
  71. EditorGUILayout.PropertyField(property.FindPropertyRelative(() => def.m_BoostAmount));
  72. #if CINEMACHINE_TIMELINE
  73. bool isPlay = actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Play;
  74. if (isPlay)
  75. {
  76. SerializedProperty[] props = new SerializedProperty[2]
  77. {
  78. property.FindPropertyRelative(() => def.m_StartTime),
  79. property.FindPropertyRelative(() => def.m_Mode)
  80. };
  81. GUIContent[] sublabels = new GUIContent[2]
  82. {
  83. GUIContent.none, new GUIContent("s", props[1].tooltip)
  84. };
  85. InspectorUtility.MultiPropertyOnLine(
  86. EditorGUILayout.GetControlRect(), null, props, sublabels);
  87. }
  88. #endif
  89. if (actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Custom)
  90. {
  91. EditorGUILayout.HelpBox("Use the Event() list below to call custom methods", MessageType.Info);
  92. }
  93. if (isBoost)
  94. {
  95. if (GetTargetComponent<CinemachineVirtualCameraBase>(targetProp.objectReferenceValue) == null)
  96. EditorGUILayout.HelpBox("Target must be a CinemachineVirtualCameraBase in order to boost priority", MessageType.Warning);
  97. }
  98. bool isEnableDisable = (actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Enable
  99. || actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Disable);
  100. if (isEnableDisable)
  101. {
  102. var value = targetProp.objectReferenceValue;
  103. if (value != null && (value as Behaviour) == null)
  104. EditorGUILayout.HelpBox("Target must be a Behaviour in order to Enable/Disable", MessageType.Warning);
  105. }
  106. #if CINEMACHINE_TIMELINE
  107. bool isPlayStop = isPlay
  108. || actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Stop;
  109. if (isPlayStop)
  110. {
  111. if (GetTargetComponent<Animator>(targetProp.objectReferenceValue) == null
  112. && GetTargetComponent<PlayableDirector>(targetProp.objectReferenceValue) == null)
  113. {
  114. EditorGUILayout.HelpBox("Target must have a PlayableDirector or Animator in order to Play/Stop", MessageType.Warning);
  115. }
  116. }
  117. #endif
  118. if (!isCustom && targetProp.objectReferenceValue == null)
  119. EditorGUILayout.HelpBox("No action will be taken because target is not valid", MessageType.Info);
  120. EditorGUILayout.Space();
  121. EditorGUILayout.LabelField("This event will be invoked. Add calls to custom methods here:");
  122. EditorGUILayout.PropertyField(property.FindPropertyRelative(() => def.m_Event));
  123. }
  124. property.serializedObject.ApplyModifiedProperties();
  125. return expanded;
  126. }
  127. T GetTargetComponent<T>(UnityEngine.Object obj) where T : Behaviour
  128. {
  129. UnityEngine.Object currentTarget = obj;
  130. if (currentTarget != null)
  131. {
  132. GameObject targetGameObject = currentTarget as GameObject;
  133. Behaviour targetBehaviour = currentTarget as Behaviour;
  134. if (targetBehaviour != null)
  135. targetGameObject = targetBehaviour.gameObject;
  136. if (targetBehaviour is T)
  137. return targetBehaviour as T;
  138. if (targetGameObject != null)
  139. return targetGameObject.GetComponent<T>();
  140. }
  141. return null;
  142. }
  143. }
  144. #endif
  145. }