589 lines
23 KiB
C#
589 lines
23 KiB
C#
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace BulletHellTemplate
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Represents the data for a skill.
|
||
|
/// </summary>
|
||
|
[CreateAssetMenu(fileName = "NewSkillData", menuName = "Skill Data", order = 51)]
|
||
|
public partial class SkillData : ScriptableObject
|
||
|
{
|
||
|
// -------------------------
|
||
|
// 1) SKILL DETAILS
|
||
|
// -------------------------
|
||
|
[Header("Skill Details")]
|
||
|
[Tooltip("Icon representing the skill.")]
|
||
|
public Sprite icon;
|
||
|
|
||
|
[Tooltip("Icon representing the evolved skill.")]
|
||
|
public Sprite iconEvolved;
|
||
|
|
||
|
[Tooltip("Frame used when the skill is evolved.")]
|
||
|
public Sprite frameEvolved;
|
||
|
|
||
|
[Tooltip("Name of the skill.")]
|
||
|
public string skillName;
|
||
|
|
||
|
public NameTranslatedByLanguage[] skillNameTranslated;
|
||
|
|
||
|
[Tooltip("Description of the skill.")]
|
||
|
public string skillDescription;
|
||
|
|
||
|
public DescriptionTranslatedByLanguage[] skillDescriptionTranslated;
|
||
|
|
||
|
[Tooltip("Type of damage dealt by the skill.")]
|
||
|
public CharacterTypeData damageType;
|
||
|
|
||
|
[Tooltip("Cooldown time between skill uses.")]
|
||
|
public int cooldown;
|
||
|
|
||
|
[Tooltip("Delay before the skill is launched.")]
|
||
|
public float delayToLaunch = 0.3f;
|
||
|
|
||
|
[Tooltip("Set a value above zero if you want the character to stop moving for a period of time.")]
|
||
|
public float delayToMove = 0;
|
||
|
|
||
|
[Tooltip("Check if you want the character to be able to turn while standing still.")]
|
||
|
public bool canRotateWhileStopped;
|
||
|
|
||
|
[Tooltip("Time to wait before allowing auto-attack after using this skill.")]
|
||
|
public float autoAttackDelay = 1.0f;
|
||
|
|
||
|
[Tooltip("Does it cost mana to use an ability?")]
|
||
|
public float manaCost = 0;
|
||
|
|
||
|
public AimType AimMode = AimType.InputDirection;
|
||
|
|
||
|
[Tooltip("Default DamageEntity prefab.")]
|
||
|
public DamageEntity damageEntityPrefab;
|
||
|
|
||
|
// -------------------------
|
||
|
// 2) EFFECTS
|
||
|
// -------------------------
|
||
|
[Header("Effects")]
|
||
|
[Tooltip("Effect to spawn when the skill is activated.")]
|
||
|
public GameObject spawnEffect;
|
||
|
|
||
|
[Tooltip("Duration of the spawn effect.")]
|
||
|
public float effectDuration;
|
||
|
|
||
|
[Tooltip("Audio clip to play when the skill is activated.")]
|
||
|
public AudioClip spawnAudio;
|
||
|
|
||
|
public bool playSpawnAudioEaShot;
|
||
|
|
||
|
[Tooltip("Audio clip to play when the skill is in action.")]
|
||
|
public AudioClip skillAudio;
|
||
|
|
||
|
public bool playSkillAudioEaShot;
|
||
|
|
||
|
[Tooltip("Delay before playing the skill audio.")]
|
||
|
public float playSkillAudioAfter = 0.15f;
|
||
|
|
||
|
// -------------------------
|
||
|
// 3) SKILL SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Skill Settings")]
|
||
|
[Tooltip("Type of range indicator to display.")]
|
||
|
public RangeIndicatorType rangeIndicatorType = RangeIndicatorType.None;
|
||
|
|
||
|
[Tooltip("Settings for the radial range indicator.")]
|
||
|
public RadialIndicatorSettings radialIndicatorSettings;
|
||
|
|
||
|
[Tooltip("Settings for the radial area-of-effect (AoE) indicator.")]
|
||
|
public RadialAoEIndicatorSettings radialAoEIndicatorSettings;
|
||
|
|
||
|
[Tooltip("Settings for the arrow range indicator.")]
|
||
|
public ArrowIndicatorSettings arrowIndicatorSettings;
|
||
|
|
||
|
[Tooltip("Settings for the cone range indicator.")]
|
||
|
public ConeIndicatorSettings coneIndicatorSettings;
|
||
|
|
||
|
[Tooltip("Defines the launch method for the skill (e.g., Projectile, Targeted AoE, Targeted Air Strike).")]
|
||
|
public LaunchType launchType = LaunchType.Projectile;
|
||
|
|
||
|
[Tooltip("Height used for air strike skills.")]
|
||
|
public float airStrikeHeight;
|
||
|
|
||
|
[Tooltip("Should the character rotate towards the enemy?")]
|
||
|
public bool isRotateToEnemy;
|
||
|
|
||
|
[Tooltip("Duration of the rotation.")]
|
||
|
public float rotateDuration;
|
||
|
|
||
|
// -------------------------
|
||
|
// 4) DESTROY SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Destroy Settings")]
|
||
|
[Tooltip("Destroy the DamageEntity when hitting the first enemy.")]
|
||
|
public bool destroyOnFirstHit;
|
||
|
|
||
|
[Tooltip("Change the size of the axes of the DamageEntity prefab.")]
|
||
|
public DamageEntitySizeChange sizeChangeConfig;
|
||
|
|
||
|
[Tooltip("Does the skill have lifesteal?")]
|
||
|
public bool isHpLeech;
|
||
|
|
||
|
[Header("Explosion on Destroy Settings")]
|
||
|
[Tooltip("When destroyed (by lifetime or hitting an enemy), instantiate an explosion DamageEntity.")]
|
||
|
public bool explodeOnDestroy;
|
||
|
|
||
|
[Tooltip("DamageEntity prefab for the explosion.")]
|
||
|
public DamageEntity explodeDamageEntity;
|
||
|
|
||
|
[Tooltip("Skill level settings for the explosion.")]
|
||
|
public SkillLevel explodeEntitySettings;
|
||
|
|
||
|
// -------------------------
|
||
|
// 5) MULTI-SHOT SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Multi-Shot Settings")]
|
||
|
[Tooltip("Is this a Multi-Shot skill?")]
|
||
|
public bool isMultiShot;
|
||
|
|
||
|
[Tooltip("Number of shots.")]
|
||
|
public int shots;
|
||
|
|
||
|
[Tooltip("Angle between shots.")]
|
||
|
public float angle = 30;
|
||
|
|
||
|
[Tooltip("Delay between each shot.")]
|
||
|
public float delay = 0;
|
||
|
|
||
|
// -------------------------
|
||
|
// 6) ADVANCED MULTI-SHOT SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Advanced Multi-Shot Settings")]
|
||
|
[Tooltip("Enable advanced multi-shot, using waves and angles.")]
|
||
|
public bool isAdvancedMultiShot;
|
||
|
|
||
|
public bool playAnimationEaShot = false;
|
||
|
|
||
|
[Tooltip("List of shot waves for normal state.")]
|
||
|
public List<ShotWave> shotWaves;
|
||
|
|
||
|
[Tooltip("List of shot waves for evolved state.")]
|
||
|
public List<ShotWave> shotWavesEvolved;
|
||
|
|
||
|
// -------------------------
|
||
|
// 7) ORBITAL SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Orbital Settings")]
|
||
|
[Tooltip("Is this an Orbital skill?")]
|
||
|
public bool isOrbital;
|
||
|
|
||
|
[Tooltip("Distance before starting to orbit.")]
|
||
|
public float orbitalDistance = 5f;
|
||
|
|
||
|
// -------------------------
|
||
|
// 8) RICOCHET SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Ricochet Settings")]
|
||
|
[Tooltip("Does the skill ricochet off surfaces?")]
|
||
|
public bool isRicochet;
|
||
|
|
||
|
// -------------------------
|
||
|
// 9) BOOMERANG SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Boomerang Settings")]
|
||
|
[Tooltip("Is this a Boomerang skill?")]
|
||
|
public bool isBoomerangSkill;
|
||
|
|
||
|
[Tooltip("Maximum distance before returning.")]
|
||
|
public float maxDistance;
|
||
|
|
||
|
// -------------------------
|
||
|
// 10) DASH SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Dash Settings")]
|
||
|
[Tooltip("Is this a Dash skill?")]
|
||
|
public bool isDash;
|
||
|
|
||
|
[Tooltip("If true, the dash will move in the reverse direction.")]
|
||
|
public bool isReverseDash;
|
||
|
|
||
|
[Tooltip("Speed of the dash.")]
|
||
|
public float dashSpeed;
|
||
|
|
||
|
[Tooltip("Duration of the dash.")]
|
||
|
public float dashDuration;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Advanced dash settings for multiple dash waves and modes.
|
||
|
/// </summary>
|
||
|
[Tooltip("Advanced dash configuration.")]
|
||
|
public AdvancedDashSettings advancedDashSettings = new AdvancedDashSettings();
|
||
|
|
||
|
// -------------------------
|
||
|
// 11) MELEE SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Melee Settings")]
|
||
|
[Tooltip("Is this a Melee skill?")]
|
||
|
public bool isMelee;
|
||
|
|
||
|
// -------------------------
|
||
|
// 12) SLOW EFFECT SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Slow Effect Settings")]
|
||
|
[Tooltip("Does the skill apply a slow effect?")]
|
||
|
public bool applySlow;
|
||
|
|
||
|
[Tooltip("Percentage to slow the target.")]
|
||
|
public float slowPercent;
|
||
|
|
||
|
[Tooltip("Duration of the slow effect.")]
|
||
|
public float slowDuration;
|
||
|
|
||
|
// -------------------------
|
||
|
// 13) KNOCKBACK EFFECT SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Knockback Effect Settings")]
|
||
|
[Tooltip("Does the skill apply knockback?")]
|
||
|
public bool applyKnockback;
|
||
|
|
||
|
[Tooltip("Distance of the knockback.")]
|
||
|
public float knockbackDistance;
|
||
|
|
||
|
[Tooltip("Duration of the knockback effect.")]
|
||
|
public float knockbackDuration;
|
||
|
|
||
|
// -------------------------
|
||
|
// 14) STUN EFFECT SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Stun Effect Settings")]
|
||
|
[Tooltip("Does the skill apply stun?")]
|
||
|
public bool applyStun;
|
||
|
|
||
|
[Tooltip("Duration of the stun effect.")]
|
||
|
public float stunDuration;
|
||
|
|
||
|
// -------------------------
|
||
|
// 15) DAMAGE OVER TIME (DOT) SETTINGS
|
||
|
// -------------------------
|
||
|
[Header("Damage Over Time (DOT) Settings")]
|
||
|
[Tooltip("Does the skill apply damage over time?")]
|
||
|
public bool applyDOT;
|
||
|
|
||
|
[Tooltip("Total DOT damage.")]
|
||
|
public int dotAmount;
|
||
|
|
||
|
[Tooltip("Duration of the DOT effect.")]
|
||
|
public float dotDuration;
|
||
|
|
||
|
// -------------------------
|
||
|
// 16) BUFFS AND DEBUFFS
|
||
|
// -------------------------
|
||
|
[Header("Self-buffs/Self-debuffs")]
|
||
|
[Header("Buffs")]
|
||
|
[Tooltip("Does this skill heal the user?")]
|
||
|
public bool receiveHeal;
|
||
|
[Tooltip("Heal amount if receiveHeal is true.")]
|
||
|
public float healAmount;
|
||
|
|
||
|
[Tooltip("Is this a Shield skill?")]
|
||
|
public bool receiveShield;
|
||
|
[Tooltip("Amount of shield provided.")]
|
||
|
public int shieldAmount;
|
||
|
[Tooltip("Duration of the shield.")]
|
||
|
public float shieldDuration;
|
||
|
|
||
|
[Tooltip("Does this skill grant a movement speed buff?")]
|
||
|
public bool receiveMoveSpeed;
|
||
|
[Tooltip("Movement speed increase amount.")]
|
||
|
public float moveSpeedAmount;
|
||
|
[Tooltip("Duration of the movement speed buff.")]
|
||
|
public float moveSpeedDuration;
|
||
|
|
||
|
[Tooltip("Does this skill grant an attack speed buff?")]
|
||
|
public bool receiveAttackSpeed;
|
||
|
[Tooltip("Attack speed increase amount.")]
|
||
|
public float attackSpeedAmount;
|
||
|
[Tooltip("Duration of the attack speed buff.")]
|
||
|
public float attackSpeedDuration;
|
||
|
|
||
|
[Tooltip("Does this skill grant a defense buff?")]
|
||
|
public bool receiveDefense;
|
||
|
[Tooltip("Defense increase amount.")]
|
||
|
public float defenseAmount;
|
||
|
[Tooltip("Duration of the defense buff.")]
|
||
|
public float defenseDuration;
|
||
|
|
||
|
[Tooltip("Does this skill grant a damage buff?")]
|
||
|
public bool receiveDamage;
|
||
|
[Tooltip("Damage increase amount.")]
|
||
|
public float damageAmount;
|
||
|
[Tooltip("Duration of the damage buff.")]
|
||
|
public float damageDuration;
|
||
|
|
||
|
[Tooltip("Does the skill grant invincibility?")]
|
||
|
public bool isInvincible;
|
||
|
[Tooltip("Duration of invincibility.")]
|
||
|
public float invincibleDuration = 0;
|
||
|
|
||
|
[Header("Debuff")]
|
||
|
[Tooltip("Does this skill apply a slow to the user?")]
|
||
|
public bool receiveSlow;
|
||
|
|
||
|
[Tooltip("Amount of self-slow if receiveSlow is true (0 = no slow, 1 = 100% slow).")]
|
||
|
[Range(0f, 1f)]
|
||
|
public float receiveSlowAmount;
|
||
|
|
||
|
[Tooltip("Duration of the self-slow.")]
|
||
|
public float receiveSlowDuration;
|
||
|
|
||
|
// -------------------------
|
||
|
// 17) EVOLVE CHANGES
|
||
|
// -------------------------
|
||
|
[Tooltip("Evolved DamageEntity prefab.")]
|
||
|
public DamageEntity evolvedDamageEntityPrefab;
|
||
|
|
||
|
[Tooltip("Do evolve changes affect Multi-Shot settings?")]
|
||
|
public bool evolveChanges;
|
||
|
|
||
|
[Tooltip("Number of shots when evolved.")]
|
||
|
public int shotsEvolved;
|
||
|
|
||
|
[Tooltip("Angle between shots when evolved.")]
|
||
|
public float angleEvolved = 30;
|
||
|
|
||
|
[Tooltip("Delay between shots when evolved.")]
|
||
|
public float delayEvolved = 0;
|
||
|
|
||
|
[Header("Skill Levels")]
|
||
|
[Tooltip("Levels of the skill.")]
|
||
|
public List<SkillLevel> skillLevels;
|
||
|
|
||
|
[Header("Evolved Skill Settings")]
|
||
|
[Tooltip("Stat required for skill evolution.")]
|
||
|
public StatPerkData requireStatForEvolve;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Launches damage from a character.
|
||
|
/// </summary>
|
||
|
/// <param name="attackTransform">Transform from which the damage is launched.</param>
|
||
|
/// <param name="direction">Direction to launch the damage.</param>
|
||
|
/// <param name="attacker">Character who is attacking.</param>
|
||
|
public void LaunchDamage(Transform attackTransform, Vector3 direction, CharacterEntity attacker)
|
||
|
{
|
||
|
int currentLevel = GameplayManager.Singleton.GetBaseSkillLevel(this);
|
||
|
int skillLevelIndex = Mathf.Clamp(currentLevel, 0, skillLevels.Count - 1);
|
||
|
SkillLevel levelData = skillLevels[skillLevelIndex];
|
||
|
|
||
|
GameplayManager.Singleton.StartCoroutine(
|
||
|
LaunchDamageInternal(attackTransform, direction, levelData, attacker)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Launches the damage entity (projectile) in the specified direction, handling multi-shot, orbital skills, etc.
|
||
|
/// </summary>
|
||
|
/// <param name="attackTransform">The transform from which to launch the damage entity.</param>
|
||
|
/// <param name="direction">The direction in which to launch the damage entity.</param>
|
||
|
/// <param name="levelData">The current skill level data.</param>
|
||
|
/// <param name="attacker">The character entity that is attacking.</param>
|
||
|
private IEnumerator LaunchDamageInternal(Transform attackTransform, Vector3 direction, SkillLevel levelData, CharacterEntity attacker)
|
||
|
{
|
||
|
bool useEvolvedSettings = levelData.isEvolved;
|
||
|
int finalShots = useEvolvedSettings && evolveChanges ? shotsEvolved : shots;
|
||
|
float finalAngle = useEvolvedSettings && evolveChanges ? angleEvolved : angle;
|
||
|
float finalDelay = useEvolvedSettings && evolveChanges ? delayEvolved : delay;
|
||
|
List<ShotWave> finalShotWaves = (useEvolvedSettings && evolveChanges) ? shotWavesEvolved : shotWaves;
|
||
|
DamageEntity damageEntityPrefabToUse = useEvolvedSettings ? evolvedDamageEntityPrefab : damageEntityPrefab;
|
||
|
|
||
|
if (damageEntityPrefabToUse == null) { Debug.LogWarning("DamageEntity prefab not assigned."); yield break; }
|
||
|
if (attackTransform == null) { Debug.LogWarning("Attack transform is null."); yield break; }
|
||
|
|
||
|
if (isOrbital)
|
||
|
{
|
||
|
GameObject orbitManagerObj = new GameObject("OrbitManager");
|
||
|
OrbitManager orbitManager = orbitManagerObj.AddComponent<OrbitManager>();
|
||
|
orbitManager.InitializeOrbital(this, levelData, attacker, finalShots, damageEntityPrefabToUse, direction.normalized * levelData.speed);
|
||
|
yield break;
|
||
|
}
|
||
|
|
||
|
if (isAdvancedMultiShot)
|
||
|
{
|
||
|
if (finalShotWaves == null || finalShotWaves.Count == 0) { Debug.LogWarning("No shot waves configured for advanced multi-shot."); yield break; }
|
||
|
foreach (ShotWave wave in finalShotWaves)
|
||
|
{
|
||
|
if (wave.shotAngles == null || wave.shotAngles.Count == 0) { Debug.LogWarning("Shot wave has no angles defined."); continue; }
|
||
|
Vector3 waveBaseDirection = GetUpdatedDirection(attacker, direction);
|
||
|
List<float> generatedAngles = GenerateShotAngles(wave.shotCount, wave.shotAngles.Count > 0 ? wave.shotAngles[0] : 0f, wave.useInitialAngle, wave.initialAngle, wave.shotAngles);
|
||
|
foreach (float angleVal in generatedAngles)
|
||
|
{
|
||
|
Quaternion rotation = Quaternion.AngleAxis(angleVal, Vector3.up);
|
||
|
Vector3 shotDirection = rotation * waveBaseDirection;
|
||
|
SpawnDamageEntity(attackTransform, shotDirection, damageEntityPrefabToUse, levelData, attacker);
|
||
|
}
|
||
|
if (wave.delayBeforeNextWave > 0) yield return new WaitForSeconds(wave.delayBeforeNextWave);
|
||
|
}
|
||
|
}
|
||
|
else if (isMultiShot)
|
||
|
{
|
||
|
if (finalShots <= 0) finalShots = 1;
|
||
|
float totalSpreadAngle = finalAngle;
|
||
|
int numberOfShots = finalShots;
|
||
|
float angleStep = numberOfShots > 1 ? totalSpreadAngle / (numberOfShots - 1) : 0f;
|
||
|
float startingAngle = -totalSpreadAngle / 2f;
|
||
|
for (int i = 0; i < numberOfShots; i++)
|
||
|
{
|
||
|
Vector3 currentDirection = GetUpdatedDirection(attacker, direction);
|
||
|
float currentAngle = startingAngle + (angleStep * i);
|
||
|
Quaternion rotation = Quaternion.AngleAxis(currentAngle, Vector3.up);
|
||
|
Vector3 shotDirection = rotation * currentDirection;
|
||
|
SpawnDamageEntity(attackTransform, shotDirection, damageEntityPrefabToUse, levelData, attacker);
|
||
|
if (finalDelay > 0) yield return new WaitForSeconds(finalDelay);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Vector3 currentDirection = GetUpdatedDirection(attacker, direction);
|
||
|
SpawnDamageEntity(attackTransform, currentDirection, damageEntityPrefabToUse, levelData, attacker);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Recalculates the current direction based on the attacker's forward direction.
|
||
|
/// </summary>
|
||
|
private Vector3 GetUpdatedDirection(CharacterEntity attacker, Vector3 originalDirection)
|
||
|
{
|
||
|
if (attacker != null && attacker.characterModelTransform != null)
|
||
|
{
|
||
|
return attacker.characterModelTransform.forward.normalized;
|
||
|
}
|
||
|
return originalDirection.normalized;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Generates shot angles based on wave data or a single baseAngle approach.
|
||
|
/// This version supports passing an entire list of angles if needed.
|
||
|
/// </summary>
|
||
|
/// <param name="shotCount">Number of shots in the wave.</param>
|
||
|
/// <param name="baseAngle">Base angle for shot increments.</param>
|
||
|
/// <param name="useInitialAngle">If true, the first shot uses initialAngle.</param>
|
||
|
/// <param name="initialAngle">The angle used if useInitialAngle is true.</param>
|
||
|
/// <param name="shotAnglesList">The raw angles from the wave (optional).</param>
|
||
|
/// <returns>List of angles for each shot in the wave.</returns>
|
||
|
private List<float> GenerateShotAngles(int shotCount, float baseAngle, bool useInitialAngle, float initialAngle, List<float> shotAnglesList)
|
||
|
{
|
||
|
List<float> angles = new List<float>();
|
||
|
if (shotCount <= 0) return angles;
|
||
|
|
||
|
if (shotAnglesList != null && shotAnglesList.Count > 1)
|
||
|
{
|
||
|
for (int i = 0; i < shotCount; i++)
|
||
|
angles.Add(i < shotAnglesList.Count ? shotAnglesList[i] : shotAnglesList[^1]); // repeat last
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (shotCount == 1)
|
||
|
{
|
||
|
angles.Add(useInitialAngle ? initialAngle : baseAngle);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (baseAngle != 0f)
|
||
|
{
|
||
|
if (useInitialAngle)
|
||
|
{
|
||
|
angles.Add(initialAngle);
|
||
|
for (int i = 1; i < shotCount; i++)
|
||
|
{
|
||
|
float angleOffset = ((i + 1) / 2) * baseAngle;
|
||
|
angles.Add(i % 2 == 1 ? initialAngle + angleOffset : initialAngle - angleOffset);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
angles.Add(0f);
|
||
|
for (int i = 1; i < shotCount; i++)
|
||
|
{
|
||
|
float angleOffset = ((i + 1) / 2) * baseAngle;
|
||
|
angles.Add(i % 2 == 1 ? angleOffset : -angleOffset);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (int i = 0; i < shotCount; i++) angles.Add(0f);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return angles;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Spawns a damage entity in the given direction.
|
||
|
/// </summary>
|
||
|
private void SpawnDamageEntity(
|
||
|
Transform attackTransform,
|
||
|
Vector3 direction,
|
||
|
DamageEntity damageEntityPrefab,
|
||
|
SkillLevel levelData,
|
||
|
CharacterEntity attacker
|
||
|
)
|
||
|
{
|
||
|
if (playSkillAudioEaShot && skillAudio != null)
|
||
|
{
|
||
|
AudioManager.Singleton.PlayAudio(skillAudio, "vfx");
|
||
|
}
|
||
|
if (playAnimationEaShot)
|
||
|
{
|
||
|
attacker.PlayTriggerAnimation(attacker.GetSkillIndex(this));
|
||
|
}
|
||
|
|
||
|
if (playSpawnAudioEaShot && spawnAudio != null)
|
||
|
{
|
||
|
AudioManager.Singleton.PlayAudio(spawnAudio, "vfx");
|
||
|
}
|
||
|
if (isMelee && attacker.characterModelTransform != null)
|
||
|
{
|
||
|
DamageEntity meleeDamage = Instantiate(
|
||
|
damageEntityPrefab,
|
||
|
attacker.characterModelTransform.position,
|
||
|
Quaternion.identity,
|
||
|
attacker.characterModelTransform
|
||
|
);
|
||
|
meleeDamage.transform.localPosition = Vector3.zero;
|
||
|
meleeDamage.transform.localRotation = Quaternion.identity;
|
||
|
meleeDamage.SetSkill(
|
||
|
this,
|
||
|
levelData.baseDamage,
|
||
|
levelData.attackerDamageRate,
|
||
|
levelData.canCauseCriticalDamage,
|
||
|
attacker,
|
||
|
levelData.lifeTime,
|
||
|
Vector3.zero
|
||
|
);
|
||
|
if (sizeChangeConfig.enableSizeChange)
|
||
|
{
|
||
|
meleeDamage.SetSizeChange(sizeChangeConfig);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DamageEntity projectile = Instantiate(
|
||
|
damageEntityPrefab,
|
||
|
attackTransform.position,
|
||
|
Quaternion.LookRotation(direction)
|
||
|
);
|
||
|
projectile.SetSkill(
|
||
|
this,
|
||
|
levelData.baseDamage,
|
||
|
levelData.attackerDamageRate,
|
||
|
levelData.canCauseCriticalDamage,
|
||
|
attacker,
|
||
|
levelData.lifeTime,
|
||
|
direction.normalized * levelData.speed
|
||
|
);
|
||
|
if (sizeChangeConfig.enableSizeChange)
|
||
|
{
|
||
|
projectile.SetSizeChange(sizeChangeConfig);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|