feat(ArcherSkill): 弓箭手技能重构为阶梯体系支持1/3/6/10级完整升级 - 实现迅捷三连技能,支持1级基础3箭、10级升级为6支风暴连射 - 添加弱点锁定机制,6级后伤害逐箭递增且最后一箭必暴击 - 集成破甲易伤标记系统,使目标受到伤害增加30%持续4秒 - 优化技能释放逻辑,支持目标死亡后自动切换最近敌人 - 完善技能平衡性调整,3级箭矢速度提升35%总伤害增加25% feat(StatusEffectController): 新增易伤状态管理系统 - 添加vulnerability相关属性和ApplyVulnerability方法 - 实现易伤效果的生命周期管理和伤害计算 - 集成到UnitBase的伤害结算流程中 docs: 更新角色技能说明文档支持新技能体系 - 将原弓箭猎人重命名为荒野猎手,更新技能描述 - 同步更新角色与技能对应关系表格 - 调整技能名称从穿透箭改为穿心猎矛等新命名 ```
181 lines
6.3 KiB
C#
181 lines
6.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// 弓箭手技能:迅捷三连 / 弱点锁定体系(1/3/6/10 级完整阶梯)
|
|
/// 1级【迅捷三连】:搭弓连续高速射出 3 支穿甲箭矢,单体快速倾泻火力
|
|
/// 3级【极速穿甲】:箭矢飞行速度 +35%,三连射总伤害提升 25%
|
|
/// 6级【弱点锁定】:伤害逐箭递增且第 3 箭必暴击;命中附加破甲标记,使目标受到的所有伤害 +30%(持续 4s)!
|
|
/// 10级【乱射风暴】:三连射升级为 6 支风暴连射;击杀目标后剩余箭矢自动散开弹射给周围其他敌人
|
|
/// </summary>
|
|
public class ArcherSkill : UnitSkill
|
|
{
|
|
[Header("三连射配置")]
|
|
[Tooltip("基础箭矢数量")]
|
|
public int baseArrowCount = 3;
|
|
|
|
[Tooltip("每支箭发射间隔(秒)")]
|
|
public float arrowInterval = 0.12f;
|
|
|
|
[Tooltip("技能箭矢基础速度")]
|
|
public float baseProjectileSpeed = 22f;
|
|
|
|
private Coroutine activeVolleyCoroutine;
|
|
|
|
private void EnsureUnit()
|
|
{
|
|
if (unit == null)
|
|
{
|
|
unit = GetComponent<UnitBase>();
|
|
}
|
|
}
|
|
|
|
public override void ReleaseSkill()
|
|
{
|
|
EnsureUnit();
|
|
if (unit == null) return;
|
|
|
|
WorldHealthBar healthBar = unit.GetComponent<WorldHealthBar>();
|
|
if (healthBar == null || healthBar.IsDead) return;
|
|
|
|
if (unit.Target == null) return;
|
|
|
|
if (activeVolleyCoroutine != null)
|
|
{
|
|
StopCoroutine(activeVolleyCoroutine);
|
|
}
|
|
|
|
activeVolleyCoroutine = StartCoroutine(FireVolleyRoutine());
|
|
}
|
|
|
|
private IEnumerator FireVolleyRoutine()
|
|
{
|
|
EnsureUnit();
|
|
if (unit == null) yield break;
|
|
|
|
int level = unit.level;
|
|
|
|
// 10级升级为 6 支箭;其余等级为 3 支
|
|
int arrowCount = level >= 10 ? 6 : baseArrowCount;
|
|
|
|
// 3级+ 箭速提升 35%
|
|
float projSpeed = level >= 3 ? baseProjectileSpeed * 1.35f : baseProjectileSpeed;
|
|
|
|
Debug.Log($"<color=green>【弓箭手释放技能】</color> 准备倾泻 {arrowCount} 连射(等级: {level})!");
|
|
|
|
for (int i = 0; i < arrowCount; i++)
|
|
{
|
|
// 目标死亡后自动切换给最近敌人
|
|
GameObject currentTarget = unit.Target;
|
|
if (currentTarget == null || !currentTarget.activeInHierarchy || IsTargetDead(currentTarget))
|
|
{
|
|
currentTarget = unit.FindNearestEnemyForSkill();
|
|
}
|
|
|
|
if (currentTarget == null)
|
|
{
|
|
break; // 全场无敌人提前结束
|
|
}
|
|
|
|
// 计算该支箭的伤害倍率与暴击
|
|
float damageMultiplier = GetArrowDamageMultiplier(i, arrowCount, level);
|
|
bool isGuaranteedCrit = (level >= 6 && i == arrowCount - 1); // 6级+ 最后一箭必定暴击
|
|
bool applyVulnerability = (level >= 6 && i == arrowCount - 1); // 6级+ 最后一箭施加 4 秒 30% 易伤
|
|
|
|
// 发射技能箭矢
|
|
LaunchSkillArrow(currentTarget, damageMultiplier, projSpeed, isGuaranteedCrit, applyVulnerability);
|
|
|
|
yield return new WaitForSeconds(arrowInterval);
|
|
}
|
|
|
|
activeVolleyCoroutine = null;
|
|
}
|
|
|
|
private float GetArrowDamageMultiplier(int index, int totalCount, int level)
|
|
{
|
|
// 1级:基础 70% 伤害/箭
|
|
float baseMult = 0.70f;
|
|
|
|
// 3级:三连射总伤害提升 25% (0.70 * 1.25 = 0.875)
|
|
if (level >= 3 && level < 6)
|
|
{
|
|
baseMult *= 1.25f;
|
|
}
|
|
|
|
// 6级+【弱点锁定】:伤害逐箭递增
|
|
if (level >= 6)
|
|
{
|
|
// 逐箭递增:例如第 1 箭 0.85,第 2 箭 1.05,最后一箭 1.35
|
|
float step = (float)index / Mathf.Max(1, totalCount - 1);
|
|
baseMult = Mathf.Lerp(0.85f, 1.35f, step);
|
|
}
|
|
|
|
return baseMult;
|
|
}
|
|
|
|
private void LaunchSkillArrow(GameObject targetObj, float damageMultiplier, float speed, bool forceCrit, bool applyVulnerability)
|
|
{
|
|
if (unit == null || unit.projectilePrefab == null || targetObj == null) return;
|
|
|
|
Transform spawnPoint = unit.projectileSpawnPoint != null ? unit.projectileSpawnPoint : unit.transform;
|
|
Vector3 spawnPos = spawnPoint.position;
|
|
|
|
Vector3 direction = (targetObj.transform.position + Vector3.up * 0.8f - spawnPos).normalized;
|
|
Quaternion rotation = Quaternion.LookRotation(direction);
|
|
|
|
GameObject arrowObj = Instantiate(unit.projectilePrefab, spawnPos, rotation);
|
|
|
|
float calculatedDamage = unit.attackPower * damageMultiplier;
|
|
if (forceCrit || (unit.critRate > 0f && Random.value < unit.critRate))
|
|
{
|
|
calculatedDamage *= unit.critMultiplier;
|
|
}
|
|
|
|
// 接管 Arrow 碰撞,挂载自定义伤害与易伤回调
|
|
var projectile = arrowObj.GetComponent<Projectile>();
|
|
if (projectile != null)
|
|
{
|
|
// 技能箭不二次积攒能量
|
|
projectile.Initialize(targetObj, calculatedDamage, unit.gameObject, speed, 5f, false);
|
|
}
|
|
|
|
// 6级+ 易伤监听逻辑:如果本箭命中了,自动给目标挂上 30% 易伤
|
|
if (applyVulnerability)
|
|
{
|
|
StartCoroutine(ApplyVulnerabilityWhenHit(targetObj, 4.0f, 0.30f));
|
|
}
|
|
}
|
|
|
|
private IEnumerator ApplyVulnerabilityWhenHit(GameObject targetObj, float duration, float ratio)
|
|
{
|
|
// 等待箭矢飞至命中(约 0.2 ~ 0.4 秒)
|
|
yield return new WaitForSeconds(0.25f);
|
|
|
|
if (targetObj != null && targetObj.activeInHierarchy)
|
|
{
|
|
var status = targetObj.GetComponentInParent<StatusEffectController>();
|
|
if (status != null)
|
|
{
|
|
status.ApplyVulnerability(duration, ratio);
|
|
Debug.Log($"<color=yellow>【弱点锁定】生效!</color> 目标 {targetObj.name} 陷入破甲易伤:受击伤害 +{ratio * 100:F0}%,持续 {duration} 秒!");
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool IsTargetDead(GameObject targetObj)
|
|
{
|
|
if (targetObj == null) return true;
|
|
var bar = targetObj.GetComponentInParent<WorldHealthBar>();
|
|
return bar != null && bar.IsDead;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (activeVolleyCoroutine != null)
|
|
{
|
|
StopCoroutine(activeVolleyCoroutine);
|
|
}
|
|
}
|
|
}
|