#if !UNITY_2019_3_OR_NEWER #define CINEMACHINE_PHYSICS #define CINEMACHINE_PHYSICS_2D #endif using UnityEngine; using UnityEditor; using System.Collections.Generic; using UnityEngine.Playables; namespace Cinemachine.Editor { #if CINEMACHINE_PHYSICS || CINEMACHINE_PHYSICS_2D [CustomEditor(typeof(CinemachineTriggerAction))] internal class CinemachineTriggerActionEditor : BaseEditor { const int vSpace = 2; CinemachineTriggerAction.ActionSettings def = new CinemachineTriggerAction.ActionSettings(); // to access name strings static bool mEnterExpanded; static bool mExitExpanded; SerializedProperty[] mRepeatProperties = new SerializedProperty[2]; GUIContent mRepeatLabel; GUIContent[] mRepeatSubLabels = new GUIContent[2]; GUIStyle mFoldoutStyle; private void OnEnable() { mRepeatProperties[0] = FindProperty(x => x.m_SkipFirst); mRepeatProperties[1] = FindProperty(x => x.m_Repeating); mRepeatLabel = new GUIContent( mRepeatProperties[0].displayName, mRepeatProperties[0].tooltip); mRepeatSubLabels[0] = GUIContent.none; mRepeatSubLabels[1] = new GUIContent( mRepeatProperties[1].displayName, mRepeatProperties[1].tooltip); } /// Get the property names to exclude in the inspector. /// Add the names to this list protected override void GetExcludedPropertiesInInspector(List excluded) { base.GetExcludedPropertiesInInspector(excluded); excluded.Add(FieldPath(x => x.m_SkipFirst)); excluded.Add(FieldPath(x => x.m_Repeating)); excluded.Add(FieldPath(x => x.m_OnObjectEnter)); excluded.Add(FieldPath(x => x.m_OnObjectExit)); } public override void OnInspectorGUI() { BeginInspector(); DrawRemainingPropertiesInInspector(); InspectorUtility.MultiPropertyOnLine( EditorGUILayout.GetControlRect(), mRepeatLabel, mRepeatProperties, mRepeatSubLabels); EditorGUILayout.Space(); mEnterExpanded = DrawActionSettings(FindProperty(x => x.m_OnObjectEnter), mEnterExpanded); mExitExpanded = DrawActionSettings(FindProperty(x => x.m_OnObjectExit), mExitExpanded); } bool DrawActionSettings(SerializedProperty property, bool expanded) { if (mFoldoutStyle == null) mFoldoutStyle = new GUIStyle(EditorStyles.foldout) { fontStyle = FontStyle.Bold }; Rect r = EditorGUILayout.GetControlRect(); expanded = EditorGUI.Foldout(r, expanded, property.displayName, true, mFoldoutStyle); if (expanded) { SerializedProperty actionProp = property.FindPropertyRelative(() => def.m_Action); EditorGUILayout.PropertyField(actionProp); SerializedProperty targetProp = property.FindPropertyRelative(() => def.m_Target); bool isCustom = (actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Custom); if (!isCustom) EditorGUILayout.PropertyField(targetProp); bool isBoost = actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.PriorityBoost; if (isBoost) EditorGUILayout.PropertyField(property.FindPropertyRelative(() => def.m_BoostAmount)); #if CINEMACHINE_TIMELINE bool isPlay = actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Play; if (isPlay) { SerializedProperty[] props = new SerializedProperty[2] { property.FindPropertyRelative(() => def.m_StartTime), property.FindPropertyRelative(() => def.m_Mode) }; GUIContent[] sublabels = new GUIContent[2] { GUIContent.none, new GUIContent("s", props[1].tooltip) }; InspectorUtility.MultiPropertyOnLine( EditorGUILayout.GetControlRect(), null, props, sublabels); } #endif if (actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Custom) { EditorGUILayout.HelpBox("Use the Event() list below to call custom methods", MessageType.Info); } if (isBoost) { if (GetTargetComponent(targetProp.objectReferenceValue) == null) EditorGUILayout.HelpBox("Target must be a CinemachineVirtualCameraBase in order to boost priority", MessageType.Warning); } bool isEnableDisable = (actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Enable || actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Disable); if (isEnableDisable) { var value = targetProp.objectReferenceValue; if (value != null && (value as Behaviour) == null) EditorGUILayout.HelpBox("Target must be a Behaviour in order to Enable/Disable", MessageType.Warning); } #if CINEMACHINE_TIMELINE bool isPlayStop = isPlay || actionProp.intValue == (int)CinemachineTriggerAction.ActionSettings.Mode.Stop; if (isPlayStop) { if (GetTargetComponent(targetProp.objectReferenceValue) == null && GetTargetComponent(targetProp.objectReferenceValue) == null) { EditorGUILayout.HelpBox("Target must have a PlayableDirector or Animator in order to Play/Stop", MessageType.Warning); } } #endif if (!isCustom && targetProp.objectReferenceValue == null) EditorGUILayout.HelpBox("No action will be taken because target is not valid", MessageType.Info); EditorGUILayout.Space(); EditorGUILayout.LabelField("This event will be invoked. Add calls to custom methods here:"); EditorGUILayout.PropertyField(property.FindPropertyRelative(() => def.m_Event)); } property.serializedObject.ApplyModifiedProperties(); return expanded; } T GetTargetComponent(UnityEngine.Object obj) where T : Behaviour { UnityEngine.Object currentTarget = obj; if (currentTarget != null) { GameObject targetGameObject = currentTarget as GameObject; Behaviour targetBehaviour = currentTarget as Behaviour; if (targetBehaviour != null) targetGameObject = targetBehaviour.gameObject; if (targetBehaviour is T) return targetBehaviour as T; if (targetGameObject != null) return targetGameObject.GetComponent(); } return null; } } #endif }