示例#1
0
        //private IEnumerator AttackDelayTime()
        //{
        //    float rand = UnityEngine.Random.Range(.35f, 1.35f);
        //    yield return CustomTimer.Timer(rand);
        //    _canAttack = true;
        //    canStartAttackDelayTime = true;
        //}

        //Attack time before going back to followTarget.
        private IEnumerator AttackTime(float time)
        {
            yield return(CustomTimer.Timer(time));

            _canReposition     = true;
            CurrentAttackState = RaccoonAttackState.FollowTarget;
        }
示例#2
0
        /// <summary>
        /// Event when entering a state
        /// </summary>
        public void OnStateEnter(RaccoonState state, RaccoonState fromState)
        {
            //SET MAXSPEED etc. HERE
            switch (state)
            {
            case RaccoonState.Default:
            {
                fieldOfView          = 60;
                timesAlerted         = 0;
                _canCheckPathfinding = true;
                _shouldMoveToHome    = true;
                MaxStableMoveSpeed   = 9f;
                //MaxMoveSpeed = x.
                //Set target to home position.
                //Reset numberOfTimesAlerted.
                break;
            }

            case RaccoonState.Alerted:
            {
                fieldOfView   = 360;
                timesAlerted += 1;
                //MaxMoveSpeed = x.
                //Set target to the detected object (thrown object or player.)
                //Play a coroutine for x amount of time.
                //If the player caused the alert, add 1 to numberOfTimesAlerted . (This is reset in the default state.)
                break;
            }

            case RaccoonState.AlertOthers:
            {
                //(Field of view doesn't matter here)
                //Play coroutine for x amount of time. Transition to followTarget.
                break;
            }

            case RaccoonState.Attack:
            {
                //_canAttack = true;
                _canChooseRandomAttack = true;
                _canCheckPathfinding   = true;
                timesAlerted           = 0;
                _canReposition         = true;
                canThrowRock           = true;
                CurrentAttackState     = RaccoonAttackState.FollowTarget;
                break;
            }

            case RaccoonState.Search:
            {
                SearchStateCoroutine = StartCoroutine(SearchStateTime());
                fieldOfView          = 60;
                break;
            }
            }
        }
示例#3
0
        //Rock throw timing
        private IEnumerator RockThrowTime()
        {
            float rand = UnityEngine.Random.Range(1f, 2.5f);

            yield return(CustomTimer.Timer(rand));

            Debug.Log("Throwing a rock.");
            CurrentAttackState = RaccoonAttackState.RockAttack;
            yield return(CustomTimer.Timer(2.5f));

            CurrentAttackState = RaccoonAttackState.FollowTarget;
            canThrowRock       = true;
        }
示例#4
0
        /// <summary>
        /// (Called by KinematicCharacterMotor during its update cycle)
        /// This is called after the character has finished its movement update
        /// </summary>
        public void AfterCharacterUpdate(float deltaTime)
        {
            //SET STATE TRANSITIONS HERE.

            //Switch to default state if in midair
            if (!Motor.GroundingStatus.IsStableOnGround)
            {
                if (CurrentRaccoonState != RaccoonState.Default)
                {
                    //Get the current state and store it.
                    //Transition to falling state (and transition back to either a new state or the stored state).
                    //Enemy should be able to transition back to the last state without anything screwing up.
                }
            }

            if (pathfinding.PathIsActive)
            {
                pathfinding.motorUpDirection = Motor.CharacterUp;
            }

            //Check line of sight to the target.
            _lineOfSightToTarget = LineOfSightToTarget(targetPosition, fieldOfView);

            //float maxDistance = 12f;
            Vector3 targetDirection = targetPosition - Motor.Transform.position;

            //Debug.Log(targetDirection);

            //State checking
            switch (CurrentRaccoonState)
            {
            case RaccoonState.Default:
            {
                if (_lineOfSightToTarget)
                {
                    TransitionToState(RaccoonState.Alerted);
                }

                _lineOfSightToHome = LineOfSightToTarget(homePosition, 360f);

                //If the home position is too far away...
                Vector3 homeDirection          = homePosition - Motor.Transform.position;
                Vector3 projectedHomeDirection = Vector3.ProjectOnPlane(homeDirection, Motor.CharacterUp);
                float   homeMaxDistance        = 2f;

                //Debug.Log(homeDirection);
                if (!_lineOfSightToHome)
                {
                    if (_canCheckPathfinding)     //(Reset this)
                    {
                        _canCheckPathfinding = false;
                        pathfinding.CheckIfCanFollowPath(homePosition);
                    }

                    if (pathfinding.PathIsActive)
                    {
                        _shouldMoveToHome = true;
                    }
                    else
                    {
                        _shouldMoveToHome = false;
                    }
                }
                else
                {
                    //Debug.Log(projectedHomeDirection.magnitude);
                    if (projectedHomeDirection.sqrMagnitude > Mathf.Pow(homeMaxDistance, 2))
                    {
                        _shouldMoveToHome = true;
                    }
                    else
                    {
                        _shouldMoveToHome = false;
                    }
                }


                //If player is detected, transition to alerted state.
                break;
            }

            case RaccoonState.Alerted:
            {
                if (timeWhileTargetSeen >= maxAlertedTime || timesAlerted > 1)
                {
                    //For now, just transition to follow player until group detection is set up.
                    TransitionToState(RaccoonState.Attack);
                }

                if (!_lineOfSightToTarget && canStartAlertToSearch)
                {
                    canStartAlertToSearch  = false;
                    AlertToSearchCoroutine = StartCoroutine(AlertToSearchTransitionTime());
                }

                break;
            }

            case RaccoonState.AlertOthers:
            {
                //Nuthin yet
                break;
            }

            case RaccoonState.Search:
            {
                if (_lineOfSightToTarget)
                {
                    TransitionToState(RaccoonState.Alerted);
                }
                break;
            }

            case RaccoonState.Attack:
            {
                switch (CurrentAttackState)
                {
                case RaccoonAttackState.FollowTarget:
                {
                    float targetDirMagnitude = targetDirection.sqrMagnitude;

                    //Check the player's height
                    //ISSUE: ONLY WORKS ON GROUND PLANE. NEEDS TO WORK WHILE THE ENEMY IS ALSO UP HIGH.
                    float   MaxHeightDistance = 2f;
                    Vector3 targetDistOnPlane = Vector3.ProjectOnPlane(targetPosition, Motor.CharacterUp); //*Projects targetPosition on ground plane.
                    float   targetHeight      = (targetPosition - targetDistOnPlane).sqrMagnitude;         //Direction between target's position and it's point on the ground.
                    Vector3 enemyDistOnPlane  =
                        Vector3.ProjectOnPlane(Motor.transform.position, Motor.CharacterUp);
                    float enemyHeight      = (Motor.transform.position - enemyDistOnPlane).sqrMagnitude;
                    float heightDifference = targetHeight - enemyHeight;
                    //Debug.Log(Mathf.Sqrt(Mathf.Abs(heightDifference)));
                    bool targetIsWithinHeight = Mathf.Abs(heightDifference) < Mathf.Pow(MaxHeightDistance, 2);

                    //The issue here is that we're comparing the player's height to it's point on the ground plane. We need to take the enemy's position into account
                    //as well. (Ex: Repeat the process to get the enemy's height, then get the difference from both the player's height and enemy's height.

                    //Repositioning stuff
                    if (targetIsWithinHeight)
                    {
                        if (!canThrowRock)
                        {
                            canThrowRock = true;
                        }
                        StopActiveCoroutine(RockThrowCoroutine);
                        if (targetDirMagnitude > Mathf.Pow(RepositionDistance, 2))
                        {
                            //Debug.Log(targetDirMagnitude / targetDirection.magnitude);
                            CurrentFollowState = RaccoonFollowTargetState.MoveToTarget;         //**
                            //If 1 hand is free...
                            //Random chance to throw rocks.
                        }
                        else
                        {
                            if (_canReposition)         //Remember to reset this, timesRepositioned, AND timesWaited.
                            {
                                _canReposition = false;
                                int rand = UnityEngine.Random.Range(0, 100);

                                //If repositioned/waited up to 3 times...
                                if (timesRepositioned + timesWaitedInPlace <= 3)
                                {
                                    //Reposition (up to 2)
                                    if ((rand > 50 && rand <= 75) || timesWaitedInPlace > 0)
                                    {
                                        Debug.Log("Repositioning.");
                                        timesRepositioned      += 1;
                                        CurrentFollowState      = RaccoonFollowTargetState.Reposition;
                                        RepositionTimeCoroutine = StartCoroutine(RepositionTime(.65f, .95f));
                                        //RepositionTimeCoroutine = StartCoroutine(RepositionTime(, 10f));
                                    }
                                    //Wait (up to 1)
                                    else if ((rand > 75 && rand <= 100) && timesWaitedInPlace == 0)
                                    {
                                        Debug.Log("Waiting.");
                                        timesWaitedInPlace     += 1;
                                        CurrentFollowState      = RaccoonFollowTargetState.Wait;
                                        RepositionTimeCoroutine = StartCoroutine(RepositionTime(.85f, 1.15f));
                                    }
                                }

                                //If over the reposition amount OR rand <= 50...
                                if (timesRepositioned + timesWaitedInPlace > 3 || rand <= 50)
                                {
                                    //(Moves towards the target here in moveInputVector)
                                    Debug.Log("Continuing movement.");
                                    CurrentFollowState = RaccoonFollowTargetState.MoveToTarget;         //**
                                }
                            }
                        }
                    }
                    //else if (_lineOfSightToTarget && !pathfinding.PathIsActive)
                    //{
                    //if (canThrowRock)
                    //{
                    //    canThrowRock = false;
                    //    CurrentFollowState = RaccoonFollowTargetState.Wait;
                    //    RockThrowCoroutine = StartCoroutine(RockThrowTime());
                    //}
                    //}

                    //Transition to sword attack
                    switch (CurrentFollowState)
                    {
                    case RaccoonFollowTargetState.MoveToTarget:
                    {
                        if (targetDirMagnitude < Mathf.Pow(AttackDistance, 2))             //**
                        {
                            //Sword Attack.
                            Debug.Log("Sword attack");
                            CurrentAttackState  = RaccoonAttackState.SwordAttack;
                            AttackTimeCoroutine = StartCoroutine(AttackTime(1.2f));
                            timesRepositioned   = 0;
                            timesWaitedInPlace  = 0;
                        }
                        break;
                    }
                    }

                    //Pathfinding (line of sight)
                    if (!_lineOfSightToTarget)
                    {
                        CurrentFollowState = RaccoonFollowTargetState.MoveToTarget;
                        if (_canCheckPathfinding)
                        {
                            _canCheckPathfinding = false;
                            pathfinding.CheckIfCanFollowPath(targetPosition);
                        }

                        //If path is unreachable...
                        if (!pathfinding.PathIsActive && !pathfinding.CheckingPath)         //*Double check this in game.
                        {
                            //Coroutine to wait? Then...
                            TransitionToState(RaccoonState.Search);
                        }
                    }
                    //Pathfinding (target height check)
                    else if (!targetIsWithinHeight)
                    {
                        if (_canCheckPathfinding)
                        {
                            _canCheckPathfinding = false;
                            pathfinding.CheckIfCanFollowPath(targetPosition);
                        }

                        if (!pathfinding.PathIsActive && !pathfinding.CheckingPath)
                        {
                            if (canThrowRock)
                            {
                                canThrowRock       = false;
                                CurrentFollowState = RaccoonFollowTargetState.Wait;
                                RockThrowCoroutine = StartCoroutine(RockThrowTime());
                            }
                        }
                    }
                    else         //*Make sure no other code interrupts this section.
                    {
                        _canCheckPathfinding = true;
                        pathfinding.StopFollowPath();
                    }
                    break;
                }
                }

                break;
            }
            }
        }