/// <summary> /// Mage player's primary attack /// </summary> protected override void PrimaryAttack() { // Ensure player has enough mana to perform this attack if ((Stats as PlayerStatsController).mana.CurrentValue < 1f) { // Stop attack if not enough mana _isPrimaryActive = false; Anim.SetBool("PrimaryAttack", false); AudioHelper.StopAudio(WeaponAudio); (Stats as PlayerStatsController).mana.StartRegen(); Motor.ResetMovementModifier(); return; } (Stats as PlayerStatsController).mana.Subtract(primaryAttackManaDepletion * Time.deltaTime); ResetTakeDamageAnim(); Vector3 vfxPos = transform.position + transform.forward * 1.5f + new Vector3(0, 2f); StartCoroutine(VfxHelper.CreateVFX(primaryVFX, vfxPos, transform.rotation)); // Check all enemies within attack radius of the player List <Transform> enemies = GetSurroundingEnemies(primaryAttackRadius); // Attack any enemies within the attack sweep and range foreach (var enemy in enemies.Where(enemy => CanDamageTarget(enemy, primaryAttackRadius, primaryAttackSweepAngle))) { float damageValue = Random.Range(primaryAttackMinDamage, primaryAttackMaxDamage + Stats.damage.GetValue()); enemy.GetComponent <EntityStatsController>().TakeDamage(Stats, damageValue, Time.deltaTime); } }
/// <summary> /// Mage player's primary attack /// </summary> protected override void PrimaryAttack() { // Ensure player has enough mana to perform this attack if ((Stats as PlayerStatsController).mana.CurrentValue < 1f) { // Stop attack if not enough mana ReleaseChargedAttack(); return; } (Stats as PlayerStatsController).mana.Subtract(primaryAttackManaDepletion * Time.deltaTime); Vector3 vfxPos = transform.position + transform.forward * 1.6f + new Vector3(0, 2f); StartCoroutine(VfxHelper.CreateVFX(primaryVFX, vfxPos, transform.rotation)); // Check all enemies within attack radius of the player List <Transform> enemies = GetSurroundingEnemies(primaryAttackRadius); float baseDamage = Stats.damage.GetValue(); float damageValue = Random.Range(primaryAttackMinDamage + baseDamage, primaryAttackMaxDamage + baseDamage); // Attack any enemies within the attack sweep and range foreach (var enemy in enemies.Where(enemy => CanDamageTarget(enemy, primaryAttackRadius, primaryAttackSweepAngle))) { enemy.GetComponent <EntityStatsController>().TakeDamage(Stats, damageValue, Time.deltaTime); } }
/// <summary> /// Mage player's secondary attack /// </summary> protected override void SecondaryAttack() { // Ensure player has enough mana to perform this attack if (AttackCooldown > 0 || (Stats as PlayerStatsController).mana.CurrentValue < secondaryAttackManaDepletion) { return; } StartCoroutine(VfxHelper.CreateVFX(secondaryVFX, transform.position + new Vector3(0, 0.01f, 0), Quaternion.identity, PlayerManager.colours.GetColour(Stats.characterColour))); // Check all enemies within attack radius of the player List <Transform> enemies = GetSurroundingEnemies(secondaryAttackRadius); // Attack any enemies within the AOE range foreach (var enemy in enemies) { StartCoroutine(PerformExplosiveDamage(enemy.GetComponent <EntityStatsController>(), secondaryAttackMaxDamage, secondaryAttackStunTime, secondaryAttackExplosionForce, transform.position, secondaryAttackRadius, secondaryAttackDamageDelay)); } // Trigger secondary attack animation Anim.SetTrigger("SecondaryAttack"); // Play the attack audio StartCoroutine(AudioHelper.PlayAudioOverlap(WeaponAudio, secondaryAttackWeaponSFX)); // Reset attack timeout and deplete mana AttackCooldown = secondaryAttackTimeout; (Stats as PlayerStatsController).mana.Subtract(secondaryAttackManaDepletion); // Apply movement speed modifier StartCoroutine(Motor.ApplyTimedMovementModifier(secondaryAttackMovementModifier, secondaryAttackTimeout)); }
/// <summary> /// Lich's spell cast attack /// </summary> public override void SecondaryAttack() { // Calculate direction to attack in relative to staff position Vector3 direction = secondaryAttackVFXRoot.up; direction.y = 0f; Vector3 position = secondaryAttackVFXRoot.position; position.y = 1f; // Spawn VFX from staff and in the direction its pointing Vector3 vfxPos = position + direction * 0.5f + new Vector3(0, 2f); StartCoroutine(VfxHelper.CreateVFX(secondaryAttackVFX, vfxPos, Quaternion.LookRotation(direction))); // Calculate the hit raycast from closer to the enemy, in the direction of the staff Vector3 raycastPos = position - direction * 2.5f; int numHits = Physics.RaycastNonAlloc(raycastPos, direction, _hitBuffer, secondaryAttackRadius); float damageValue = Random.Range(secondaryAttackMinDamage, secondaryAttackMaxDamage) + Stats.damage.GetValue(); // Damage any players hit by the raycast for (int i = 0; i < numHits; i++) { if (_hitBuffer[i].transform.tag.Equals("Player")) { _hitBuffer[i].transform.GetComponent <EntityStatsController>().TakeDamage(Stats, damageValue, Time.deltaTime); } } }
/// <summary> /// Melee's secondary attack /// </summary> protected override void SecondaryAttack() { // Ensure player has enough mana to perform this attack if (AttackCooldown > 0 || (Stats as PlayerStatsController).mana.CurrentValue < secondaryAttackManaDepletion) { return; } StartCoroutine(VfxHelper.CreateVFX(secondaryVFX, transform.position + new Vector3(0, 0.01f, 0), transform.rotation, PlayerManager.colours.GetColour(Stats.characterColour), secondaryAttackDamageDelay)); // Check all enemies within attack radius of the player List <Transform> enemies = GetSurroundingEnemies(secondaryAttackRadius); // Attack any enemies within the attack sweep and range foreach (var enemy in enemies.Where(enemy => CanDamageTarget(enemy, secondaryAttackRadius, secondaryAttackSweepAngle))) { // Calculate and perform damage float damageValue = Random.Range(secondaryAttackMinDamage, secondaryAttackMaxDamage + Stats.damage.GetValue()); StartCoroutine(PerformDamage(enemy.GetComponent <EntityStatsController>(), damageValue, secondaryAttackDamageDelay)); } // Trigger secondary attack animation Anim.SetTrigger("SecondaryAttack"); // Play the attack audio StartCoroutine(AudioHelper.PlayAudioOverlap(WeaponAudio, secondaryAttackWeaponSFX)); // Reset attack timeout and deplete mana AttackCooldown = secondaryAttackTimeout; (Stats as PlayerStatsController).mana.Subtract(secondaryAttackManaDepletion); // Apply movement speed modifier StartCoroutine(Motor.ApplyTimedMovementModifier(secondaryAttackMovementModifier, secondaryAttackTimeout)); }
private void Start() { // Assign enemy a colour if (characterColour == CharacterColour.None) { AssignEnemyColour(characterColour); } // Create a VFX where the enemy will spawn - just slightly above the stage (0.1f) - and change the VFX colour to match the enemy colour StartCoroutine(VfxHelper.CreateVFX(spawnVFX, transform.position + new Vector3(0, 0.01f, 0), Quaternion.identity, PlayerManager.colours.GetColour(characterColour), 0.5f)); // "Spawn" the enemy (they float up through the stage) StartCoroutine(Spawn(gameObject, spawnSpeed, spawnDelay, spawnCooldown)); }
private void Start() { Color playerColour = PlayerManager.colours.GetColour(characterColour); // colour the player's weapon AssignWeaponColour(gameObject, playerColour); if (shouldSpawn) { // Create a VFX where the player will spawn - just slightly above the stage (0.1f) - and change the VFX colour to match the player colour StartCoroutine(VfxHelper.CreateVFX(spawnVFX, transform.position + new Vector3(0, 0.01f, 0), Quaternion.identity, playerColour, 0.5f)); // "Spawn" the player (they float up through the stage) StartCoroutine(Spawn(gameObject, spawnSpeed, spawnDelay, spawnCooldown)); } }
private void Start() { playerInput = GetComponent <PlayerInput>(); Color playerColour = PlayerManager.colours.GetColour(characterColour); // colour the player's weapon AssignWeaponColour(gameObject, playerColour); // Scale player damage based on number of levels cleared damage.AddModifier(LevelManager.Instance.GetNumLevelsCleared()); if (shouldSpawn) { // Create a VFX where the player will spawn - just slightly above the stage (0.1f) - and change the VFX colour to match the player colour StartCoroutine(VfxHelper.CreateVFX(spawnVFX, transform.position + new Vector3(0, 0.01f, 0), Quaternion.identity, playerColour, 0.5f)); // "Spawn" the player (they float up through the stage) StartCoroutine(Spawn(gameObject, spawnSpeed, spawnDelay, spawnCooldown)); } }
protected override void Update() { base.Update(); // Handle attack charge ups if (_isPrimaryCharging) { _primaryChargeTime += Time.deltaTime; if (_primaryChargeTime >= primaryAttackChargeTime) { if (!_sparkleShown) { StartCoroutine(VfxHelper.CreateVFX(sparkleVFX, transform.position + transform.forward * 1.6f + new Vector3(0, 2f, 0), transform.rotation)); StartCoroutine(AudioHelper.PlayAudioOverlap(WeaponAudio, sparkleSFX)); _sparkleShown = true; } // Clamp to max charge time _primaryChargeTime = primaryAttackChargeTime; } } }
/// <summary> /// Enemy boss's tertiary attack /// </summary> public override void TertiaryAttack() { if (AttackCooldown > 0f) { return; } Anim.SetTrigger("TertiaryAttack"); // audio StartCoroutine(AudioHelper.PlayAudioOverlap(WeaponAudio, tertiaryAttackSFX)); StartCoroutine(VfxHelper.CreateVFX(tertiaryAttackVFX, gameObject.transform.position + new Vector3(0, 1f, 0), gameObject.transform.rotation, PlayerManager.colours.GetColour(Stats.characterColour), tertiaryAttackDelay * 0.5f)); // Attack any enemies within the attack sweep and range foreach (GameObject player in Players.Where(player => CanDamageTarget(player.transform.position, attackRadius, attackAngle))) { // Calculate and perform damage StartCoroutine(PerformDamage(player.GetComponent <EntityStatsController>(), Stats.ComputeDamageModifer(), tertiaryAttackDelay * 0.5f)); } AttackCooldown = tertiaryAttackCooldown; }
private void UpdateRespawnPercentage(bool playersOnBeacon) { if (playersOnBeacon) { respawnPercentage += respawnRate; if (respawnPercentage >= 100f) { playerStatsController.Respawn(); StartCoroutine(VfxHelper.CreateVFX(respawnEffectPrefab, transform.position + new Vector3(0, 0.01f, 0), Quaternion.identity, PlayerManager.colours.GetColour(playerStatsController.characterColour))); Destroy(gameObject); } } else { respawnPercentage = Mathf.Max(0, respawnPercentage - 2f * respawnRate); if (respawnPercentage <= 0) { text.text = reviveText; return; } } text.text = respawnPercentage.ToString("N0") + "%"; }