using System; using System.Collections.Generic; using UnityEngine; public class PenetrateBulletCurve : BulletCurve { private Vector2 start; // 子弹起点(本地坐标) private Vector2 end; // 目标点(本地坐标) private Vector2 outPos; // 屏幕外延长点(本地坐标) private bool hitTriggered = false; // 是否已触发onHit public PenetrateBulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer effectPlayer, RectTransform target, List hurtList, int bulletIndex, Action> onHit) : base(caster, skillConfig, effectPlayer, target, hurtList, bulletIndex, onHit) { } /// /// 初始化弹道参数 /// public override void Reset() { base.Reset(); hitTriggered = false; start = WorldToLocalAnchoredPosition(bulletTrans.position) + bulletOffset; end = WorldToLocalAnchoredPosition(target.position); duration = Vector2.Distance(start, end) / skillConfig.BulletFlySpeed; Vector2 dir = (end - start).normalized; float extend = 500f; // 贯穿距离,可根据需求调整 outPos = end + dir * extend; } /// /// 每帧调用,驱动子弹移动和表现 /// public override void Run() { if (finished) return; elapsed += Time.deltaTime; float t = Mathf.Clamp01(elapsed / duration); // 贯穿分两段:0~0.5到目标点,0.5~1.0继续飞出 float mid = 0.5f; Vector2 pos; if (t < mid) { // 前半段:插值到目标点 pos = Vector2.Lerp(start, end, t / mid); } else { // 后半段:插值到屏幕外 pos = Vector2.Lerp(end, outPos, (t - mid) / (1f - mid)); // 到达目标点瞬间触发onHit,只触发一次 if (!hitTriggered) { hitTriggered = true; onHit?.Invoke(mBulletIndex, hurts); } } bulletTrans.anchoredPosition = pos; // 旋转:始终朝向运动方向,子弹默认90°向上 Vector2 dir = (t < mid) ? (end - start) : (outPos - end); float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg - 90f; bulletTrans.localRotation = Quaternion.Euler(0, 0, angle); // 到达终点,结束 if (t >= 1f) { finished = true; } } }