/// <summary>
        ///     Changes from Fase 1 to Fase 2
        /// </summary>
        /// <returns>The reference to the coroutine</returns>
        private IEnumerator F1ToF2StateCoroutine()
        {
            // Make boss vanish
            yield return(StartCoroutine(MakeBossVanish(_bossVanishTime)));

            // Move boss gameObject to F2 position
            transform.position = new Vector3(_f2PlatformPosition.position.x, _f2PlatformPosition.position.y, transform.position.z);
            // Wait for some time
            yield return(new WaitForSeconds(2.0f));

            // Make platforms appear
            for (int i = 0; i < _f2OtherPlatforms.Length; i++)
            {
                _f2OtherPlatforms[i].SetActive(true);
            }
            // Make spikes appear
            _f2LeftSpikes.SetActive(true);
            _f2RightSpikes.SetActive(true);
            _f2LeftPlatformSpikes.SetActive(true);
            _f2RightPlatformSpikes.SetActive(true);
            // Make boss appear
            yield return(StartCoroutine(MakeBossReappear(_bossVanishTime)));

            // Change state
            _enemyState = EEnemyStates.Alert;
            // Clear coroutine reference
            _f1ToF2StateCoroutine = null;
        }
        /// <summary>
        ///     F2 spikes reappearing coroutine
        /// </summary>
        /// <returns>The reference to the coroutine</returns>
        private IEnumerator F2SpikesReappearCoroutine()
        {
            // Vanish boss
            _spriteRenderer.enabled       = false;
            _capsuleCollider2D.enabled    = false;
            _attackSlider.normalizedValue = 0.0f;
            //_attackSlider.gameObject.SetActive(false);
            //_healthSlider.gameObject.SetActive(false);
            // Disable spikes colliders
            ManageSpikesCollidersTriggers(false);
            // Reappearing process
            float l_iter = 0;

            // Process
            while (l_iter < _f2SpikesReappearTimes)
            {
                // Enable spikes
                ManageSpikes(true);

                yield return(new WaitForSeconds(0.75f));

                // Disable spikes
                ManageSpikes(false);

                yield return(new WaitForSeconds(0.25f));

                l_iter++;
            }
            // Enable spikes colliders
            ManageSpikesCollidersTriggers(true);
            // Enable spikes
            ManageSpikes(true);
            // Disable platform
            _f2FirstPlatform.SetActive(false);
            // Wait some time
            yield return(new WaitForSeconds(2.0f));

            // Disable middle spike
            _f2MiddleSpikes.SetActive(false);
            // Reappear boss
            _spriteRenderer.enabled    = true;
            _capsuleCollider2D.enabled = true;
            //_attackSlider.gameObject.SetActive(true);
            //_healthSlider.gameObject.SetActive(true);
            // Change state
            _enemyState = EEnemyStates.DistanceAttack;
            // Change animator
            AnimatorStateInfo l_animatorStateInfo = _animator.GetCurrentAnimatorStateInfo(0);

            if (!l_animatorStateInfo.IsName("SamuraiHeavyBoss_Alert"))
            {
                _animator.SetTrigger("ToAlert");
            }
            // Recharge attack bar
            _attackSlider.normalizedValue = 1.0f;
            // Clear coroutine reference
            _f2SpikesReappearCoroutine = null;
        }
        public void AttackState()
        {
            // Get attack target position
            if (_attackTargetPosition == Vector3.zero)
            {
                float l_x =
                    _player.position.x > _f3RightLimit.position.x ?
                    _f3RightLimit.position.x :
                    (_player.position.x < _f3LeftLimit.position.x ? _f3LeftLimit.position.x : _player.position.x);
                float l_y = _f3LeftLimit.position.y;

                _attackTargetPosition = new Vector3(l_x, l_y, 0.0f);
                // Flip is needed
                if (transform.position.x < _attackTargetPosition.x && !_facingRight)
                {
                    FlipFacingDirection();
                }
                // Flip is needed
                if (transform.position.x > _attackTargetPosition.x && _facingRight)
                {
                    FlipFacingDirection();
                }
                // Play attack sound
                PlayRandomSound();
            }
            // Attack
            // Distance to move
            float l_dist = _flySpeed * Time.fixedDeltaTime;
            // Save boss previous position before moving
            Vector3 l_previousPosition = transform.position;

            // Move boss towards attack target position
            transform.position = Vector3.MoveTowards(transform.position, _attackTargetPosition, l_dist);
            // Check if boss has reached attack target position
            if (Mathf.Abs(transform.position.x - l_previousPosition.x) < 0.01f &&
                Mathf.Abs(transform.position.y - l_previousPosition.y) < 0.01f)
            {
                // Put boss on attack target position
                transform.position = _attackTargetPosition;
                // Put attack target position to zero
                _attackTargetPosition = Vector3.zero;
                // Change state
                _enemyState = EEnemyStates.None;
                // Loops left
                _loopsLeft--;
                // Attack bar
                _attackSlider.normalizedValue = (float)_loopsLeft / (float)_attackLoops;
                // Check loops left
                if (_loopsLeft == 0)
                {
                    // Change state
                    _enemyState = EEnemyStates.Idle;
                    // Enable animator
                    _animator.enabled = true;
                    _animator.SetTrigger("ToIdle");
                }
            }
        }
 /// <summary>
 ///     Gets called when boss hurt animations ends
 /// </summary>
 public void BossHurtEndAnimationEvent()
 {
     // Set flag
     _isHurt = false;
     // Manage flip
     //FlipFacingDirection();
     // Set run slashing loops left
     //_loopsLeft = _attackLoops;
     // Change state
     _enemyState = EEnemyStates.Alert;
     // Change boss fase
     if (_hitsLeft > 4)
     {
     }
     if (_hitsLeft <= 4 && _hitsLeft > 2)
     {
         if (_bossFase != EBossFases.Fase2)
         {
             // Change fase
             _bossFase = EBossFases.Fase2;
             // Change state
             _enemyState = EEnemyStates.None;
             // Start fase 1 to fase 2 coroutine
             _f1ToF2StateCoroutine = StartCoroutine(F1ToF2StateCoroutine());
         }
         else
         {
             // Change state
             _enemyState = EEnemyStates.None;
             // Start reappearing spikes
             _f2SpikesReappearCoroutine = StartCoroutine(F2SpikesReappearCoroutine());
         }
     }
     if (_hitsLeft <= 2 && _hitsLeft > 0)
     {
         if (_bossFase != EBossFases.Fase3)
         {
             // Change fase
             _bossFase = EBossFases.Fase3;
             // Change state
             _enemyState = EEnemyStates.None;
             // Start fase 2 to fase 3 coroutine
             _f2ToF3StateCoroutine = StartCoroutine(F2ToF3StateCoroutine());
         }
         else
         {
             // Change state
             _enemyState = EEnemyStates.None;
             // Start reappearing spikes
             _f3VanishReappearCoroutine = StartCoroutine(F3VanishReappearCoroutine());
         }
     }
     // Change animator state
     _animator.SetBool("IsHurt", false);
 }
        public void RunSlashingState()
        {
            // Set speed direction
            float l_runSpeed = _facingRight ? _runSpeed : _runSpeed * (-1.0f);

            // Move enemy
            transform.Translate(l_runSpeed * Time.fixedDeltaTime, 0.0f, 0.0f, Space.Self);
            // Whether the enemy is facing right or not...
            if (_facingRight)
            {
                // If right limit is reached
                if (transform.position.x > _f1RightLimit.position.x)
                {
                    // Put enemy in right limit position
                    transform.position = new Vector3(_f1RightLimit.position.x, transform.position.y, transform.position.z);
                    // Set remaining lopps
                    _loopsLeft--;
                    // Set attack slider value
                    _attackSlider.normalizedValue = (float)_loopsLeft / (float)_attackLoops;
                    // If remaining loops are 0
                    if (_loopsLeft == 0)
                    {
                        // Change state
                        _enemyState = EEnemyStates.Idle;
                        // Change animator state
                        _animator.SetTrigger("ToIdle");
                        // Cancel sound invoking
                        CancelInvoke("PlayRandomSound");

                        return;
                    }
                    // Manage flip
                    FlipFacingDirection();
                }
            }
            else
            {
                // If left limit is reached
                if (transform.position.x < _f1LeftLimit.position.x)
                {
                    // Put enemy in left limit position
                    transform.position = new Vector3(_f1LeftLimit.position.x, transform.position.y, transform.position.z);
                    // Manage flip
                    FlipFacingDirection();
                }
            }
            // Invoke attack sounds
            if (!IsInvoking("PlayRandomSound"))
            {
                InvokeRepeating("PlayRandomSound", 0.1f, 1.5f);
            }
        }
 /// <summary>
 ///     Gets called when enemy hurt animations ends
 /// </summary>
 public void EnemyHurtEndAnimationEvent()
 {
     // Set flag
     _isHurt = false;
     // Manage flip
     FlipFacingDirection();
     // Set run slashing loops left
     _loopsLeft = _attackLoops;
     // Change state
     _enemyState = EEnemyStates.RunSlash;
     // Change animator state
     _animator.SetBool("IsHurt", false);
 }
        /// <summary>
        ///     Boss takes hit
        /// </summary>
        public void TakeDamage(int damage)
        {
            // Only hurt boss when in idle state
            if (_enemyState != EEnemyStates.Idle)
            {
                return;
            }

            // Take damage
            _hitsLeft--;

            // Set health slider
            _healthSlider.normalizedValue = (float)_hitsLeft / (float)_maxHits;

            // Cancel coroutine
            if (_idleStateCoroutine != null)
            {
                StopCoroutine(_idleStateCoroutine);

                _idleStateCoroutine = null;
            }

            // Manage state depending on remaining health
            if (_hitsLeft == 0)
            {
                // Attack bar
                _attackSlider.normalizedValue = 0.0f;
                // Disable collider
                _capsuleCollider2D.enabled = false;
                // Change state
                _enemyState = EEnemyStates.Dead;
                // Change animator state
                _animator.SetTrigger("IsDead");
                // Play dead sound
                _audioSource.PlayOneShot(_deathAudioClip);
            }
            else
            {
                // Set flag
                _isHurt = true;
                // Change state
                _enemyState = EEnemyStates.Hurt;
                // Change animator state
                _animator.SetBool("IsHurt", true);
                // Play damage sound
                PlayRandomSound();
            }
        }
        /// <summary>
        ///     Idle state coroutine waits for a period of time
        /// </summary>
        /// <returns>The reference to the coroutine</returns>
        private IEnumerator IdleStateCoroutine()
        {
            // stay sometime in idle state before changing to run slashing
            yield return(new WaitForSeconds(_idleTime));

            // Manage flip
            FlipFacingDirection();
            // Set run slashing loops left
            _loopsLeft = _attackLoops;
            // Change state
            _enemyState = EEnemyStates.RunSlash;
            // Change animator state
            _animator.SetTrigger("ToRunSlashing");
            // Set variable to null
            _idleStateCoroutine = null;
        }
        /// <summary>
        ///     Enemy takes damage
        /// </summary>
        /// <param name="damage">Damage</param>
        public void TakeDamage(int damage)
        {
            // Only hurt enemy when in idle state
            if (_enemyState != EEnemyStates.Idle)
            {
                return;
            }

            // Take damage
            _health = _health - damage < 0 ? 0 : _health - damage;

            // Set health slider
            _healthSlider.normalizedValue = (float)_health / (float)_maxHealth;

            // Cancel coroutine
            if (_idleStateCoroutine != null)
            {
                StopCoroutine(_idleStateCoroutine);

                _idleStateCoroutine = null;
            }

            // Manage state depending on remaining health
            if (_health == 0)
            {
                // Disable collider
                _capsuleCollider2D.enabled = false;
                // Change state
                _enemyState = EEnemyStates.Dead;
                // Change animator state
                _animator.SetTrigger("IsDead");
                // Play dead sound
                _audioSource.PlayOneShot(_audioClipDead);
            }
            else
            {
                // Set flag
                _isHurt = true;
                // Change state
                _enemyState = EEnemyStates.Hurt;
                // Change animator state
                _animator.SetBool("IsHurt", true);
                // Play damage sound
                _audioSource.PlayOneShot(_audioClipDamage);
            }
        }
Esempio n. 10
0
        /// <summary>
        ///     Waits between attack fases in F3
        /// </summary>
        /// <returns>The reference to the coroutine</returns>
        private IEnumerator F3WaitBetweenAttackFasesCoroutine(float waitTime)
        {
            // Enable animator
            _animator.enabled = true;
            // Wait some time
            yield return(new WaitForSeconds(waitTime));

            // Rebind and disable animator
            _animator.Rebind();
            _animator.enabled = false;
            // Change sprite
            _spriteRenderer.sprite = _f3AttackSprite;
            // Change state
            _enemyState = EEnemyStates.Attack;
            // Clear coroutine reference
            _f3WaitBetweenAttackFasesCoroutine = null;
        }
        /// <summary>
        ///     Run slashing state
        /// </summary>
        private void RunSlashingState()
        {
            // Set speed direction
            float l_runSpeed = _facingRight ? _runSpeed : _runSpeed * (-1.0f);

            // Move enemy
            transform.Translate(l_runSpeed * Time.fixedDeltaTime, 0.0f, 0.0f, Space.Self);
            // Whether the enemy is facing right or not...
            if (_facingRight)
            {
                // If right limit is reached
                if (transform.position.x > _rightLimit.position.x)
                {
                    // Put enemy in right limit position
                    transform.position = new Vector3(_rightLimit.position.x, transform.position.y, transform.position.z);
                    // Set remaining lopps
                    _loopsLeft--;
                    // If remaining loops are 0
                    if (_loopsLeft == 0)
                    {
                        // Change state
                        _enemyState = EEnemyStates.Idle;
                        // Change animator state
                        _animator.SetTrigger("ToIdle");

                        return;
                    }
                    // Manage flip
                    FlipFacingDirection();
                }
            }
            else
            {
                // If left limit is reached
                if (transform.position.x < _leftLimit.position.x)
                {
                    // Put enemy in left limit position
                    transform.position = new Vector3(_leftLimit.position.x, transform.position.y, transform.position.z);
                    // Manage flip
                    FlipFacingDirection();
                }
            }
        }
Esempio n. 12
0
        /// <summary>
        ///     Makes boss vanish and reappear in F3
        /// </summary>
        /// <returns>The reference to the coroutine</returns>
        private IEnumerator F3VanishReappearCoroutine()
        {
            // Change animator state
            _animator.SetTrigger("ToAlert");
            // Make boss vanish
            yield return(StartCoroutine(MakeBossVanish(_bossVanishTime)));

            // Rebind and disable animator
            _animator.Rebind();
            _animator.enabled = false;
            // Change to attack sprite
            _spriteRenderer.sprite = _f3AttackSprite;
            // Choose random reappear position
            transform.position = RandomReappearPosition();
            // Flip is needed
            if (transform.position.x > 0.0f && _facingRight)
            {
                FlipFacingDirection();
            }
            if (transform.position.x < 0.0f && !_facingRight)
            {
                FlipFacingDirection();
            }
            // Boss levitation move
            if (_f3LevitationMove == null)
            {
                _f3LevitationMove = StartCoroutine(F3LevitationMove());
            }
            // Make boss reappear
            yield return(StartCoroutine(MakeBossReappear(_bossVanishTime)));

            // Change state
            _enemyState = EEnemyStates.Alert;
            // Clear coroutine reference
            _f3VanishReappearCoroutine = null;
        }
Esempio n. 13
0
        /// <summary>
        ///     F2 Vertical attack coroutine
        /// </summary>
        /// <returns>The reference to the coroutine</returns>
        private IEnumerator F2VerticalKunaiCoroutine()
        {
            float l_waitedTime = 0.0f;

            while (l_waitedTime < _f2DistanceAttackTime)
            {
                GameObject l_verticalKunai = Instantiate(_kunaiPrefab, GameManager.Instance.PrefabContainer);

                l_verticalKunai.transform.position = new Vector3(_player.position.x, _f2KunaiSpawnerPosition.position.y, 0.0f);
                l_verticalKunai.transform.Rotate(0.0f, 0.0f, -90.0f, Space.Self);

                l_waitedTime += _f2VerticalKunaiAttackDeltaTime;

                _attackSlider.normalizedValue = Mathf.Clamp01(1.0f - l_waitedTime / _f2DistanceAttackTime);

                yield return(new WaitForSeconds(_f2VerticalKunaiAttackDeltaTime));
            }
            // Change state
            _enemyState = EEnemyStates.Idle;
            // Change animator
            _animator.SetTrigger("ToIdle");
            // Clear coroutine reference
            _f2VerticalKunaiCoroutine = null;
        }
Esempio n. 14
0
        /// <summary>
        ///     Changes from Fase 2 to Fase 3
        /// </summary>
        /// <returns>The reference to the coroutine</returns>
        private IEnumerator F2ToF3StateCoroutine()
        {
            // Make boss vanish
            yield return(StartCoroutine(MakeBossVanish(_bossVanishTime)));

            // Disable spikes colliders
            ManageSpikesCollidersTriggers(false);
            // Disable platform
            _f2FirstPlatform.SetActive(false);
            // Reappearing process
            float l_iter = 0;

            // Process
            while (l_iter < _f2SpikesReappearTimes)
            {
                // Enable spikes
                ManageSpikes(true);

                yield return(new WaitForSeconds(0.75f));

                // Disable spikes
                ManageSpikes(false);

                yield return(new WaitForSeconds(0.25f));

                l_iter++;
            }
            // Enable spikes colliders
            ManageSpikesCollidersTriggers(true);
            // Enable spikes
            ManageSpikes(true);
            // Wait some time
            yield return(new WaitForSeconds(2.0f));

            // Disable spikes
            ManageSpikes(false);
            // Disable other platforms
            for (int i = 0; i < _f2OtherPlatforms.Length; i++)
            {
                _f2OtherPlatforms[i].SetActive(false);
            }
            // Wait some time
            yield return(new WaitForSeconds(2.0f));

            // Rebind and disable animator
            _animator.Rebind();
            _animator.enabled = false;
            // Change to attack sprite
            _spriteRenderer.sprite = _f3AttackSprite;
            // Choose random reappear position
            transform.position = RandomReappearPosition();
            // Flip is needed
            if (transform.position.x > 0.0f)
            {
                FlipFacingDirection();
            }
            // Boss levitation move
            if (_f3LevitationMove == null)
            {
                _f3LevitationMove = StartCoroutine(F3LevitationMove());
            }
            // Make boss reappear
            yield return(StartCoroutine(MakeBossReappear(_bossVanishTime)));

            // Change state
            _enemyState = EEnemyStates.Alert;
            // Clear coroutine reference
            _f2ToF3StateCoroutine = null;
        }
Esempio n. 15
0
        /// <summary>
        ///     Idle state F1 coroutine waits for a period of time
        /// </summary>
        /// <returns>The reference to the coroutine</returns>
        private IEnumerator IdleStateCoroutine()
        {
            // Before waiting
            switch (_bossFase)
            {
            case EBossFases.Fase1:
                break;

            case EBossFases.Fase2:
            {
                // Disable spikes
                _f2LeftSpikes.SetActive(false);
                _f2RightSpikes.SetActive(false);
                _f2LeftPlatformSpikes.SetActive(false);
                _f2RightPlatformSpikes.SetActive(false);
                // Enable platform
                _f2FirstPlatform.SetActive(true);
            }
            break;

            case EBossFases.Fase3:
                break;

            default:
                break;
            }
            // Set attack slider value to 0
            _attackSlider.normalizedValue = 0.0f;
            // stay sometime in idle state before changing to run slashing
            // Recharge attack bar
            float l_waitedTime = 0.0f;
            float l_idleTime   = _bossFase == EBossFases.Fase1 ? _f1IdleTime : (_bossFase == EBossFases.Fase2 ? _f2IdleTime : _f3IdleTime);

            while (l_waitedTime < l_idleTime)
            {
                yield return(new WaitForSeconds(0.1f));

                l_waitedTime += 0.1f;

                if (l_waitedTime > l_idleTime)
                {
                    l_waitedTime = l_idleTime;
                }

                _attackSlider.normalizedValue = l_waitedTime / l_idleTime;
            }

            //
            switch (_bossFase)
            {
            case EBossFases.Fase1:
            {
                // Manage flip
                FlipFacingDirection();
                // Set run slashing loops left
                _loopsLeft = _attackLoops;
                // Change state and animator
                _enemyState = EEnemyStates.RunSlash;
                _animator.SetTrigger("ToRunSlashing");
            }
            break;

            case EBossFases.Fase2:
            {
                // Change state
                _enemyState = EEnemyStates.None;
                // Start spikes reappearing
                _f2SpikesReappearCoroutine = StartCoroutine(F2SpikesReappearCoroutine());
            }
            break;

            case EBossFases.Fase3:
            {
                // Change state
                _enemyState = EEnemyStates.None;
                // Start spikes reappearing
                _f3VanishReappearCoroutine = StartCoroutine(F3VanishReappearCoroutine());
            }
            break;

            default:
                break;
            }
            // Clear coroutine reference
            _idleStateCoroutine = null;
        }
Esempio n. 16
0
        /// <summary>
        ///     Alert state coroutine waits for a period of time
        /// </summary>
        /// <returns>The reference to the coroutine</returns>
        private IEnumerator AlertStateCoroutine()
        {
            // Before waiting
            switch (_bossFase)
            {
            case EBossFases.Fase1:
                break;

            case EBossFases.Fase2:
            {
                // Enable spikes
                _f2LeftSpikes.SetActive(true);
                _f2RightSpikes.SetActive(true);
                _f2LeftPlatformSpikes.SetActive(true);
                _f2RightPlatformSpikes.SetActive(true);
                // Disable platform
                _f2FirstPlatform.SetActive(false);
            }
            break;

            case EBossFases.Fase3:
                break;

            default:
                break;
            }
            // Set attack slider value to 0
            _attackSlider.normalizedValue = 0.0f;
            // Enable particle system
            _rechargeAttackPSFX.SetActive(true);
            // Stay sometime in alert state before changing to next state and recharge atack bar
            float l_waitedTime = 0.0f;
            float l_alertTime  = _bossFase == EBossFases.Fase1 ? _f1AlertTime : (_bossFase == EBossFases.Fase2 ? _f2AlertTime : _f3AlertTime);

            while (l_waitedTime < l_alertTime)
            {
                yield return(new WaitForSeconds(0.1f));

                l_waitedTime += 0.1f;

                if (l_waitedTime > l_alertTime)
                {
                    l_waitedTime = l_alertTime;
                }

                _attackSlider.normalizedValue = l_waitedTime / l_alertTime;
            }
            // Disable particle system
            _rechargeAttackPSFX.SetActive(false);
            //
            switch (_bossFase)
            {
            case EBossFases.Fase1:
            {
                // Manage flip
                FlipFacingDirection();
                // Set run slashing loops left
                _loopsLeft = _attackLoops;
                // Change state and animator
                _enemyState = EEnemyStates.RunSlash;
                _animator.SetTrigger("ToRunSlashing");
            }
            break;

            case EBossFases.Fase2:
            {
                // Change state
                _enemyState = EEnemyStates.DistanceAttack;
            }
            break;

            case EBossFases.Fase3:
            {
                // Set attack loops left
                _loopsLeft = _attackLoops;
                // Change state
                _enemyState = EEnemyStates.Attack;
                // Stop boss levitation move
                StopCoroutine(_f3LevitationMove);
                _f3LevitationMove = null;
            }
            break;

            default:
                break;
            }
            // Clear coroutine reference
            _alertStateCoroutine = null;
        }