Files
Loong/Assets/_Loong/Scripts/Enemys/DragonBoss/LightingDragon.cs

272 lines
8.4 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.Collections;
using System.Collections.Generic;
using DamageNumbersPro;
using DamageNumbersPro.Demo;
using DarkTonic.MasterAudio;
using DG.Tweening;
using DragonLi.Core;
using UnityEngine;
public class LightingDragon : Enemy
{
public Launcher mouth;
public Transform model;
public Transform enemyUI;
[SoundGroup] public string flySound;
[SoundGroup] public string beHited;
[Header("死亡音效")][SoundGroup] public string dieSound;
private int _fireTime = 0;
private float _rotation = -190f;
public Transform createGuardEnemyPos;
private bool isCreateGuard;
private int spawnCount = 8; // 召唤数量
[Header("传送门特效")]
public GameObject portalPrefab; // 传送门预制体
public float portalDuration = 3f; // 传送门持续时间
public float spawnIntervalMin = 0.2f; // 每条小龙生成间隔(最小)
public float spawnIntervalMax = 0.5f; // 每条小龙生成间隔(最大)
private List<Vector3> usedPositions = new List<Vector3>();
private bool isSummoning = false; // 是否正在召唤中
private List<Enemy> currentGuards = new List<Enemy>(); // 当前召唤的小龙列表
public override void OnSpawn(int id, EnemyType type, int lvl)
{
base.OnSpawn(id, type, lvl);
StartCoroutine(AutoSummonRoutine());
}
public override void Update()
{
base.Update();
//if (isAlive)
//{
// UpdateLookRotation();
//}
//最简单直接的转向
if (isAlive && GameManager.Ins._player != null && state == EnemyState.Atk)
{
Vector3 direction = GameManager.Ins._player.transform.position - transform.position;
direction.y = 0;
if (direction != Vector3.zero)
{
// 直接设置旋转,不使用插值
transform.rotation = Quaternion.LookRotation(direction);
}
}
}
/// <summary>
/// 造成一次伤害
/// </summary>
/// <param name="value"></param>
/// <param name="info"></param>
/// <param name="sender"></param>
public override void ApplyDamage(float value, int ownerIndex, Vector3 hitPos, Transform sender)
{
if (isAlive)
{
// 生成伤害数字
// DNP_PrefabSettings settings = DNP_DemoManager.instance.GetSettings();
DamageNumber prefab = MRDamage.Ins.GetCurrent();
DamageNumber newDamageNumber = prefab.Spawn(hitPos, value);
// 受击音效
MasterAudio.PlaySound(beHited);
// //Apply Demo Settings:
// settings.Apply(newDamageNumber);
Health -= OnReceiveDamage(value, ownerIndex, hitPos, sender);
if (!isAlive)
{
Die(ownerIndex, sender);
}
}
}
public override void Die(object info, Transform _sender)
{
Debug.Log("死亡");
enemyUI.gameObject.SetActive(false);
base.Die(info, _sender);
model.DOLocalMoveY(0, 0.5f).OnComplete(() =>
{
Debug.Log("坠落");
AnimatorComponent.SetBool("dead", false);
AnimatorComponent.SetBool("down", true);
GameManager.Ins.PlayNarration16();
MasterAudio.PlaySound(dieSound);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
CloseAllGuards();
GameManager.Ins.ShowDragonSoul(transform);
model.DOLocalMoveY(-5, 6f).OnComplete(() =>
{
Debug.Log("沉入地下");
Destroy(gameObject);
GameManager.Ins.curBossId++;
Vector3 pos = GameManager.Ins.bossPos[GameManager.Ins.curBossId].transform.position;
// 创建鱼龙
GameManager.Ins.CreateEnemy(EnemyType.BlackDragon, pos, -190f);
});
}, 3f);
});
}
//public void UpdateLookRotation()
//{
// if (GameManager.Ins._player != null && state == EnemyState.Atk)
// {
// Vector3 lookDir = GameManager.Ins._player.transform.position - transform.position;
// lookDir.y = 0;
// transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(lookDir), Time.deltaTime * 20);
// }
//}
/// <summary>
/// 普通攻击一次
/// </summary>
public void FireOnce()
{
Debug.Log("喷弹");
_fireTime += 1;
//_rotation += _fireTime * 10;
if (_fireTime == 3)
{
//_rotation = -190;
_fireTime = 0;
}
mouth.Shoot();
}
public void FlyVoice()
{
MasterAudio.PlaySound(flySound);
}
public override void CreateGuard()
{
base.CreateGuard();
if (isSummoning) return;
if(GameManager.Ins.isGameEnd) return;
isSummoning = true;
base.CreateGuard();
StartCoroutine(SummonRoutine(EnemyType.LightingDragonGuard));
}
public override void CloseGuard()
{
base.CloseGuard();
foreach (var item in currentGuards)
{
Destroy(item.gameObject);
}
}
public void CloseAllGuards()
{
foreach (var item in currentGuards)
{
item.Die(null,GameManager.Ins._player.transform);
}
CleanupGuardList(); // 清除已经死亡的引用
}
/// <summary>
/// 召唤守卫小龙
/// </summary>
IEnumerator SummonRoutine(EnemyType curType)
{
// 1⃣ 生成传送门
GameObject portal = Instantiate(portalPrefab, createGuardEnemyPos.position, Quaternion.identity);
portal.transform.localScale = Vector3.zero;
portal.transform.DOScale(Vector3.one * 1.5f, 0.5f);
yield return new WaitForSeconds(0.5f);
usedPositions.Clear();
// 2⃣ 分批生成小龙
for (int i = 0; i < spawnCount; i++)
{
if (state != EnemyState.Die)
{
Vector3 spawnPos = GetSpawnPositionAroundPortal(portal.transform.position);
GameObject dragonObj = GameManager.Ins.CreateEnemy(curType, spawnPos, -190);
dragonObj.transform.localScale = Vector3.zero;
dragonObj.transform.DOScale(1f, 0.3f);
dragonObj.transform.DOMoveY(dragonObj.transform.position.y + 1f, 0.5f).SetLoops(2, LoopType.Yoyo);
Enemy e = dragonObj.GetComponent<Enemy>();
if (e != null)
currentGuards.Add(e);
}
yield return new WaitForSeconds(Random.Range(spawnIntervalMin, spawnIntervalMax));
}
// 3⃣ 传送门关闭
portal.transform.DOScale(Vector3.zero, 0.5f).OnComplete(() => Destroy(portal));
// 延迟一点点再允许下次召唤
yield return new WaitForSeconds(1f);
isSummoning = false;
}
/// <summary>
/// 清理死亡的小龙引用
/// </summary>
private void CleanupGuardList()
{
currentGuards.RemoveAll(g => g == null || !g.isAlive);
}
/// <summary>
/// 获取不重叠的生成点(围绕传送门)
/// </summary>
Vector3 GetSpawnPositionAroundPortal(Vector3 center)
{
Vector3 pos = center;
int safety = 0;
while (safety < 10)
{
Vector2 circle = Random.insideUnitCircle * 2f; // 半径2米内
pos = new Vector3(center.x + circle.x, center.y, center.z + circle.y);
bool tooClose = usedPositions.Exists(p => Vector3.Distance(p, pos) < 1.5f);
if (!tooClose)
{
usedPositions.Add(pos);
break;
}
safety++;
}
return pos;
}
/// <summary>
/// 自动循环召唤每30-60秒
/// </summary>
IEnumerator AutoSummonRoutine()
{
while (isAlive&& !GameManager.Ins.isGameEnd)
{
float waitTime = Random.Range(5f, 10f);
yield return new WaitForSeconds(waitTime);
// 如果上一批还活着,不召唤
CleanupGuardList(); // 清除已经死亡的引用
if (currentGuards.Count == 0 && !isSummoning)
{
CreateGuard();
}
}
}
}