229 lines
5.5 KiB
C#
229 lines
5.5 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using BehaviorDesigner.Runtime.Tasks;
|
||
using DragonLi.Core;
|
||
using Pathfinding;
|
||
using UnityEngine;
|
||
|
||
/// <summary>
|
||
/// 死亡冲锋技能
|
||
/// </summary>
|
||
public class DeathKnightChargeAtk : Action
|
||
{
|
||
private DeathKnightBoss boss;
|
||
private bool isFinished;
|
||
|
||
[Header("Sprint")]
|
||
public float sprintDistance = 3f;
|
||
public float sprintSpeed = 6f;
|
||
|
||
[Header("Angry Trample")]
|
||
public float angryDuration = 3f;
|
||
public float rotateSpeed = 90f;
|
||
|
||
public override void OnStart()
|
||
{
|
||
boss = GetComponent<DeathKnightBoss>();
|
||
isFinished = false;
|
||
|
||
boss.ResetSkill1();
|
||
StartCoroutine(SkillFlow());
|
||
}
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
return isFinished ? TaskStatus.Success : TaskStatus.Running;
|
||
}
|
||
|
||
IEnumerator SkillFlow()
|
||
{
|
||
// ===== Phase 1:冲刺 =====
|
||
yield return SprintThroughPlayer();
|
||
|
||
// ===== Phase 2:原地劈砍 =====
|
||
yield return Alash();
|
||
// ===== Phase 3:转向玩家 → Idle =====
|
||
yield return boss.RotateToPlayer();
|
||
boss.Idle();
|
||
isFinished = true;
|
||
}
|
||
|
||
#region Phase 1 - Sprint
|
||
|
||
IEnumerator SprintThroughPlayer()
|
||
{
|
||
boss.BeginAttack();
|
||
boss.Run();
|
||
GameManager.Ins.PlaySound3D("1.55",transform,true);
|
||
Transform player = GameManager.Ins.player.transform;
|
||
|
||
Vector3 dir = (player.position.ReflectVectorXOZ() - boss.transform.position.ReflectVectorXOZ()).normalized;
|
||
dir.y = 0;
|
||
|
||
// 🎯 贯穿目标点
|
||
Vector3 targetPos = player.position + dir * sprintDistance;
|
||
|
||
// A* 移动
|
||
boss.aiPath.maxSpeed = sprintSpeed;
|
||
boss.aiPath.isStopped = false;
|
||
boss.aiPath.destination = targetPos;
|
||
|
||
// 面向移动方向
|
||
boss.transform.rotation = Quaternion.LookRotation(dir);
|
||
|
||
// 等待到达
|
||
while (!boss.aiPath.reachedEndOfPath)
|
||
{
|
||
if (boss.isDead)
|
||
{
|
||
StopAllCoroutines();
|
||
isFinished = true;
|
||
}
|
||
yield return null;
|
||
}
|
||
|
||
boss.aiPath.isStopped = true;
|
||
boss.EndAttack();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Phase 2 - Angry Trample
|
||
|
||
IEnumerator Alash()
|
||
{
|
||
Transform player = GameManager.Ins.player.transform;
|
||
|
||
// 1️⃣ 计算玩家方向(基准方向)
|
||
Vector3 dir = player.position - boss.transform.position;
|
||
dir.y = 0;
|
||
|
||
if (dir.sqrMagnitude < 0.01f)
|
||
yield break;
|
||
|
||
Quaternion baseRot = Quaternion.LookRotation(dir);
|
||
|
||
// 2️⃣ 左侧 30°
|
||
Quaternion leftRot = baseRot * Quaternion.Euler(0, -15f, 0);
|
||
yield return RotateAndTrample(leftRot);
|
||
|
||
// 3️⃣ 右侧 30°
|
||
Quaternion rightRot = baseRot * Quaternion.Euler(0, 15f, 0);
|
||
yield return RotateAndTrample(rightRot);
|
||
}
|
||
|
||
IEnumerator RotateAndTrample(Quaternion targetRot)
|
||
{
|
||
boss.Walk();
|
||
// 先转向
|
||
while (Quaternion.Angle(boss.transform.rotation, targetRot) > 1f)
|
||
{
|
||
if (boss.isDead)
|
||
{
|
||
StopAllCoroutines();
|
||
isFinished = true;
|
||
}
|
||
boss.transform.rotation = Quaternion.RotateTowards(
|
||
boss.transform.rotation,
|
||
targetRot,
|
||
rotateSpeed * Time.deltaTime
|
||
);
|
||
yield return null;
|
||
}
|
||
|
||
// 播放劈砍动画
|
||
boss.Slash();
|
||
|
||
yield return new WaitForSeconds(1f);
|
||
boss.swordEx.SetActive(true);
|
||
|
||
// 在该方向持续践踏
|
||
float timer = 0f;
|
||
while (timer < angryDuration)
|
||
{
|
||
timer += Time.deltaTime;
|
||
yield return null;
|
||
}
|
||
boss.Idle();
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
public class DeathKnightSwordAtk : Action
|
||
{
|
||
private DeathKnightBoss boss;
|
||
private bool isFinished;
|
||
|
||
public override void OnStart()
|
||
{
|
||
boss = GetComponent<DeathKnightBoss>();
|
||
isFinished = false;
|
||
|
||
boss.ResetSkill2();
|
||
boss.StartCoroutine(SkillFlow());
|
||
}
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
return isFinished ? TaskStatus.Success : TaskStatus.Running;
|
||
}
|
||
|
||
IEnumerator SkillFlow()
|
||
{
|
||
boss.Idle();
|
||
// 1️⃣ 转向玩家
|
||
yield return boss.RotateToPlayer();
|
||
|
||
// 2️⃣ 播放投掷动画
|
||
boss.ThrowSword();
|
||
yield return new WaitForSeconds(0.4f); // 对齐动画出手点
|
||
|
||
// 3️⃣ 发射大剑
|
||
boss.LaunchSword();
|
||
|
||
// 4️⃣ 等技能完成
|
||
yield return new WaitUntil(() => boss.IsSwordSkillFinished);
|
||
|
||
// 5️⃣ 回到 Idle
|
||
boss.Idle();
|
||
boss.swordPre.SetActive(true);
|
||
isFinished = true;
|
||
}
|
||
}
|
||
|
||
public class DeathPhantomChargeAtk : Action
|
||
{
|
||
private DeathKnightBoss boss;
|
||
private bool isFinished;
|
||
|
||
public override void OnStart()
|
||
{
|
||
boss = GetComponent<DeathKnightBoss>();
|
||
isFinished = false;
|
||
|
||
boss.StartCoroutine(PhantomSkillFlow());
|
||
}
|
||
|
||
public override TaskStatus OnUpdate()
|
||
{
|
||
return isFinished ? TaskStatus.Success : TaskStatus.Running;
|
||
}
|
||
|
||
IEnumerator PhantomSkillFlow()
|
||
{
|
||
// 1️⃣ 转向玩家
|
||
yield return boss.RotateToPlayer();
|
||
|
||
// 2️⃣ 播放蓄力 / 咆哮
|
||
boss.Roar();
|
||
yield return new WaitForSeconds(0.8f);
|
||
|
||
// 3️⃣ 执行幻影冲锋
|
||
yield return boss.StartCoroutine(boss.ExecutePhantomCharge());
|
||
|
||
boss.Idle();
|
||
isFinished = true;
|
||
}
|
||
}
|
||
|