272 lines
8.4 KiB
C#
272 lines
8.4 KiB
C#
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();
|
||
}
|
||
}
|
||
}
|
||
}
|