Files
FutureMen2/Assets/_FutureMen2/Scripts/Enemy/DeathKnightBoss/DeathKnightBoss.cs

333 lines
8.8 KiB
C#
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using DragonLi.Core;
using UnityEngine;
using Random = UnityEngine.Random;
public class DeathKnightBoss : Enemy
{
[Header("Base")]
public GameObject clipQuadObj;
public Animator bossManAnim;
public Animator houseAnim;
[Header("预制体")]
public GameObject swordEx;
public GameObject swordPre;
[Header("Sword Skill")]
public DeathSwordProjectile swordProjectilePrefab;
public Transform swordFirePoint;
[HideInInspector]
public bool IsSwordSkillFinished;
[Header("Phantom Skill")]
public GameObject phantomPrefab;
public int phantomCountPerSide = 3;
private float phantomSpacing = 3f;
private float phantomChargeDistance = 20f;
private float phantomChargeSpeed = 8f;
[HideInInspector]
public bool isPhantomSkillFinished;
public EnemyBoneHit skill1Bone;
public GameObject[] bossCrystals;
private void Start()
{
swordEx.SetActive(false);
swordPre.SetActive(false);
bloodSlider.gameObject.SetActive(false);
skill1Bone.SetDamage(Data.Atk_1P);
foreach (var item in bossCrystals)
{
item.SetActive(false);
}
}
public override void Update()
{
base.Update();
if (enemyState != EnemyState.Show && enemyState != EnemyState.Dead)
{
skill1Timer += Time.deltaTime;
skill2Timer += Time.deltaTime;
}
}
#region Show
public override void Show()
{
base.Show();
clipQuadObj.transform.DOLocalMoveY(10, 5).OnComplete(() =>
{
Roar();
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
isShowEnd = true;
swordPre.SetActive(true);
bloodSlider.gameObject.SetActive(true);
foreach (var item in bossCrystals)
{
item.SetActive(true);
}
}, 2f);
});
}
#endregion
public void ResetSkill1() => skill1Timer = 0;
public void ResetSkill2() => skill2Timer = 0;
public bool IsUserSkill3()
{
float hpPercent =health / maxHealth;
int index = Mathf.FloorToInt(hpPercent / 0.2f);
if (index < spikeTriggerIndex)
{
spikeTriggerIndex = index;
return true;
}
return false;
}
public bool HasAnySkillReady()
{
return skill1Timer >= skill1Cooldown ||
skill2Timer >= skill2Cooldown ||
IsUserSkill3();
}
public void Roar()
{
bossManAnim.SetInteger("state", 0);
houseAnim.SetInteger("state", 0);
GameManager.Ins.PlaySound3D("1.2", transform);
}
public void Run()
{
bossManAnim.SetInteger("state",2);
houseAnim.SetInteger("state",2);
}
public void Walk()
{
houseAnim.SetInteger("state",3);
}
public void Idle()
{
bossManAnim.SetInteger("state",1);
houseAnim.SetInteger("state",1);
GameManager.Ins.PlaySound3D("1.45", transform);
swordEx.SetActive(false);
}
public void Slash()
{
bossManAnim.SetInteger("state",3);
houseAnim.SetInteger("state",1);
}
public void ThrowSword()
{
bossManAnim.SetInteger("state",4);
houseAnim.SetInteger("state",1);
}
public float rotateSpeed = 90f;
public IEnumerator RotateToPlayer()
{
Transform player = GameManager.Ins.player.transform;
Vector3 dir = player.position - transform.position;
dir.y = 0;
if (dir.sqrMagnitude < 0.01f)
yield break;
Walk();
Quaternion targetRot = Quaternion.LookRotation(dir);
while (Quaternion.Angle(transform.rotation, targetRot) > 1f)
{
if (isDead)
{
StopAllCoroutines();
}
transform.rotation = Quaternion.RotateTowards(
transform.rotation,
targetRot,
rotateSpeed * Time.deltaTime
);
yield return null;
}
Idle();
}
public void LaunchSword()
{
IsSwordSkillFinished = false;
Vector3 targetPos = GameManager.Ins.player.transform.position.ReflectVectorXOZ();
swordPre.SetActive(false); // Boss 手上剑隐藏
swordEx.SetActive(false);
DeathSwordProjectile sword = Instantiate(
swordProjectilePrefab,
swordFirePoint.position,
swordFirePoint.rotation
);
sword.Init(
swordFirePoint,
targetPos,
Data.Atk_2,
() => IsSwordSkillFinished = true
);
//sword.SetOriginSword(sword); // 绑定自身
//swordEx.SetActive(false);
//sword.SetActive(false); // Boss 手上剑隐藏
}
public IEnumerator ExecutePhantomCharge()
{
Transform player = GameManager.Ins.player.transform;
Vector3 startPos = transform.position;
Vector3 forward = (player.position - startPos).normalized;
forward.y = 0;
Vector3 right = Vector3.Cross(Vector3.up, forward);
// ===== 1⃣ 随机一个分身空位0~5=====
int emptySlot = Random.Range(0, 6);
List<GameObject> allChargers = new List<GameObject>();
// ===== 2⃣ 生成左边 3 个 =====
for (int i = 0; i < 3; i++)
{
int slotIndex = i; // 0,1,2
if (slotIndex == emptySlot)
continue;
Vector3 offset = -right * (i + 1) * phantomSpacing;
SpawnPhantom(startPos + offset, forward, allChargers);
}
// ===== 3⃣ 生成右边 3 个 =====
for (int i = 0; i < 3; i++)
{
int slotIndex = i + 3; // 3,4,5
if (slotIndex == emptySlot)
continue;
Vector3 offset = right * (i + 1) * phantomSpacing;
SpawnPhantom(startPos + offset, forward, allChargers);
}
// ===== 4⃣ 加入本体(永远存在)=====
allChargers.Add(gameObject);
Slash();
houseAnim.SetInteger("state", 2);
// ===== 5⃣ 直线冲锋 =====
float moved = 0f;
while (moved < phantomChargeDistance)
{
float step = phantomChargeSpeed * Time.deltaTime;
moved += step;
foreach (var obj in allChargers)
{
if (obj == null) continue;
if(obj.GetComponent<DeathKnightPhantomHit>()!=null)
obj.GetComponent<DeathKnightPhantomHit>().Run();
obj.transform.position += forward * step;
}
yield return null;
}
yield return new WaitForSeconds(1f);
foreach (var obj in allChargers)
{
if (obj == null) continue;
if(obj.GetComponent<DeathKnightPhantomHit>()!=null)
obj.GetComponent<DeathKnightPhantomHit>().Idle();
Idle();
}
yield return new WaitForSeconds(2f);
// ===== 6⃣ 销毁分身 =====
foreach (var obj in allChargers)
{
if (obj != gameObject)
Destroy(obj);
}
}
void SpawnPhantom(Vector3 pos, Vector3 forward, List<GameObject> list)
{
GameObject phantom = Instantiate(
phantomPrefab,
pos,
Quaternion.LookRotation(forward)
);
var phantomStr=phantom.GetComponent<DeathKnightPhantomHit>();
phantomStr.SetDamage(Data.Atk_3);
list.Add(phantom);
}
public override void Dead()
{
if (isDead)
{
return;
}
GameManager.Ins.curLevel++;
isDead = true;
health = 0;
if (bloodSlider != null)
bloodSlider.gameObject.SetActive(false);
if(ColliderComponent!=null)
ColliderComponent.enabled = false;
if(behaviourTree != null)
behaviourTree.enabled = false;
GameManager.Ins.PlaySound3D("1.53",transform);
foreach (var item in bossCrystals)
{
if(item==null)
continue;
item.SetActive(false);
}
StartCoroutine(DeathDissolve());
}
IEnumerator DeathDissolve()
{
clipQuadObj.SetActive(true);
bloodSlider.gameObject.SetActive(false);
clipQuadObj.transform.localPosition = new Vector3(0, 5f, 0);
houseAnim.SetBool("isDie",true);
bossManAnim.SetBool("isDie",true);
yield return new WaitForSeconds(3f);
clipQuadObj.transform.DOLocalMoveY(-5f, 5);
yield return new WaitForSeconds(8f);
Destroy(gameObject);
GameManager.Ins.WinEndGame();
}
}