IEnumerator ReloadRoutine()
    {
        hasAttackInterruptReload = false;
        if (!isReloading && CurrentEquippedWeapon.CanReload())
        {
            isReloading = true;
            if (WeaponData != null)
            {
                reloadDuration  = WeaponData.reloadDuration;
                startReloadTime = Time.unscaledTime;
                if (WeaponData.clipOutFx != null && AudioManager.Singleton != null)
                {
                    AudioSource.PlayClipAtPoint(WeaponData.clipOutFx, TempTransform.position, AudioManager.Singleton.sfxVolumeSetting.Level);
                }
                yield return(new WaitForSeconds(reloadDuration));

                if (isServer)
                {
                    var equippedWeapon = CurrentEquippedWeapon;
                    equippedWeapon.Reload();
                    equippedWeapons[selectWeaponIndex] = equippedWeapon;
                    equippedWeapons.Dirty(selectWeaponIndex);
                }
                if (WeaponData.clipInFx != null && AudioManager.Singleton != null)
                {
                    AudioSource.PlayClipAtPoint(WeaponData.clipInFx, TempTransform.position, AudioManager.Singleton.sfxVolumeSetting.Level);
                }
            }
            // If player still attacking, random new attacking action id
            if (isServer && attackingActionId >= 0 && WeaponData != null)
            {
                attackingActionId = WeaponData.GetRandomAttackAnimation().actionId;
            }
            yield return(new WaitForEndOfFrame());

            isReloading = false;
            if (isLocalPlayer)
            {
                // If weapon is reload one ammo at a time (like as shotgun), automatically reload more bullets
                // When there is no attack interrupt while reload
                if (WeaponData != null && WeaponData.reloadOneAmmoAtATime && CurrentEquippedWeapon.CanReload())
                {
                    if (!hasAttackInterruptReload)
                    {
                        Reload();
                    }
                    else
                    {
                        Attack();
                    }
                }
            }
        }
    }
 public void CmdAttack()
 {
     if (WeaponData != null)
     {
         attackingActionId = WeaponData.GetRandomAttackAnimation().actionId;
     }
     else
     {
         attackingActionId = -1;
     }
 }
    IEnumerator AttackRoutine(int actionId)
    {
        if (!isPlayingAttackAnim &&
            !isReloading &&
            CurrentEquippedWeapon.CanShoot() &&
            Hp > 0 &&
            characterModel != null &&
            characterModel.TempAnimator != null)
        {
            isPlayingAttackAnim = true;
            var             animator = characterModel.TempAnimator;
            AttackAnimation attackAnimation;
            if (WeaponData != null &&
                WeaponData.AttackAnimations.TryGetValue(actionId, out attackAnimation))
            {
                // Play attack animation
                animator.SetBool("DoAction", false);
                yield return(new WaitForEndOfFrame());

                animator.SetBool("DoAction", true);
                animator.SetInteger("ActionID", attackAnimation.actionId);

                // Wait to launch damage entity
                var speed             = attackAnimation.speed;
                var animationDuration = attackAnimation.animationDuration;
                var launchDuration    = attackAnimation.launchDuration;
                if (launchDuration > animationDuration)
                {
                    launchDuration = animationDuration;
                }
                yield return(new WaitForSeconds(launchDuration / speed));

                // Launch damage entity on server only
                if (isServer)
                {
                    WeaponData.Launch(this, attackAnimation.isAnimationForLeftHandWeapon);
                    var equippedWeapon = CurrentEquippedWeapon;
                    equippedWeapon.DecreaseAmmo();
                    equippedWeapons[selectWeaponIndex] = equippedWeapon;
                    equippedWeapons.Dirty(selectWeaponIndex);
                }

                // Random play shoot sounds
                if (WeaponData.attackFx != null && WeaponData.attackFx.Length > 0 && AudioManager.Singleton != null)
                {
                    AudioSource.PlayClipAtPoint(WeaponData.attackFx[Random.Range(0, WeaponData.attackFx.Length - 1)], TempTransform.position, AudioManager.Singleton.sfxVolumeSetting.Level);
                }

                // Wait till animation end
                yield return(new WaitForSeconds((animationDuration - launchDuration) / speed));
            }
            // If player still attacking, random new attacking action id
            if (isServer && attackingActionId >= 0 && WeaponData != null)
            {
                attackingActionId = WeaponData.GetRandomAttackAnimation().actionId;
            }
            yield return(new WaitForEndOfFrame());

            // Attack animation ended
            animator.SetBool("DoAction", false);
            isPlayingAttackAnim = false;
        }
    }
Beispiel #4
0
    protected override void UpdateMovements()
    {
        if (!isServer)
        {
            return;
        }

        if (GameNetworkManager.Singleton.numPlayers <= 0)
        {
            TempRigidbody.velocity = new Vector3(0, TempRigidbody.velocity.y, 0);
            attackingActionId      = -1;
            return;
        }

        if (Hp <= 0)
        {
            ServerRespawn(false);
            TempRigidbody.velocity = new Vector3(0, TempRigidbody.velocity.y, 0);
            return;
        }
        // Bots will update target movement when reached move target / hitting the walls / it's time
        if (isWallHit || Time.unscaledTime - lastUpdateMovementTime >= updateMovementDuration)
        {
            lastUpdateMovementTime = Time.unscaledTime;
            targetPosition         = new Vector3(
                TempTransform.position.x + Random.Range(-randomMoveDistance, randomMoveDistance),
                0,
                TempTransform.position.z + Random.Range(-randomMoveDistance, randomMoveDistance));
            isWallHit = false;
        }

        var             rotatePosition = targetPosition;
        CharacterEntity enemy;

        if (FindEnemy(out enemy))
        {
            if (characteristic == Characteristic.Normal)
            {
                if (Time.unscaledTime - lastAttackTime >= attackDuration)
                {
                    if (CurrentEquippedWeapon.currentReserveAmmo > 0)
                    {
                        if (CurrentEquippedWeapon.currentAmmo == 0)
                        {
                            ServerReload();
                        }
                        else if (attackingActionId < 0)
                        {
                            attackingActionId = WeaponData.GetRandomAttackAnimation().actionId;
                        }
                    }
                    else
                    {
                        if (WeaponData != null)
                        {
                            var nextPosition = WeaponData.equipPosition + 1;
                            if (nextPosition < equippedWeapons.Count && !equippedWeapons[nextPosition].IsEmpty())
                            {
                                ServerChangeWeapon(nextPosition);
                            }
                        }
                        else
                        {
                            ServerChangeWeapon(selectWeaponIndex + 1);
                        }
                    }
                }
                else if (attackingActionId >= 0)
                {
                    attackingActionId = -1;
                }
            }
            else if (attackingActionId >= 0)
            {
                attackingActionId = -1;
            }
            rotatePosition = enemy.TempTransform.position;
        }
        else if (attackingActionId >= 0)
        {
            attackingActionId = -1;
        }

        // Gets a vector that points from the player's position to the target's.
        if (!IsReachedTargetPosition())
        {
            Move((targetPosition - TempTransform.position).normalized);
        }
        if (IsReachedTargetPosition())
        {
            targetPosition         = TempTransform.position + (TempTransform.forward * ReachedTargetDistance / 2f);
            TempRigidbody.velocity = new Vector3(0, TempRigidbody.velocity.y, 0);
        }
        // Rotate to target
        var rotateHeading  = rotatePosition - TempTransform.position;
        var targetRotation = Quaternion.LookRotation(rotateHeading);

        TempTransform.rotation = Quaternion.Lerp(TempTransform.rotation, Quaternion.Euler(0, targetRotation.eulerAngles.y, 0), Time.deltaTime * turnSpeed);
    }