Пример #1
0
        protected override void DrawStateInspectorEditor(SerializedObject stateObject, AIBehaviors fsm)
        {
            SerializedProperty property;

            GUILayout.Label("Step Back Properties:", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);

            // Properties
            property = stateObject.FindProperty("distance");
            EditorGUILayout.PropertyField(property);

            property = stateObject.FindProperty("stopThreshold");
            EditorGUILayout.PropertyField(property);

            GUILayout.BeginHorizontal();
            {
                GUILayout.Label("Next State:");
                property = stateObject.FindProperty("nextState");
                property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, property.objectReferenceValue as BaseState);
            }
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();

            stateObject.ApplyModifiedProperties();

            if (Application.isPlaying)
            {
                GUILayout.Label("Debug:", EditorStyles.boldLabel);
                GUILayout.BeginVertical(GUI.skin.box);
                GUILayout.Label("Distance to target: " + (fsm.transform.position - targetPosition).magnitude.ToString(), EditorStyles.boldLabel);
                GUILayout.EndVertical();
            }
        }
Пример #2
0
        protected override void DrawStateInspectorEditor(SerializedObject stateObject, AIBehaviors fsm)
        {
            SerializedProperty property;

            GUILayout.Label("Off Mesh Link State Properties: ", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);

            //GameObject targetObject = (stateObject.targetObject as Component).gameObject;
            //AIBehaviors fsm = targetObject.transform.parent.GetComponent<AIBehaviors>();

            property = stateObject.FindProperty("jumpDelay");
            EditorGUILayout.PropertyField(property);

            property = stateObject.FindProperty("returnToPreviousState");
            EditorGUILayout.PropertyField(property);

            if (!property.boolValue)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("Transition State: ");
                property = stateObject.FindProperty("transitionState");
                property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, property.objectReferenceValue as BaseState) as BaseState;
                GUILayout.EndHorizontal();
            }

            GUILayout.EndVertical();
        }
Пример #3
0
        protected override void DrawStateInspectorEditor(SerializedObject stateObject, AIBehaviors fsm)
        {
            SerializedProperty property;

            GUILayout.Label("Invisibility Properties:", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);

            property = stateObject.FindProperty("duration");
            EditorGUILayout.PropertyField(property);

            property = stateObject.FindProperty("disableColliders");
            EditorGUILayout.PropertyField(property);

            property = stateObject.FindProperty("returnToPreviousState");
            EditorGUILayout.PropertyField(property);

            if (!property.boolValue)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("Go to state:");
                property = stateObject.FindProperty("goToState");
                property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, property.objectReferenceValue as BaseState);
                GUILayout.EndHorizontal();
            }

            GUILayout.EndVertical();

            stateObject.ApplyModifiedProperties();
        }
Пример #4
0
        public override void DrawInspectorProperties(AIBehaviors fsm, SerializedObject triggerObject)
        {
            SerializedProperty property;

            property = triggerObject.FindProperty("speedThreshold");
            EditorGUILayout.PropertyField(property);

            GUILayout.BeginHorizontal();
            {
                property = triggerObject.FindProperty("maxDistanceFromAI");
                EditorGUILayout.PropertyField(property);
            }
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            {
                property = triggerObject.FindProperty("setTransformAsSeekTarget");
                EditorGUILayout.PropertyField(property);

                if (property.boolValue)
                {
                    property = triggerObject.FindProperty("seekState");
                    property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup <SeekState>(fsm, property.objectReferenceValue as SeekState);
                }
            }
            GUILayout.EndHorizontal();
        }
Пример #5
0
        protected override void DrawStateInspectorEditor(SerializedObject stateObject, AIBehaviors stateMachine)
        {
            SerializedProperty property;

            GUILayout.Label("Seek Properties:", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);

            property = stateObject.FindProperty("specifySeekTarget");
            EditorGUILayout.PropertyField(property);

            if (property.boolValue)
            {
                property = stateObject.FindProperty("seekTarget");
                EditorGUILayout.PropertyField(property);
            }
            else
            {
                GUILayout.Label("Seek items with tag:");
                property             = stateObject.FindProperty("seekItemsWithTag");
                property.stringValue = EditorGUILayout.TagField(property.stringValue);
            }

            EditorGUILayout.Separator();
            GUILayout.BeginHorizontal();
            {
                GUILayout.Label("Seek Target Reached Transition:");
                property = stateObject.FindProperty("seekTargetReachedState");
                property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(stateMachine, property.objectReferenceValue as BaseState);
            }
            GUILayout.EndHorizontal();

            property = stateObject.FindProperty("distanceToTargetThreshold");
            float prevValue = property.floatValue;

            EditorGUILayout.PropertyField(property);

            if (property.floatValue <= 0.0f)
            {
                property.floatValue = prevValue;
            }

            property = stateObject.FindProperty("destroyTargetWhenReached");
            EditorGUILayout.PropertyField(property);

            EditorGUILayout.Separator();
            GUILayout.BeginHorizontal();
            {
                GUILayout.Label("No Seek Target Transition:");
                property = stateObject.FindProperty("noSeekTargetFoundState");
                property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(stateMachine, property.objectReferenceValue as BaseState);
            }
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();

            stateObject.ApplyModifiedProperties();
        }
Пример #6
0
        public void DrawTransitionState(AIBehaviors fsm)
        {
            SerializedObject   sObject = new SerializedObject(this);
            SerializedProperty property;

            GUILayout.BeginHorizontal();
            GUILayout.Label("Change to State:");
            property = sObject.FindProperty("transitionState");
            property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, property.objectReferenceValue as BaseState);
            GUILayout.EndHorizontal();

            sObject.ApplyModifiedProperties();
        }
Пример #7
0
        protected override void DrawStateInspectorEditor(SerializedObject stateObject, AIBehaviors fsm)
        {
            SerializedProperty property;

            GUILayout.Label("Help Properties:", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);

            property = stateObject.FindProperty("helpCondition");
            EditorGUILayout.PropertyField(property);
            if (helpCondition == HelpCondition.WhenInSpecificStates)
            {
                property = stateObject.FindProperty("helpStates");

                int arraySize = property.arraySize;
                arraySize          = EditorGUILayout.IntField("Number Of States", arraySize);
                property.arraySize = arraySize;

                SerializedProperty stateProperty;
                for (int i = 0; i < arraySize; i++)
                {
                    stateProperty = property.GetArrayElementAtIndex(i);
                    stateProperty.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, stateProperty.objectReferenceValue as BaseState);
                }
                //InspectorHelper.DrawArray (stateObject, "helpStates");
            }

            property = stateObject.FindProperty("withinHelpPointDistance");
            EditorGUILayout.PropertyField(property);

            EditorGUILayout.Separator();

            GUILayout.BeginHorizontal();
            GUILayout.Label("State When Help Point Reached");
            property = stateObject.FindProperty("helpPointReachedState");
            property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, property.objectReferenceValue as BaseState);
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();

            stateObject.ApplyModifiedProperties();

            if (Application.isPlaying)
            {
                GUILayout.Label("Debug:", EditorStyles.boldLabel);
                GUILayout.BeginVertical(GUI.skin.box);
                GUILayout.Label("Distance to target: " + (transform.position - helpPoint).magnitude.ToString(), EditorStyles.boldLabel);
                GUILayout.EndVertical();
            }
        }
Пример #8
0
        void DrawCooldownProperties(SerializedObject m_State, AIBehaviors fsm)
        {
            SerializedProperty m_Property;

            GUILayout.Label("Cooldown Properties:", EditorStyles.boldLabel);

            m_Property = m_State.FindProperty("cooldownTime");
            EditorGUILayout.PropertyField(m_Property);

            m_Property = m_State.FindProperty("initResetsCooldown");
            EditorGUILayout.PropertyField(m_Property, new GUIContent("Reset on State Change"));

            if (!m_Property.boolValue)
            {
                m_Property = m_State.FindProperty("switchStateIfStillCoolingDown");
                EditorGUILayout.PropertyField(m_Property);

                if (m_Property.boolValue)
                {
                    GUILayout.BeginHorizontal();
                    {
                        GUILayout.Label("Still Cooling Down Transition:");

                        m_Property = m_State.FindProperty("stillCoolingDownState");
                        m_Property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, m_Property.objectReferenceValue as BaseState);
                    }
                    GUILayout.EndHorizontal();
                }
            }

            m_Property = m_State.FindProperty("hasCooldownLimit");
            EditorGUILayout.PropertyField(m_Property);

            if (m_Property.boolValue)
            {
                m_Property = m_State.FindProperty("cooldownLimit");
                EditorGUILayout.PropertyField(m_Property);

                GUILayout.BeginHorizontal();
                {
                    GUILayout.Label("Limit Exceeded Transition:");

                    m_Property = m_State.FindProperty("cooldownLimitExceededState");
                    m_Property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, m_Property.objectReferenceValue as BaseState);
                }
                GUILayout.EndHorizontal();
            }
        }
Пример #9
0
        public void DrawTransitionStatePopup(string label, AIBehaviors fsm, SerializedObject m_Object, string propertyName)
        {
            SerializedProperty m_InitialState = m_Object.FindProperty(propertyName);
            BaseState          state          = m_InitialState.objectReferenceValue as BaseState;
            BaseState          updatedState;

            EditorGUILayout.Separator();

            GUILayout.Label(label, EditorStyles.boldLabel);
            updatedState = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, state);
            if (updatedState != state)
            {
                m_InitialState.objectReferenceValue = updatedState;
                m_Object.ApplyModifiedProperties();
            }
        }
Пример #10
0
        public override void DrawInspectorProperties(AIBehaviors fsm, SerializedObject sObject)
        {
            SerializedProperty statesArray  = sObject.FindProperty("states");
            SerializedProperty weightsArray = sObject.FindProperty("weights");
            int    arraySize      = statesArray.arraySize;
            float  total          = 0.0f;
            string transitionName = transitionState != null ? transitionState.name : "";

            arraySize              = EditorGUILayout.IntField("Number of possible states", arraySize);
            statesArray.arraySize  = arraySize;
            weightsArray.arraySize = arraySize;

            for (int i = 0; i < arraySize; i++)
            {
                EditorGUILayout.BeginHorizontal();
                {
                    SerializedProperty stateProperty   = statesArray.GetArrayElementAtIndex(i);
                    SerializedProperty weightsProperty = weightsArray.GetArrayElementAtIndex(i);

                    total += weightsProperty.floatValue;
                    stateProperty.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, stateProperty.objectReferenceValue as BaseState);

                    EditorGUILayout.Slider(weightsProperty, 0.0f, 1.0f, GUIContent.none);
                }
                EditorGUILayout.EndHorizontal();
            }

            if (total > 1.0f)
            {
                Color oldColor = GUI.color;
                GUI.color = Color.red;
                GUILayout.Label("All possibilities combined must be less than 1");
                GUI.color = oldColor;
            }

            GUILayout.Label("If the total of the numbers above are less than 1,");
            GUILayout.Label("the remaining possiblity will go to the");
            GUILayout.Label("'Change to State' below which is: " + transitionName);

            sObject.ApplyModifiedProperties();
        }
Пример #11
0
        protected override void DrawStateInspectorEditor(SerializedObject m_Object, AIBehaviors stateMachine)
        {
            SerializedObject   m_State = new SerializedObject(this);
            SerializedProperty m_Prop;

            GUILayout.Label("Help Properties:", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);

            m_Prop = m_State.FindProperty("withinHelpPointDistance");
            EditorGUILayout.PropertyField(m_Prop);

            EditorGUILayout.Separator();

            GUILayout.Label("State when help point reached");
            m_Prop = m_State.FindProperty("helpPointReachedState");
            m_Prop.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(stateMachine, m_Prop.objectReferenceValue as BaseState);

            GUILayout.EndVertical();

            m_State.ApplyModifiedProperties();
        }
Пример #12
0
        protected override void DrawStateInspectorEditor(SerializedObject stateObject, AIBehaviors fsm)
        {
            SerializedProperty property;

            GUILayout.Label("Get Help Properties:", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);

            GUILayout.BeginHorizontal();
            GUILayout.Label("Get Help From Objects With Tag");
            string newTag = EditorGUILayout.TagField(helpTag);

            if (newTag != helpTag)
            {
                property             = stateObject.FindProperty("helpTag");
                property.stringValue = newTag;
            }
            GUILayout.EndHorizontal();

            EditorGUILayout.Separator();

            property = stateObject.FindProperty("helpRadius");
            EditorGUILayout.PropertyField(property);

            property = stateObject.FindProperty("stateDuration");
            EditorGUILayout.PropertyField(property);

            GUILayout.BeginHorizontal();
            GUILayout.Label("Change To State:");
            property = stateObject.FindProperty("changeToState");
            property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, property.objectReferenceValue as BaseState);
            GUILayout.EndHorizontal();

            GUILayout.EndVertical();

            stateObject.ApplyModifiedProperties();
        }
Пример #13
0
        public override void DrawInspectorProperties(AIBehaviors fsm, SerializedObject triggerObject)
        {
            SerializedProperty property;

            GUILayout.Label("Properties: ", EditorStyles.boldLabel);
            GUILayout.BeginVertical(GUI.skin.box);

            property = triggerObject.FindProperty("audioCachePoint");
            EditorGUILayout.PropertyField(property);

            property = triggerObject.FindProperty("volumeTriggerLevel");
            EditorGUILayout.PropertyField(property);

            property = triggerObject.FindProperty("setAudioTransformAsSeekTarget");
            EditorGUILayout.PropertyField(property);

            if (property.boolValue)
            {
                property = triggerObject.FindProperty("seekState");
                property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup <SeekState>(fsm, property.objectReferenceValue as SeekState);
            }

            GUILayout.EndVertical();
        }
Пример #14
0
        protected override void DrawStateInspectorEditor(SerializedObject stateObject, AIBehaviors fsm)
        {
            SerializedProperty property;

            GUILayout.Label("Seek Properties:", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);

            property = stateObject.FindProperty("specifySeekTarget");
            EditorGUILayout.PropertyField(property);

            if (property.boolValue)
            {
                property = stateObject.FindProperty("seekTarget");
                EditorGUILayout.PropertyField(property);
            }

            EditorGUILayout.Separator();
            GUILayout.BeginHorizontal();
            {
                GUILayout.Label("No Seek Target Transition:");
                property = stateObject.FindProperty("noSeekTargetFoundState");
                property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, property.objectReferenceValue as BaseState);
            }
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            {
                GUILayout.Label("No Movement Transition:");
                property = stateObject.FindProperty("noMovementState");
                property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, property.objectReferenceValue as BaseState);
            }
            GUILayout.EndHorizontal();

            EditorGUILayout.Separator();
            GUILayout.BeginHorizontal();
            {
                GUILayout.Label("Seek Target Reached Transition:");
                property = stateObject.FindProperty("seekTargetReachedState");
                property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, property.objectReferenceValue as BaseState);
            }
            GUILayout.EndHorizontal();

            property = stateObject.FindProperty("distanceToTargetThreshold");
            float prevValue = property.floatValue;

            EditorGUILayout.PropertyField(property);

            if (property.floatValue <= 0.0f)
            {
                property.floatValue = prevValue;
            }

            property = stateObject.FindProperty("destroyTargetWhenReached");
            EditorGUILayout.PropertyField(property);

            property = stateObject.FindProperty("getAsCloseAsPossible");
            EditorGUILayout.PropertyField(property);

            if (property.boolValue)
            {
                if (fsm.GetComponentInChildren <NavMeshAgent>() == null)
                {
                    EditorGUILayout.HelpBox("This trigger only works with an AI that uses a NavMeshAgent", MessageType.Warning);
                }
            }

            GUILayout.EndVertical();

            stateObject.ApplyModifiedProperties();

            if (Application.isPlaying)
            {
                GUILayout.Label("Debug:", EditorStyles.boldLabel);

                GUILayout.BeginVertical(GUI.skin.box);
                if (seekTarget != null)
                {
                    GUILayout.Label("Distance to target: " + (transform.position - targetPosition).magnitude.ToString(), EditorStyles.boldLabel);
                }
                else
                {
                    GUILayout.Label("No Seek Target Found", EditorStyles.boldLabel);
                }
                GUILayout.EndVertical();
            }
        }
Пример #15
0
        protected override void DrawStateInspectorEditor(SerializedObject m_Object, AIBehaviors stateMachine)
        {
            SerializedObject   m_State = new SerializedObject(this);
            SerializedProperty m_property;
            GUIContent         distanceToTargetThresholdContent = new GUIContent("Distance to target threshold", "This distance should be greater than the stopping distance of the Nav Mesh Agent. Default=1");

            m_State.Update();

            GUILayout.Label("Flee Properties:", EditorStyles.boldLabel);
            GUILayout.BeginVertical(GUI.skin.box);

            m_property = m_State.FindProperty("fleeMode");
            EditorGUILayout.PropertyField(m_property);

            FleeMode fleeMode = (FleeMode)m_property.enumValueIndex;

            switch (fleeMode)
            {
            case FleeMode.NearestTaggedObject:
                GUILayout.BeginHorizontal();
                {
                    GUILayout.Label("Use nearest object with tag:");
                    m_property             = m_State.FindProperty("fleeTargetTag");
                    m_property.stringValue = EditorGUILayout.TagField(m_property.stringValue);
                }
                GUILayout.EndHorizontal();
                m_property = m_State.FindProperty("distanceToTargetThreshold");
                EditorGUILayout.PropertyField(m_property, distanceToTargetThresholdContent);

                break;

            case FleeMode.FixedTarget:
                m_property = m_State.FindProperty("fleeToTarget");
                EditorGUILayout.PropertyField(m_property);
                m_property = m_State.FindProperty("distanceToTargetThreshold");
                EditorGUILayout.PropertyField(m_property, distanceToTargetThresholdContent);

                break;

            case FleeMode.Direction:
                m_property = m_State.FindProperty("fleeDirection");
                EditorGUILayout.PropertyField(m_property);
                m_property = m_State.FindProperty("stopFleeDistance");
                EditorGUILayout.PropertyField(m_property);

                break;

            case FleeMode.AwayFromNearestTaggedObject:
                m_property = m_State.FindProperty("stopFleeDistance");
                EditorGUILayout.PropertyField(m_property);

                break;
            }

            EditorGUILayout.Separator();
            GUILayout.BeginHorizontal();
            {
                GUILayout.Label("Flight Ended Transition:");
                m_property = m_State.FindProperty("flightEndedState");
                m_property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(stateMachine, m_property.objectReferenceValue as BaseState);
            }
            GUILayout.EndHorizontal();

            // "distanceToTargetThreshold" and "stopFleeDistance" can't be less than 0
            m_property = m_State.FindProperty("distanceToTargetThreshold");
            if (m_property.floatValue < 0.0f)
            {
                m_property.floatValue = 0.0f;
            }
            m_property = m_State.FindProperty("stopFleeDistance");
            if (m_property.floatValue < 0.0f)
            {
                m_property.floatValue = 0.0f;
            }

            GUILayout.EndVertical();

            m_State.ApplyModifiedProperties();
        }
Пример #16
0
        protected override void DrawStateInspectorEditor(SerializedObject m_Object, AIBehaviors stateMachine)
        {
            SerializedObject   m_State = new SerializedObject(this);
            SerializedProperty m_property;

            m_State.Update();

            // === Handle other properties === //

            EditorGUILayout.Separator();

            GUILayout.Label("Patrol Properties:", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);
            GUILayout.Label("Movement Options:", EditorStyles.boldLabel);

            PatrolMode patrolMode;

            m_property = m_State.FindProperty("patrolMode");
            EditorGUILayout.PropertyField(m_property);
            patrolMode = (PatrolMode)m_property.enumValueIndex;

            m_property = m_State.FindProperty("continuePatrolMode");
            EditorGUILayout.PropertyField(m_property, new GUIContent("Continue Previous Patrol", "When this state is switched back to, will it continue where it left off?"));

            if (patrolMode == PatrolState.PatrolMode.Once)
            {
                GUILayout.BeginHorizontal();
                {
                    GUILayout.Label("End Patrol Transition:");
                    m_property = m_State.FindProperty("patrolEndedState");
                    m_property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(stateMachine, m_property.objectReferenceValue as BaseState);
                }
                GUILayout.EndHorizontal();
            }

            // Handle the patrol points

            if (patrolPoints == null)
            {
                patrolPoints = new Transform[0];
            }

            EditorGUILayout.Separator();

            m_property = m_State.FindProperty("patrolPointsGroup");
            EditorGUILayout.PropertyField(m_property);

            m_property = m_State.FindProperty("pointDistanceThreshold");
            EditorGUILayout.PropertyField(m_property, new GUIContent("Distance Threshold"));

            if (m_property.floatValue < 0.0f)
            {
                m_property.floatValue = 0.0f;
            }

            m_property = m_State.FindProperty("useAccurateCornering");
            EditorGUILayout.PropertyField(m_property, new GUIContent("Accurate Cornering"));

            if (m_property.boolValue)
            {
                m_property = m_State.FindProperty("corneringError");
                EditorGUILayout.PropertyField(m_property, new GUIContent("Cornering Error"));

                if (m_property.intValue <= 0)
                {
                    m_property.intValue = 1;
                }
            }

            GUILayout.EndVertical();

            m_State.ApplyModifiedProperties();
        }
Пример #17
0
        protected override void DrawStateInspectorEditor(SerializedObject m_State, AIBehaviors fsm)
        {
            SerializedProperty m_property;

            string[] animNames          = AIBehaviorsAnimationEditorGUI.GetAnimationStateNames(m_State);
            int      curAttackAnimIndex = 0;

            for (int i = 0; i < animNames.Length; i++)
            {
                if (animNames[i] == animationStates[0].name)
                {
                    curAttackAnimIndex = i;
                }
            }

            GUILayout.Label("Attack Properties:", EditorStyles.boldLabel);

            GUILayout.BeginVertical(GUI.skin.box);

            m_property = m_State.FindProperty("attackDamage");
            EditorGUILayout.PropertyField(m_property);

            EditorGUILayout.Separator();

            // Movement Settings

            GUILayout.Label("Movement Settings:", EditorStyles.boldLabel);

            m_property = m_State.FindProperty("inheritPreviousStateMovement");
            EditorGUILayout.PropertyField(m_property);

            EditorGUILayout.Separator();

            // Animation Settings

            GUILayout.Label("Animation Settings:", EditorStyles.boldLabel);

            m_property = m_State.FindProperty("attackPoint");
            EditorGUILayout.Slider(m_property, 0.0f, 1.0f);

            if (!Application.isPlaying)
            {
                if (curAttackAnimIndex != -1 && curAttackAnimIndex < animNames.Length)
                {
                    float calcAttackTime = SampleAttackAnimation(fsm, animNames[curAttackAnimIndex], m_property.floatValue);

                    m_property            = m_State.FindProperty("animAttackTime");
                    m_property.floatValue = calcAttackTime;
                }
            }

            EditorGUILayout.Separator();

            // === Reload Properties === //

            GUILayout.Label("Reload Settings:", EditorStyles.boldLabel);

            m_property = m_State.FindProperty("attacksBeforeReload");
            EditorGUILayout.PropertyField(m_property, new GUIContent("Attacks Before Reload"));

            m_property = m_State.FindProperty("attackCount");
            EditorGUILayout.PropertyField(m_property, new GUIContent("Attack count (of " + attacksBeforeReload + ")"));

            GUILayout.BeginHorizontal();
            {
                GUILayout.Label("Reload State:");
                m_property = m_State.FindProperty("reloadState");
                m_property.objectReferenceValue = AIBehaviorsStatePopups.DrawEnabledStatePopup(fsm, m_property.objectReferenceValue as BaseState);

                if (reloadState == null)
                {
                    m_property.objectReferenceValue = this;
                }
            }
            GUILayout.EndHorizontal();

            EditorGUILayout.Separator();

            // === Attack Method === //

            GUILayout.Label("Attack Method:", EditorStyles.boldLabel);

            Component[] components = GetAttackMethodComponents(fsm.gameObject);
            int         selectedComponent = -1, newSelectedComponent = 0;

            if (components.Length > 0)
            {
                string[] componentNames = GetAttackMethodComponentNames(components);

                for (int i = 0; i < components.Length; i++)
                {
                    if (components[i] == scriptWithAttackMethod)
                    {
                        selectedComponent = i;
                        break;
                    }
                }

                newSelectedComponent = EditorGUILayout.Popup(selectedComponent, componentNames);

                if (selectedComponent != newSelectedComponent)
                {
                    m_property = m_State.FindProperty("scriptWithAttackMethod");
                    m_property.objectReferenceValue = components[newSelectedComponent];
                }
            }
            else
            {
                AIBehaviorsCodeSampleGUI.Draw(typeof(AttackData), "attackData", "OnAttack");
            }

            if (components.Length > 0)
            {
                string[] methodNames = GetAttackMethodNamesForComponent(components[selectedComponent < 0 ? 0 : selectedComponent]);
                int      curSelectedMethod = -1, newSelectedMethod = 0;

                for (int i = 0; i < methodNames.Length; i++)
                {
                    if (methodNames[i] == methodName)
                    {
                        curSelectedMethod = i;
                        break;
                    }
                }

                newSelectedMethod = EditorGUILayout.Popup(curSelectedMethod, methodNames);

                if (curSelectedMethod != newSelectedMethod)
                {
                    m_property             = m_State.FindProperty("methodName");
                    m_property.stringValue = methodNames[newSelectedMethod];
                }
            }

            GUILayout.EndVertical();

            m_State.ApplyModifiedProperties();
        }