Example #1
0
    public void Persuade(GameObject pAttacker)
    {
        m_iPersuasion++;

        if (m_iPersuasion >= m_iPersuasionStrenght)
        {
            m_eBehaviour = Behaviour.Ally;
            m_eWanderingBehaviour = WanderType.Area;

            if (transform.parent.tag == "Target")
            {
                Destroy(m_pTargetProjectorHostile);

                string pProjectorName = m_pTargetProjectorFriendly.name;
                m_pTargetProjectorFriendly = Instantiate(m_pTargetProjectorFriendly, transform.parent.position, m_pTargetProjectorFriendly.transform.rotation) as GameObject;
                m_pTargetProjectorFriendly.name = pProjectorName;
                m_pTargetProjectorFriendly.transform.parent = transform.parent;
            }
        }

        OnAttacked(pAttacker);
    }
Example #2
0
    public void Persuade(GameObject pAttacker)
    {
        m_iPersuasion++;

        if (m_iPersuasion >= m_iPersuasionStrenght)
        {
            m_eBehaviour          = Behaviour.Ally;
            m_eWanderingBehaviour = WanderType.Area;

            if (transform.parent.tag == "Target")
            {
                Destroy(m_pTargetProjectorHostile);

                string pProjectorName = m_pTargetProjectorFriendly.name;
                m_pTargetProjectorFriendly                  = Instantiate(m_pTargetProjectorFriendly, transform.parent.position, m_pTargetProjectorFriendly.transform.rotation) as GameObject;
                m_pTargetProjectorFriendly.name             = pProjectorName;
                m_pTargetProjectorFriendly.transform.parent = transform.parent;
            }
        }

        OnAttacked(pAttacker);
    }
Example #3
0
        public void Wander()
        {
            if (wanderType == WanderType.Random)
            {
                // Random wandering
                if (Vector3.Distance(transform.position, wanderPoint) < 1f)
                {
                    // If the enemy got to its wander point then we have to calculate
                    // another wander point so the enemy keeps going from one wander
                    // point to another and so on.
                    wanderPoint = RandomWanderPoint();
                }
                else
                {
                    agent.SetDestination(wanderPoint);
                }
            }
            else
            {
                // Waypoint wandering
                if (waypoints.Length >= 2)
                {
                    // There should be more than 1 waypoint
                    if (Vector3.Distance(waypoints[waypointIndex].position, transform.position) < 1f)
                    {
                        if (waypointIndex == waypoints.Length - 1)
                        {
                            // If the enemy reach the last waypoint, start again
                            waypointIndex = 0;
                        }
                        else
                        {
                            waypointIndex++;
                        }
                    }
                    else
                    {
                        agent.SetDestination(waypoints[waypointIndex].position);
                    }
                }
                else
                {
                    if (!warningThrown)
                    {
                        // Throw the warning just once
                        warningThrown = true;
                        Debug.LogWarning("Wandering mode set to 'Waypoint', please assign more than 1 waypoint to the AI: " + gameObject.name + ". You can also change the wandering mode to 'Random'.");

                        // But if we want the enemy to stay still in the same place we can set only 1 waypoint
                        if (waypoints.Length == 1)
                        {
                            Debug.LogWarning("Just 1 waypoint assigned to '" + gameObject.name + "'. It will stay still in the same place when reaching that waypoint.");
                            agent.SetDestination(waypoints[0].position);
                        }
                        else
                        {
                            // Set enemy AI to random wandering mode
                            wanderType = WanderType.Random;
                            Debug.LogWarning("There is no waypoints assigned to '" + gameObject.name + "'. Setting wandering type to 'Random'.");
                        }
                    }
                }
            }
        }
Example #4
0
    void OnGUI()
    {
        GUILayout.Space(15);

        EditorGUILayout.BeginHorizontal();
        GUILayout.FlexibleSpace();
        EditorGUILayout.BeginVertical("Box", GUILayout.Width(90 * Screen.width / 100));
        var style = new GUIStyle(EditorStyles.boldLabel)
        {
            alignment = TextAnchor.MiddleCenter
        };

        EditorGUILayout.LabelField(new GUIContent(SettingsIcon), style, GUILayout.ExpandWidth(true), GUILayout.Height(32));
        EditorGUILayout.LabelField("Emerald AI Setup Manager - v1.0", style, GUILayout.ExpandWidth(true));
        EditorGUILayout.HelpBox("With the Emerald AI Setup Manager, you can apply an Emerald AI component to an object. Be aware that closing the Emerald Setup Manager will lose all references you've entered below. Make sure you select 'Setup AI' before closing, if you'd like your changes to be applied.", MessageType.None, true);
        GUILayout.Space(4);
        EditorGUILayout.EndVertical();
        GUILayout.FlexibleSpace();
        EditorGUILayout.EndHorizontal();

        GUILayout.Space(15);

        EditorGUILayout.BeginVertical();

        GUILayout.BeginHorizontal();
        GUILayout.Space(25);
        scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

        EditorGUILayout.BeginVertical("Box");

        GUI.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.25f);
        EditorGUILayout.BeginVertical("Box");
        EditorGUILayout.LabelField("Setup Settings", EditorStyles.boldLabel);
        GUI.backgroundColor = Color.white;
        EditorGUILayout.EndVertical();
        GUI.backgroundColor = Color.white;

        GUILayout.Space(15);

        GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
        EditorGUILayout.HelpBox("The object that the Emerald AI system will be added to.", MessageType.None, true);
        GUI.backgroundColor = Color.white;
        if (ObjectToSetup == null)
        {
            GUI.backgroundColor = new Color(10f, 0.0f, 0.0f, 0.25f);
            EditorGUILayout.LabelField("This field cannot be left blank.", EditorStyles.helpBox);
            GUI.backgroundColor = Color.white;
        }
        ObjectToSetup = (GameObject)EditorGUILayout.ObjectField("AI Object", ObjectToSetup, typeof(GameObject), true);
        GUILayout.Space(10);

        GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
        EditorGUILayout.HelpBox("Please select your AI's Behavior.", MessageType.None, true);
        GUI.backgroundColor = Color.white;
        AIBehaviorRef       = (AIBehavior)EditorGUILayout.EnumPopup("AI's Behavior", AIBehaviorRef);
        GUILayout.Space(10);

        GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
        EditorGUILayout.HelpBox("Please select your AI's Confidence.", MessageType.None, true);
        GUI.backgroundColor = Color.white;
        ConfidenceRef       = (ConfidenceType)EditorGUILayout.EnumPopup("AI's Confidence", ConfidenceRef);
        GUILayout.Space(10);

        GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
        EditorGUILayout.HelpBox("Please select your AI's Wander Type.", MessageType.None, true);
        GUI.backgroundColor = Color.white;
        WanderTypeRef       = (WanderType)EditorGUILayout.EnumPopup("AI's Wander Type", WanderTypeRef);
        GUILayout.Space(10);

        GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
        EditorGUILayout.HelpBox("Would you like the Setup Manager to automatically setup Emerald's optimization settings? This allows Emerald to be deactivated when an AI is culled or not visible which will help improve performance.", MessageType.None, true);
        GUI.backgroundColor          = Color.white;
        SetupOptimizationSettingsRef = (SetupOptimizationSettings)EditorGUILayout.EnumPopup("Auto Optimize", SetupOptimizationSettingsRef);
        GUILayout.Space(10);

        GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
        EditorGUILayout.HelpBox("Would you like to setup your animations now or later?", MessageType.None, true);
        GUI.backgroundColor = Color.white;
        SetupAnimationsRef  = (SetupAnimations)EditorGUILayout.EnumPopup("Setup Animations", SetupAnimationsRef);
        if (SetupAnimationsRef == SetupAnimations.Later)
        {
            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("You can setup your animations later via the Emerald Editor.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
        }
        GUILayout.Space(10);

        if (SetupAnimationsRef == SetupAnimations.Now && ObjectToSetup == null)
        {
            GUI.backgroundColor = new Color(10f, 0.0f, 0.0f, 0.25f);
            EditorGUILayout.LabelField("You must have an object applied to the AI Object slot before you can create an Animator Controller for it.", EditorStyles.helpBox);
            GUI.backgroundColor = Color.white;
        }

        if (SetupAnimationsRef == SetupAnimations.Now && ObjectToSetup != null)
        {
            if (ObjectToSetup.GetComponent <Animator>() != null)
            {
                AIAnimator = ObjectToSetup.GetComponent <Animator>();
            }
            else if (ObjectToSetup.GetComponent <Animator>() == null)
            {
                GUI.backgroundColor = new Color(10f, 0.0f, 0.0f, 0.25f);
                EditorGUILayout.LabelField("You must have an Animator Component on your AI Object in order to create an Animator Controller.", EditorStyles.helpBox);
                GUI.backgroundColor = Color.white;
            }
        }

        EditorGUI.BeginDisabledGroup(SetupAnimationsRef == SetupAnimations.Now && ObjectToSetup == null || SetupAnimationsRef == SetupAnimations.Now && ObjectToSetup != null && ObjectToSetup.GetComponent <Animator>() == null);
        if (SetupAnimationsRef == SetupAnimations.Now && overrideController == null)
        {
            if (GUILayout.Button("Create Animator Controller"))
            {
                FilePath = EditorUtility.SaveFilePanelInProject("Save as OverrideController", "New OverrideController", "overrideController", "Please enter a file name to save the file to");
                if (FilePath != string.Empty)
                {
                    _T = ObjectToSetup.transform.position;

                    AssetDatabase.CopyAsset("Assets/Emerald AI 2.0/Animator/Emerald Override.overrideController", FilePath);
                    overrideController = AssetDatabase.LoadAssetAtPath(FilePath, typeof(AnimatorOverrideController)) as AnimatorOverrideController;

                    string Temp = FilePath;
                    Temp = Temp.Replace(".overrideController", ".controller");
                    AssetDatabase.CopyAsset("Assets/Emerald AI 2.0/Animator/Temp Emerald Animator (Do Not Edit).controller", Temp);
                    overrideController.runtimeAnimatorController = AssetDatabase.LoadAssetAtPath(Temp, typeof(RuntimeAnimatorController)) as RuntimeAnimatorController;

                    AIAnimator = ObjectToSetup.GetComponent <Animator>();
                    AIAnimator.runtimeAnimatorController = overrideController;

                    ObjectToSetup.transform.position = _T;
                }
            }
        }
        EditorGUI.EndDisabledGroup();

        if (SetupAnimationsRef == SetupAnimations.Now && overrideController != null)
        {
            GUI.backgroundColor = new Color(10f, 0.0f, 0.0f, 0.25f);
            EditorGUILayout.LabelField("Note: Closing the Emerald Setup Manager will lose all references you've entered to the animations clips below. Make sure you select 'Setup AI' before closing, if you'd like your changes to be applied.", EditorStyles.helpBox);
            GUI.backgroundColor = Color.white;

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.LabelField("Idle Animations", EditorStyles.helpBox);
            GUI.backgroundColor = Color.white;

            Idle1       = (AnimationClip)EditorGUILayout.ObjectField("Idle 1 Animation", Idle1, typeof(AnimationClip), true);
            Idle2       = (AnimationClip)EditorGUILayout.ObjectField("Idle 2 Animation", Idle2, typeof(AnimationClip), true);
            Idle3       = (AnimationClip)EditorGUILayout.ObjectField("Idle 3 Animation", Idle3, typeof(AnimationClip), true);
            IdleAlert   = (AnimationClip)EditorGUILayout.ObjectField("Idle Alert Animation", IdleAlert, typeof(AnimationClip), true);
            IdleWarning = (AnimationClip)EditorGUILayout.ObjectField("Idle Warning Animation", IdleWarning, typeof(AnimationClip), true);
            IdleCombat  = (AnimationClip)EditorGUILayout.ObjectField("Idle Combat Animation", IdleCombat, typeof(AnimationClip), true);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.LabelField("Movement Animations", EditorStyles.helpBox);
            GUI.backgroundColor = Color.white;
            Walk      = (AnimationClip)EditorGUILayout.ObjectField("Walk Animation", Walk, typeof(AnimationClip), true);
            Run       = (AnimationClip)EditorGUILayout.ObjectField("Run Animation", Run, typeof(AnimationClip), true);
            TurnLeft  = (AnimationClip)EditorGUILayout.ObjectField("Turn Left Animation", TurnLeft, typeof(AnimationClip), true);
            TurnRight = (AnimationClip)EditorGUILayout.ObjectField("Turn Right Animation", TurnRight, typeof(AnimationClip), true);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.LabelField("Combat Animations", EditorStyles.helpBox);
            GUI.backgroundColor = Color.white;
            Attack1             = (AnimationClip)EditorGUILayout.ObjectField("Attack 1 Animation", Attack1, typeof(AnimationClip), true);
            Attack2             = (AnimationClip)EditorGUILayout.ObjectField("Attack 2 Animation", Attack2, typeof(AnimationClip), true);
            Attack3             = (AnimationClip)EditorGUILayout.ObjectField("Attack 3 Animation", Attack3, typeof(AnimationClip), true);
            RunAttack           = (AnimationClip)EditorGUILayout.ObjectField("Run Attack Animation", RunAttack, typeof(AnimationClip), true);
            Hit1     = (AnimationClip)EditorGUILayout.ObjectField("Hit Animation", Hit1, typeof(AnimationClip), true);
            DeadAnim = (AnimationClip)EditorGUILayout.ObjectField("Death Animation", DeadAnim, typeof(AnimationClip), true);
        }

        GUILayout.Space(35);

        if (SetupAnimationsRef == SetupAnimations.Now && overrideController == null)
        {
            GUI.backgroundColor = new Color(10f, 0.0f, 0.0f, 0.25f);
            EditorGUILayout.LabelField("You must create an Animator Controller for this AI, when using the Setup Animations Now feature.", EditorStyles.helpBox);
            GUI.backgroundColor = Color.white;
        }

        if (ObjectToSetup == null)
        {
            GUI.backgroundColor = new Color(10f, 0.0f, 0.0f, 0.25f);
            EditorGUILayout.LabelField("You must have an object applied to the AI Object slot before you can complete the setup process.", EditorStyles.helpBox);
            GUI.backgroundColor = Color.white;
        }

        EditorGUI.BeginDisabledGroup(SetupAnimationsRef == SetupAnimations.Now && overrideController == null || ObjectToSetup == null);
        if (GUILayout.Button("Setup AI"))
        {
            if (EditorUtility.DisplayDialog("Emerald AI Setup Manager", "Are you sure you'd like to setup an AI on this object?", "Setup", "Cancel"))
            {
                PrefabUtility.DisconnectPrefabInstance(ObjectToSetup);
                AssignEmeraldAIComponents();
                startVal = EditorApplication.timeSinceStartup;
            }
        }
        GUILayout.Space(25);
        EditorGUI.EndDisabledGroup();

        EditorGUILayout.EndVertical();
        EditorGUILayout.EndScrollView();
        GUILayout.Space(25);
        GUILayout.EndHorizontal();
        EditorGUILayout.EndVertical();


        GUILayout.Space(30);

        if (secs > 0)
        {
            progress = EditorApplication.timeSinceStartup - startVal;

            if (progress < secs)
            {
                EditorUtility.DisplayProgressBar("Emerald AI Setup Manager", "Setting up AI...", (float)(progress / secs));
            }
            else
            {
                EditorUtility.ClearProgressBar();
            }
        }
    }
Example #5
0
    /*
     * This Enumerator has the whole behaviour of the states of the AI.
     * There are 4 cases of AIStates, idle, chasing, attack, follow.
     */
    IEnumerator Think()
    {
        while (true)
        {
            switch (aiState)
            {
            /*
             * The default state of the AI. StatusIcon = green.
             * The distance to the player and the leaderzombie will be calculated and if they are in the distanceThreshold, a linecast will be used to determine
             * if the player/leaderzombie should be visible or is blocked by walls. Zombies can see the player trough other zombies.(Layermask)
             * The speed of the Agents will be set to 0.5f and the animation of the slow walk is used.
             * Only 4 zombies can be in the attacking state at the same time.
             * When there is no player or leaderzombie visible, the Agent starts to wander depending on the Wandertype, in this case the waypoint system.
             * If the player is visible the AI switches to the AIState.chasing.
             * If the leaderzombie is visible the AI switches to the AIState.follow.
             */
            case AIState.idle:
                float dist = Vector3.Distance(target.position, transform.position);
                Sprite.color = new Color(0f, 1f, 0f, 1f);
                nm.speed     = 0.5f;
                if (control.GetComponent <SwarmControl>().leaderExists)
                {
                    leader = GameObject.FindGameObjectWithTag("Leader");
                    float dist2 = Vector3.Distance(leader.transform.position, transform.position);
                    if (dist2 < distanceThreshold && dist2 > 0.2f)
                    {
                        if (Physics.Linecast(transform.position, leader.transform.position, out hit, ~(1 << 8)))
                        {
                            if (hit.transform.CompareTag("Leader"))
                            {
                                nm.speed = 0.5f;
                                aiState  = AIState.follow;
                                animator.SetBool("Chasing", false);
                            }
                            else
                            {
                                Wander();
                            }
                        }
                    }
                }
                if (dist < distanceThreshold && !player.playerDown)
                {
                    if (Physics.Linecast(transform.position, target.position, out hit, ~(1 << 8)))
                    {
                        if (hit.transform.CompareTag("Player") && control.GetComponent <SwarmControl>().attackingZombies < 4 && control.GetComponent <SwarmControl>().chasingZombies < 4)
                        {
                            aiState = AIState.chasing;
                            animator.SetBool("Chasing", true);
                            control.GetComponent <SwarmControl>().chasingZombies += 1;
                        }
                        else
                        {
                            Wander();
                        }
                    }
                }
                else
                {
                    Wander();
                }
                break;

            /*
             * The chasing state of the AI. Statusicon = Yellow.
             * Movement speed is set up to double the amount of the idle state speed (now 1.0f)
             * The AI starts to move to the players location. If the player has 0 healthpoints left
             * or the AI cant see him anymore the AI will go back into the idle state.
             * If the player is in attackrange, the AI will go into the AIState.attack.
             */
            case AIState.chasing:

                Sprite.color = new Color(1f, 1f, 0f, 1f);
                dist         = Vector3.Distance(target.position, transform.position);
                nm.speed     = 1f;
                nm.SetDestination(target.position);

                if (player.getHealthPoints() <= 0)
                {
                    aiState = AIState.idle;
                    animator.SetBool("Chasing", false);
                    control.GetComponent <SwarmControl>().chasingZombies -= 1;
                }

                if (Physics.Linecast(transform.position, target.position, out hit, (1 << 11) | (1 << 10)))
                {
                    if (!hit.transform.CompareTag("Player"))
                    {
                        aiState = AIState.idle;
                        animator.SetBool("Chasing", false);
                        control.GetComponent <SwarmControl>().chasingZombies -= 1;
                    }
                }

                if (dist > distanceThreshold)
                {
                    aiState = AIState.idle;
                    animator.SetBool("Chasing", false);
                    control.GetComponent <SwarmControl>().chasingZombies -= 1;
                }

                if (dist < attackThreshold && control.GetComponent <SwarmControl>().attackingZombies < 4)
                {
                    aiState = AIState.attack;
                    animator.SetBool("Attacking", true);
                    control.GetComponent <SwarmControl>().attackingZombies += 1;
                }
                break;

            /*
             *  The attacking state of the AI. Statusicon = red.
             *  When the player has 0 healthpoints, the AI will check for the closest Waypoint and switch to idle state.
             *  If the player moves away and is not in attack range anymore, the AI will switch into chasing state.
             *  The AI damages the player while in attack state.
             */
            case AIState.attack:

                Sprite.color = new Color(1f, 0f, 0f, 1f);
                dist         = Vector3.Distance(target.position, transform.position);

                if (player.getHealthPoints() <= 0)
                {
                    control.GetComponent <SwarmControl>().attackingZombies -= 1;
                    control.GetComponent <SwarmControl>().chasingZombies   -= 1;
                    nm.SetDestination(transform.position);
                    checkClosestWaypoint();
                    wanderType = WanderType.Waypoint;

                    aiState = AIState.idle;
                    animator.SetBool("Attacking", false);
                    animator.SetBool("Chasing", false);
                }

                if (dist > attackThreshold)
                {
                    control.GetComponent <SwarmControl>().attackingZombies -= 1;
                    aiState = AIState.chasing;
                    animator.SetBool("Attacking", false);
                }
                player.damageHealthPoints(0.5f);
                nm.SetDestination(transform.position);
                break;

            /*
             * The follow state of the AI. Statusicon = orange.
             * If the zombieleader is visible but far away, the AI will have a speedboost,
             * until beeing close to the leaderzombie
             * When the leaderzombie is not visible or to far away, the AI will switch into idle state.
             * Same goes for the player.
             * If the player is visible while following the leaderzombie, the AI will switch into the
             * chasing state.
             */
            case AIState.follow:
                Sprite.color = new Color(1f, 0.65f, 0f, 1f);
                dist         = Vector3.Distance(target.position, transform.position);
                float distLeader = Vector3.Distance(leader.transform.position, transform.position);

                if (distLeader > 3)
                {
                    nm.speed = 1f;
                }
                else
                {
                    nm.speed = 0.5f;
                }

                if (Physics.Linecast(transform.position, leader.transform.position, out hit, ~(1 << 8)))
                {
                    if (!hit.transform.CompareTag("Leader"))
                    {
                        nm.speed = 0.5f;
                        aiState  = AIState.idle;
                        animator.SetBool("Chasing", false);
                    }
                    else
                    {
                        nm.SetDestination(leader.transform.position);
                    }
                }

                if (distLeader > distanceThreshold)
                {
                    aiState = AIState.idle;
                    animator.SetBool("Chasing", false);
                }

                if (dist < distanceThreshold)
                {
                    if (Physics.Linecast(transform.position, target.position, out hit, (1 << 11) | (1 << 10)))
                    {
                        if (hit.transform.CompareTag("Player"))
                        {
                            aiState = AIState.chasing;
                            animator.SetBool("Chasing", true);
                        }
                    }
                }
                break;

            default:
                break;
            }

            yield return(new WaitForSeconds(0.2f)); //delay 0.2 second when destination changes
        }
    }
Example #6
0
        void OnGUI()
        {
            GUILayout.Space(15);

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.BeginVertical("Box");
            var style = new GUIStyle(EditorStyles.boldLabel)
            {
                alignment = TextAnchor.MiddleCenter
            };

            EditorGUILayout.LabelField(new GUIContent(SettingsIcon), style, GUILayout.ExpandWidth(true), GUILayout.Height(32));
            EditorGUILayout.LabelField("Emerald AI Setup Manager", style, GUILayout.ExpandWidth(true));
            EditorGUILayout.HelpBox("The Emerald AI Setup Manager applies all needed settings and components to automatically create an AI on the applied object. Be aware that closing the Emerald Setup Manager will lose all references you've entered below. Make sure you select 'Setup AI' before closing, if you'd like your changes to be applied.", MessageType.None, true);
            GUILayout.Space(4);

            var HelpButtonStyle = new GUIStyle(GUI.skin.button);

            HelpButtonStyle.normal.textColor = Color.white;
            HelpButtonStyle.fontStyle        = FontStyle.Bold;

            GUI.backgroundColor = new Color(1f, 1, 0.25f, 0.25f);
            EditorGUILayout.LabelField("For a detailed tutorial on setting up an AI from start to finish, please see the Getting Started Tutorial below.", EditorStyles.helpBox);
            GUI.backgroundColor = new Color(0, 0.65f, 0, 0.8f);
            if (GUILayout.Button("See the Getting Started Tutorial", HelpButtonStyle, GUILayout.Height(20)))
            {
                Application.OpenURL("https://github.com/Black-Horizon-Studios/Emerald-AI/wiki/Creating-a-New-AI");
            }
            GUI.backgroundColor = Color.white;
            GUILayout.Space(10);

            EditorGUILayout.EndVertical();
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            GUILayout.Space(15);

            EditorGUILayout.BeginVertical();

            GUILayout.BeginHorizontal();
            GUILayout.Space(25);
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos);

            EditorGUILayout.BeginVertical("Box");

            GUI.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.25f);
            EditorGUILayout.BeginVertical("Box");
            EditorGUILayout.LabelField("Setup Settings", EditorStyles.boldLabel);
            GUI.backgroundColor = Color.white;
            EditorGUILayout.EndVertical();
            GUI.backgroundColor = Color.white;

            GUILayout.Space(15);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("The object that the Emerald AI system will be added to.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
            if (ObjectToSetup == null)
            {
                GUI.backgroundColor = new Color(10f, 0.0f, 0.0f, 0.25f);
                EditorGUILayout.LabelField("This field cannot be left blank.", EditorStyles.helpBox);
                GUI.backgroundColor = Color.white;
            }
            ObjectToSetup = (GameObject)EditorGUILayout.ObjectField("AI Object", ObjectToSetup, typeof(GameObject), true);
            GUILayout.Space(10);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("The Unity Tag that will be applied to your AI. Note: Untagged cannot be used.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
            AITag = EditorGUILayout.TagField("Tag for AI", AITag);
            GUILayout.Space(10);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("The Unity Layer that will be applied to your AI. Note: Default cannot be used.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
            AILayer             = EditorGUILayout.LayerField("Layer for AI", AILayer);
            GUILayout.Space(10);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("The Behavior that will be applied to this AI.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
            AIBehaviorRef       = (AIBehavior)EditorGUILayout.EnumPopup("AI's Behavior", AIBehaviorRef);
            GUILayout.Space(10);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("The Confidence that will be applied to this AI.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
            ConfidenceRef       = (ConfidenceType)EditorGUILayout.EnumPopup("AI's Confidence", ConfidenceRef);
            GUILayout.Space(10);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("The Wander Type  that will be applied to this AI.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
            WanderTypeRef       = (WanderType)EditorGUILayout.EnumPopup("AI's Wander Type", WanderTypeRef);
            GUILayout.Space(10);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("Would you like the Setup Manager to automatically setup Emerald's optimization settings? This allows Emerald to be deactivated when an AI is culled or not visible which will help improve performance.", MessageType.None, true);
            GUI.backgroundColor          = Color.white;
            SetupOptimizationSettingsRef = (SetupOptimizationSettings)EditorGUILayout.EnumPopup("Auto Optimize", SetupOptimizationSettingsRef);
            GUILayout.Space(10);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("The Weapon Type this AI will use.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
            WeaponTypeRef       = (WeaponType)EditorGUILayout.EnumPopup("Weapon Type", WeaponTypeRef);
            GUILayout.Space(10);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("Controls whether this AI will play an animation on death or transition to a ragdoll state.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
            DeathTypeRef        = (DeathType)EditorGUILayout.EnumPopup("Death Type", DeathTypeRef);
            GUILayout.Space(10);

            GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.19f);
            EditorGUILayout.HelpBox("Controls whether this AI will use Root Motion or NavMesh for its movement and speed.", MessageType.None, true);
            GUI.backgroundColor = Color.white;
            AnimatorType        = (AnimatorTypeState)EditorGUILayout.EnumPopup("Animator Type", AnimatorType);
            GUILayout.Space(30);

            if (ObjectToSetup == null)
            {
                GUI.backgroundColor = new Color(10f, 0.0f, 0.0f, 0.25f);
                EditorGUILayout.LabelField("You must have an object applied to the AI Object slot before you can complete the setup process.", EditorStyles.helpBox);
                GUI.backgroundColor = Color.white;
            }

            EditorGUI.BeginDisabledGroup(ObjectToSetup == null);
            if (GUILayout.Button("Setup AI"))
            {
                if (EditorUtility.DisplayDialog("Emerald AI Setup Manager", "Are you sure you'd like to setup an AI on this object?", "Setup", "Cancel"))
                {
                    #if UNITY_2018_3_OR_NEWER
                    PrefabAssetType m_AssetType = PrefabUtility.GetPrefabAssetType(ObjectToSetup);

                    //Only unpack prefab if the ObjectToSetup is a prefab.
                    if (m_AssetType != PrefabAssetType.NotAPrefab)
                    {
                        PrefabUtility.UnpackPrefabInstance(ObjectToSetup, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
                    }
                    #else
                    PrefabUtility.DisconnectPrefabInstance(ObjectToSetup);
                    #endif
                    AssignEmeraldAIComponents();
                    startVal = EditorApplication.timeSinceStartup;
                }
            }
            GUILayout.Space(25);
            EditorGUI.EndDisabledGroup();

            EditorGUILayout.EndVertical();
            EditorGUILayout.EndScrollView();
            GUILayout.Space(25);
            GUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();


            GUILayout.Space(30);

            if (secs > 0)
            {
                progress = EditorApplication.timeSinceStartup - startVal;

                if (progress < secs)
                {
                    EditorUtility.DisplayProgressBar("Emerald AI Setup Manager", "Setting up AI...", (float)(progress / secs));
                }
                else
                {
                    EditorUtility.ClearProgressBar();

                    if (DisplayConfirmation && !DontShowDisplayConfirmation)
                    {
                        if (EditorUtility.DisplayDialog("Emerald AI Setup Manager - Success", "Your AI has been successfully created! You will still need to create an Animator Controller, " +
                                                        "apply your AI's Animations, and assign the AI's Head Transform from within the Emerald AI Editor. You may also need to adjust the generated Box Collider's " +
                                                        "position and size to properly fit your AI's model.", "Okay", "Okay, Don't Show Again"))
                        {
                            DisplayConfirmation = false;
                        }
                        else
                        {
                            DisplayConfirmation         = false;
                            DontShowDisplayConfirmation = true;
                        }
                    }
                }
            }
        }