public virtual void GetProperties(SerializedObject targetObject)
        {
            serializedObject = targetObject;
            //LoadDefaultVars();

            m_EnterState = serializedObject.FindProperty("m_EnterState");
            customProperties.Add(m_EnterState.name);

            m_TransitionDuration = serializedObject.FindProperty("m_TransitionDuration");
            customProperties.Add(m_TransitionDuration.name);

            m_FinishOnAnimationEnd = serializedObject.FindProperty("m_FinishOnAnimationEnd");
            customProperties.Add(m_FinishOnAnimationEnd.name);

            m_UseRootMotion = serializedObject.FindProperty("m_UseRootMotion");
            customProperties.Add(m_UseRootMotion.name);

            m_RootMotionMultiplier = serializedObject.FindProperty("m_RootMotionMultiplier");
            customProperties.Add(m_RootMotionMultiplier.name);

            m_UseRotationRootMotion = serializedObject.FindProperty("m_UseRotationRootMotion");
            customProperties.Add(m_UseRotationRootMotion.name);

            m_UseVerticalRootMotion = serializedObject.FindProperty("m_UseVerticalRootMotion");
            customProperties.Add(m_UseVerticalRootMotion.name);

            IgnoreAbilities = serializedObject.FindProperty("IgnoreAbilities");
            customProperties.Add(IgnoreAbilities.name);

            OnEnterAbilityEvent = serializedObject.FindProperty("OnEnterAbilityEvent");
            customProperties.Add(OnEnterAbilityEvent.name);

            OnExitAbilityEvent = serializedObject.FindProperty("OnExitAbilityEvent");
            customProperties.Add(OnExitAbilityEvent.name);


            allowZoomProperty = serializedObject.FindProperty("m_AllowCameraZoom");
            customProperties.Add(allowZoomProperty.name);

            abilityEnterType = serializedObject.FindProperty("m_UseInputStateToEnter");
            customProperties.Add(abilityEnterType.name);

            inputButton = serializedObject.FindProperty("InputButton");
            customProperties.Add(inputButton.name);

            enabled = serializedObject.FindProperty("m_Enabled");

            m_CharacterAbilityTarget = serializedObject.targetObject as ThirdPersonAbility;
            if (m_CharacterAbilityTarget.IgnoreAbilities == null)
            {
                m_CharacterAbilityTarget.IgnoreAbilities = new List <ThirdPersonAbility>();
            }
        }
        /// <summary>
        /// Method that enter an ability. Can be also called to force any ability to enter
        /// </summary>
        /// <param name="ability"></param>
        public void EnterAbility(ThirdPersonAbility ability, bool forceAbility = false)
        {
            ExitActiveAbility();

            m_ActiveAbility = ability;

            m_ActiveAbility.OnEnterAbility();
            m_Animator.applyRootMotion = m_ActiveAbility.UseRootMotion;

            OnAnyAbilityEnters.Invoke();
            UpdatePositionOnMovableObject(null);
            OnAbilityChanged?.Invoke(ability);
        }
        /// <summary>
        /// Force current active ability to exit
        /// </summary>
        /// <param name="ability"></param>
        public void ExitActiveAbility()
        {
            if (m_ActiveAbility != null)
            {
                LastAbility = m_ActiveAbility;
                if (m_ActiveAbility.Active)
                {
                    m_ActiveAbility.OnExitAbility();
                }

                m_ActiveAbility = null;

                m_Capsule.sharedMaterial = capsuleOriginalMaterial;
                OnAnyAbilityExits.Invoke();
            }
        }
        /// <summary>
        /// Method that exits an ability.
        /// </summary>
        /// <param name="ability"></param>
        public void ExitAbility(ThirdPersonAbility ability)
        {
            if (m_ActiveAbility == ability)
            {
                LastAbility     = m_ActiveAbility;
                m_ActiveAbility = null;

                if (ability.Active)
                {
                    ability.OnExitAbility();
                }

                m_Capsule.sharedMaterial = capsuleOriginalMaterial;
                OnAnyAbilityExits.Invoke();
            }
        }
        protected void AddIgnoreAbility(ThirdPersonAbility abilityTarget, ThirdPersonAbility abilityToAdd)
        {
            if (abilityTarget == null || abilityToAdd == null)
            {
                return;
            }

            SerializedObject   ability         = new SerializedObject(abilityTarget);
            SerializedProperty IgnoreAbilities = ability.FindProperty("IgnoreAbilities");

            int i = IgnoreAbilities.arraySize;

            IgnoreAbilities.arraySize++;
            IgnoreAbilities.GetArrayElementAtIndex(i).objectReferenceValue = abilityToAdd;

            ability.ApplyModifiedProperties();
        }
 /// <summary>
 /// Method called by any ability to try enter ability
 /// </summary>
 /// <param name="ability"></param>
 public void OnTryEnterAbility(ThirdPersonAbility ability)
 {
     if (m_ActiveAbility == null)
     {
         EnterAbility(ability);
     }
     else
     {
         // Check if new ability has priority above current ability
         foreach (ThirdPersonAbility stopAbility in ability.IgnoreAbilities)
         {
             if (stopAbility == m_ActiveAbility)
             {
                 EnterAbility(ability);
             }
         }
     }
 }
        private void RemoveAllowedAbility(object ability)
        {
            int index = -1;
            ThirdPersonAbility abilityToRemove = ability as ThirdPersonAbility;

            for (int i = 0; i < abilities.arraySize; i++)
            {
                if (abilities.GetArrayElementAtIndex(i).objectReferenceValue == abilityToRemove)
                {
                    index = i;
                    break;
                }
            }

            abilities.DeleteArrayElementAtIndex(index);
            if (abilities.GetArrayElementAtIndex(index).objectReferenceValue == null)
            {
                abilities.DeleteArrayElementAtIndex(index);
            }

            serializedObject.ApplyModifiedProperties();
        }
        protected void DrawIgnoreAbilities()
        {
            EditorGUI.indentLevel++;

            // -------------------------------------- ADD AND REMOVE ABILITIES BUTTONS -------------------------------------- //

            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.HelpBox("Add or remove abilities to be ignored when this ability request to enter. " +
                                    "All abilities that are inside ignore abilities will be stopped to allow this ability to enter. " +
                                    "If Ignore abilities were void, this ability will enter only if noone ability is active", MessageType.Info);

            EditorGUILayout.Space();

            // AddButton Style
            GUIStyle addButtonStyle = new GUIStyle(EditorStyles.miniButtonLeft);

            addButtonStyle.alignment    = TextAnchor.MiddleRight;
            addButtonStyle.fontStyle    = FontStyle.Bold;
            addButtonStyle.fontSize     = 13;
            addButtonStyle.stretchWidth = false;

            if (GUILayout.Button("+", addButtonStyle))
            {
                GenericMenu          m_Menu       = new GenericMenu();
                ThirdPersonAbility[] allAbilities = m_CharacterAbilityTarget.GetComponents <ThirdPersonAbility>();
                foreach (ThirdPersonAbility ability in allAbilities)
                {
                    if (m_CharacterAbilityTarget.IgnoreAbilities.Contains(ability) || ability == m_CharacterAbilityTarget)
                    {
                        continue;
                    }

                    m_Menu.AddItem(new GUIContent(ability.GetType().Name), false, AddIgnoredAbility, ability);
                }

                m_Menu.ShowAsContext();
            }

            // RemoveButton Style
            GUIStyle removeButtonStyle = new GUIStyle(EditorStyles.miniButtonRight);

            removeButtonStyle.alignment    = TextAnchor.MiddleCenter;
            removeButtonStyle.fontStyle    = FontStyle.Bold;
            removeButtonStyle.fontSize     = 13;
            removeButtonStyle.stretchWidth = false;

            if (GUILayout.Button("-", removeButtonStyle))
            {
                GenericMenu m_Menu = new GenericMenu();
                foreach (ThirdPersonAbility ability in m_CharacterAbilityTarget.IgnoreAbilities)
                {
                    m_Menu.AddItem(new GUIContent(ability.GetType().Name), false, RemoveIgnoredAbility, ability);
                }

                m_Menu.ShowAsContext();
            }

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space();

            // ----------------------------------------------------------------------------------------------------- //



            // Draw ignored abilities
            for (int i = 0; i < m_CharacterAbilityTarget.IgnoreAbilities.Count; i++)
            {
                ThirdPersonAbility ability = m_CharacterAbilityTarget.IgnoreAbilities[i];
                if (ability == null)
                {
                    m_CharacterAbilityTarget.IgnoreAbilities.RemoveAt(i);
                    break;
                }
                EditorGUILayout.PropertyField(IgnoreAbilities.GetArrayElementAtIndex(i), new GUIContent(ability.GetType().Name));
            }

            EditorGUI.indentLevel--;
        }