예제 #1
0
        private IEnumerator MakeAttack(WanderScript target)
        {
            target.GetAttacked(this);

            float timer = 0f;

            while (!target.dead)
            {
                timer += Time.deltaTime;

                if (timer > attackSpeed)
                {
                    target.TakeDamage(power);
                    timer = 0f;
                }

                yield return(null);
            }

            if (attackingStates.Length > 0 && !string.IsNullOrEmpty(attackingStates[currentState].animationBool))
            {
                animator.SetBool(attackingStates[currentState].animationBool, false);
            }

            attackingEvent.Invoke();

            StopAllCoroutines();
            DecideNextState(false);
        }
예제 #2
0
        private void NonNavMeshRunAwayFromAnimal(WanderScript predator)
        {
            moving = true;

            Quaternion startRotation = transform.rotation;

            transform.rotation = Quaternion.LookRotation(transform.position - predator.transform.position);
            targetLocation     = transform.position + transform.forward * 5f;
            transform.rotation = startRotation;

            if (constainedToWanderZone && Vector3.Distance(targetLocation, origin) > wanderZone)
            {
                targetLocation = RandonPointInRange();
            }

            int fastestMovementState = 0;

            for (int i = 0; i < movementStates.Length; i++)
            {
                if (movementStates[i].moveSpeed > movementStates[fastestMovementState].moveSpeed)
                {
                    fastestMovementState = i;
                }
            }
            currentState = fastestMovementState;

            if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
            {
                animator.SetBool(movementStates[currentState].animationBool, true);
            }

            StartCoroutine(NonNavMeshRunAwayState(targetLocation, predator));
        }
예제 #3
0
        private void AttackAnimal(WanderScript target)
        {
            attacking = true;

            if (logChanges)
            {
                Debug.Log(string.Format("{0}: Attacking {1}!", gameObject.name, target.gameObject.name));
            }

            if (useNavMesh)
            {
                navMeshAgent.SetDestination(transform.position);
            }
            else
            {
                targetLocation = transform.position;
            }

            currentState = Random.Range(0, attackingStates.Length);

            if (attackingStates.Length > 0)
            {
                if (!string.IsNullOrEmpty(attackingStates[currentState].animationBool))
                {
                    animator.SetBool(attackingStates[currentState].animationBool, true);
                }
            }

            StartCoroutine(MakeAttack(target));
        }
예제 #4
0
        private IEnumerator RunAwayState(Vector3 target, WanderScript predator)
        {
            navMeshAgent.speed        = movementStates[currentState].moveSpeed;
            navMeshAgent.angularSpeed = movementStates[currentState].turnSpeed;
            navMeshAgent.SetDestination(target);

            float timeMoving = 0f;

            while ((navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance || timeMoving < 0.1f) && timeMoving < stamina)
            {
                timeMoving += Time.deltaTime;
                yield return(null);
            }

            navMeshAgent.SetDestination(transform.position);

            if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
            {
                animator.SetBool(movementStates[currentState].animationBool, false);
            }

            if (timeMoving > stamina || predator.dead || Vector3.Distance(transform.position, predator.transform.position) > awareness)
            {
                BeginIdleState();
            }
            else
            {
                RunAwayFromAnimal(predator);
            }
        }
예제 #5
0
        private IEnumerator ChaseState(WanderScript prey)
        {
            moving = true;

            navMeshAgent.speed        = movementStates[currentState].moveSpeed;
            navMeshAgent.angularSpeed = movementStates[currentState].turnSpeed;
            navMeshAgent.SetDestination(prey.transform.position);

            float timeMoving = 0f;
            bool  gotAway    = false;

            while ((navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance || timeMoving < 0.1f) && timeMoving < stamina)
            {
                navMeshAgent.SetDestination(prey.transform.position);

                timeMoving += Time.deltaTime;

                if (Vector3.Distance(transform.position, prey.transform.position) < 2f)
                {
                    if (logChanges)
                    {
                        Debug.Log(string.Format("{0}: Caught prey ({1})!", gameObject.name, prey.gameObject.name));
                    }

                    if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
                    {
                        animator.SetBool(movementStates[currentState].animationBool, false);
                    }

                    AttackAnimal(prey);
                    yield break;
                }

                if (constainedToWanderZone && Vector3.Distance(transform.position, origin) > wanderZone)
                {
                    gotAway = true;
                    navMeshAgent.SetDestination(transform.position);
                    break;
                }

                yield return(null);
            }

            navMeshAgent.SetDestination(transform.position);

            if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
            {
                animator.SetBool(movementStates[currentState].animationBool, false);
            }

            if (timeMoving > stamina || prey.dead || Vector3.Distance(transform.position, prey.transform.position) > scent || gotAway)
            {
                BeginIdleState();
            }
            else
            {
                ChaseAnimal(prey);
            }
        }
예제 #6
0
        private void BeginChase(WanderScript chasingAnimal)
        {
            if (attacking)
            {
                return;
            }

            StartCoroutine(ChaseCheck(chasingAnimal));
        }
예제 #7
0
        private void GetAttacked(WanderScript attacker)
        {
            if (attacking)
            {
                return;
            }

            if (logChanges)
            {
                Debug.Log(string.Format("{0}: Getting attacked by {1}!", gameObject.name, attacker.gameObject.name));
            }
            StopAllCoroutines();

            StartCoroutine(TurnToLookAtTarget(attacker.transform));

            if (agression > 0)
            {
                if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
                {
                    animator.SetBool(movementStates[currentState].animationBool, false);
                }

                AttackAnimal(attacker);
            }
            else
            {
                if (moving)
                {
                    if (useNavMesh)
                    {
                        navMeshAgent.SetDestination(transform.position);
                    }
                    else
                    {
                        targetLocation = transform.position;
                    }

                    if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
                    {
                        animator.SetBool(movementStates[currentState].animationBool, false);
                    }

                    moving = false;
                }
                else
                {
                    if (idleStates.Length > 0 && !string.IsNullOrEmpty(idleStates[currentState].animationBool))
                    {
                        animator.SetBool(idleStates[currentState].animationBool, false);
                    }
                }
            }
        }
예제 #8
0
        private IEnumerator ChaseCheck(WanderScript chasingAnimal)
        {
            while (Vector3.Distance(transform.position, chasingAnimal.transform.position) > awareness)
            {
                yield return(new WaitForSeconds(0.5f));
            }

            StopAllCoroutines();
            if (moving)
            {
                if (useNavMesh)
                {
                    navMeshAgent.SetDestination(transform.position);
                }
                else
                {
                    targetLocation = transform.position;
                }

                if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
                {
                    animator.SetBool(movementStates[currentState].animationBool, false);
                }

                moving = false;
            }
            else
            {
                if (idleStates.Length - 1 >= currentState)
                {
                    if (idleStates.Length > 0 && !string.IsNullOrEmpty(idleStates[currentState].animationBool))
                    {
                        animator.SetBool(idleStates[currentState].animationBool, false);
                    }
                }
            }

            DecideNextState(false);
        }
예제 #9
0
        private void RunAwayFromAnimal(WanderScript predator)
        {
            moving = true;

            Quaternion startRotation = transform.rotation;

            transform.rotation = Quaternion.LookRotation(transform.position - predator.transform.position);
            Vector3    areaAwayFromPredator = transform.position + transform.forward * 5f;
            NavMeshHit hit;

            NavMesh.SamplePosition(areaAwayFromPredator, out hit, 5, 1 << NavMesh.GetAreaFromName("Walkable"));
            Vector3 target = hit.position;

            transform.rotation = startRotation;

            if (constainedToWanderZone && Vector3.Distance(target, origin) > wanderZone)
            {
                target = RandonPointInRange();
            }

            int fastestMovementState = 0;

            for (int i = 0; i < movementStates.Length; i++)
            {
                if (movementStates[i].moveSpeed > movementStates[fastestMovementState].moveSpeed)
                {
                    fastestMovementState = i;
                }
            }
            currentState = fastestMovementState;

            if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
            {
                animator.SetBool(movementStates[currentState].animationBool, true);
            }

            StartCoroutine(RunAwayState(target, predator));
        }
예제 #10
0
        private void ChaseAnimal(WanderScript prey)
        {
            Vector3 target = prey.transform.position;

            prey.BeginChase(this);

            if (movementStates.Length <= 0)
            {
                Debug.Log("Movement states length is 0");
                this.enabled = false;
                return;
            }
            int fastestMovementState = 0;

            for (int i = 0; i < movementStates.Length; i++)
            {
                if (movementStates[i].moveSpeed > movementStates[fastestMovementState].moveSpeed)
                {
                    fastestMovementState = i;
                }
            }
            currentState = fastestMovementState;

            if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
            {
                animator.SetBool(movementStates[currentState].animationBool, true);
            }

            if (useNavMesh)
            {
                StartCoroutine(ChaseState(prey));
            }
            else
            {
                StartCoroutine(NonNavMeshChaseState(prey));
            }
        }
예제 #11
0
        private IEnumerator NonNavMeshRunAwayState(Vector3 target, WanderScript predator)
        {
            currentTurnSpeed = movementStates[currentState].turnSpeed;

            float walkTime           = 0f;
            float timeUntilAbortWalk = Vector3.Distance(transform.position, target) / movementStates[currentState].moveSpeed;

            while (Vector3.Distance(transform.position, target) > contingencyDistance && walkTime < timeUntilAbortWalk && stamina > 0)
            {
                characterController.SimpleMove(transform.TransformDirection(Vector3.forward) * movementStates[currentState].moveSpeed);

                Vector3    relativePos = target - transform.position;
                Quaternion rotation    = Quaternion.LookRotation(relativePos);
                transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * (currentTurnSpeed / 10));
                currentTurnSpeed  += Time.deltaTime;

                walkTime += Time.deltaTime;
                stamina  -= Time.deltaTime;
                yield return(null);
            }

            targetLocation = Vector3.zero;

            if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
            {
                animator.SetBool(movementStates[currentState].animationBool, false);
            }

            if (stamina <= 0 || predator.dead || Vector3.Distance(transform.position, predator.transform.position) > awareness)
            {
                BeginIdleState();
            }
            else
            {
                NonNavMeshRunAwayFromAnimal(predator);
            }
        }
예제 #12
0
        private IEnumerator NonNavMeshChaseState(WanderScript prey)
        {
            moving           = true;
            targetLocation   = prey.transform.position;
            currentTurnSpeed = movementStates[currentState].turnSpeed;

            float walkTime           = 0f;
            bool  gotAway            = false;
            float timeUntilAbortWalk = Vector3.Distance(transform.position, targetLocation) / movementStates[currentState].moveSpeed;


            while (Vector3.Distance(transform.position, targetLocation) > contingencyDistance && walkTime < timeUntilAbortWalk && stamina > 0)
            {
                characterController.SimpleMove(transform.TransformDirection(Vector3.forward) * movementStates[currentState].moveSpeed);
                targetLocation = prey.transform.position;

                Vector3    relativePos = targetLocation - transform.position;
                Quaternion rotation    = Quaternion.LookRotation(relativePos);
                transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * (currentTurnSpeed / 10));
                currentTurnSpeed  += Time.deltaTime;

                walkTime += Time.deltaTime;
                stamina  -= Time.deltaTime;

                if (Vector3.Distance(transform.position, prey.transform.position) < 2f)
                {
                    if (logChanges)
                    {
                        Debug.Log(string.Format("{0}: Caught prey ({1})!", gameObject.name, prey.gameObject.name));
                    }

                    if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
                    {
                        animator.SetBool(movementStates[currentState].animationBool, false);
                    }

                    AttackAnimal(prey);
                    yield break;
                }

                if (constainedToWanderZone && Vector3.Distance(transform.position, origin) > wanderZone)
                {
                    gotAway        = true;
                    targetLocation = transform.position;
                    break;
                }

                yield return(null);
            }

            targetLocation = Vector3.zero;

            if (!string.IsNullOrEmpty(movementStates[currentState].animationBool))
            {
                animator.SetBool(movementStates[currentState].animationBool, false);
            }

            if (stamina <= 0 || prey.dead || Vector3.Distance(transform.position, prey.transform.position) > scent || gotAway)
            {
                BeginIdleState();
            }
            else
            {
                ChaseAnimal(prey);
            }
        }
예제 #13
0
        public override void OnInspectorGUI()
        {
            WanderScript myWanderScript = (WanderScript)target;

            serializedObject.Update();

            //Get Lists
            SerializedProperty idleStates      = serializedObject.FindProperty("idleStates");
            SerializedProperty movementStates  = serializedObject.FindProperty("movementStates");
            SerializedProperty attackingStates = serializedObject.FindProperty("attackingStates");
            SerializedProperty deathStates     = serializedObject.FindProperty("deathStates");

            //Death Unity Event
            SerializedProperty deathEvent     = serializedObject.FindProperty("deathEvent");
            SerializedProperty attackingEvent = serializedObject.FindProperty("attackingEvent");
            SerializedProperty idleEvent      = serializedObject.FindProperty("idleEvent");

            SerializedProperty movementEvent = serializedObject.FindProperty("movementEvent");

            //Get Strings
            SerializedProperty species = serializedObject.FindProperty("species");

            //Get Animal Stats
            SerializedProperty stats = serializedObject.FindProperty("stats");

            //Get AI Controls
            SerializedProperty wanderSize             = serializedObject.FindProperty("wanderZone");
            SerializedProperty awareness              = serializedObject.FindProperty("awareness");
            SerializedProperty scent                  = serializedObject.FindProperty("scent");
            SerializedProperty constainedToWanderZone = serializedObject.FindProperty("constainedToWanderZone");
            SerializedProperty nonAgressiveTowards    = serializedObject.FindProperty("nonAgressiveTowards");
            SerializedProperty surfaceRotationSpeed   = serializedObject.FindProperty("surfaceRotationSpeed");
            SerializedProperty matchSurfaceRotation   = serializedObject.FindProperty("matchSurfaceRotation");

            ///DEBUG
            SerializedProperty logChanges         = serializedObject.FindProperty("logChanges");
            SerializedProperty showGizmos         = serializedObject.FindProperty("showGizmos");
            SerializedProperty drawWanderRange    = serializedObject.FindProperty("drawWanderRange");
            SerializedProperty drawScentRange     = serializedObject.FindProperty("drawScentRange");
            SerializedProperty drawAwarenessRange = serializedObject.FindProperty("drawAwarenessRange");


            //Load a Texture (Assets/Resources/Textures/texture01.png)
            var mainTexture = Resources.Load <Texture2D>("WanderScriptLogo");

            //Main Image
            GUILayout.BeginHorizontal();
            GUILayout.Label(mainTexture);
            GUILayout.EndHorizontal();

            //Draw The Species Name
            EditorGUILayout.PropertyField(species);
            EditorGUILayout.PropertyField(stats);


            if (GUILayout.Button("Show Animation States", GUILayout.MaxWidth(Screen.width - 30)))
            {
                AnimationStates = !AnimationStates;
            }

            if (AnimationStates)
            {
                GUILayout.BeginHorizontal();
                //GUILayout.Label(idleTexture);
                GUILayout.EndHorizontal();

                EditorGUILayout.PropertyField(idleStates, true);


                GUILayout.BeginHorizontal();
                //GUILayout.Label(movementTexture);
                GUILayout.EndHorizontal();

                EditorGUILayout.PropertyField(movementStates, true);


                GUILayout.BeginHorizontal();
                //GUILayout.Label(attackingTexture);
                GUILayout.EndHorizontal();

                EditorGUILayout.PropertyField(attackingStates, true);


                GUILayout.BeginHorizontal();
                //GUILayout.Label(deathTexture);
                GUILayout.EndHorizontal();

                EditorGUILayout.PropertyField(deathStates, true);
            }

            if (GUILayout.Button("Show State Unity Events", GUILayout.MaxWidth(Screen.width - 30)))
            {
                StateEvents = !StateEvents;
            }

            if (StateEvents)
            {
                var width = GUILayout.MaxWidth(Screen.width);
                EditorGUILayout.PropertyField(idleEvent, width);
                EditorGUILayout.PropertyField(movementEvent, width);
                EditorGUILayout.PropertyField(attackingEvent, width);
                EditorGUILayout.PropertyField(deathEvent, width);
            }

            if (GUILayout.Button("Show AI Controls", GUILayout.MaxWidth(Screen.width - 30)))
            {
                AIControls = !AIControls;
            }

            if (AIControls)
            {
                GUILayout.BeginHorizontal();
                //GUILayout.Label(AITexture);
                GUILayout.EndHorizontal();

                EditorGUILayout.PropertyField(wanderSize);
                EditorGUILayout.PropertyField(awareness);
                EditorGUILayout.PropertyField(scent);

                EditorGUILayout.PropertyField(constainedToWanderZone);
                EditorGUILayout.PropertyField(nonAgressiveTowards, true);
                EditorGUILayout.PropertyField(matchSurfaceRotation, true);
                EditorGUILayout.PropertyField(surfaceRotationSpeed, true);
            }

            if (GUILayout.Button("Show DEBUG Options", GUILayout.MaxWidth(Screen.width - 30)))
            {
                DEBUGToggle = !DEBUGToggle;
            }

            if (DEBUGToggle)
            {
                EditorGUILayout.PropertyField(logChanges);
                EditorGUILayout.PropertyField(showGizmos);
                EditorGUILayout.PropertyField(drawWanderRange);
                EditorGUILayout.PropertyField(drawScentRange);
                EditorGUILayout.PropertyField(drawAwarenessRange, true);
            }

            serializedObject.ApplyModifiedProperties();
            //DrawDefaultInspector();
        }