265 lines
7.5 KiB
C#
265 lines
7.5 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using DragonLi.Core;
|
|
using DragonLi.Frame;
|
|
using EPOOutline;
|
|
using UnityEngine;
|
|
|
|
public class EnemyComponent : MonoBehaviour,IDamagable
|
|
{
|
|
[Header("References")]
|
|
public Transform showPos; // 子弹和火光生成位置
|
|
public Enemy parentEnemy; // 父级敌人
|
|
public GameObject bulletPre; // 子弹预制体
|
|
public GameObject firePre; // 火焰特效预制体 (Muzzle Flash)
|
|
public GameObject explosionPre; // 爆炸特效预制体
|
|
|
|
public BoxCollider boxCollider;
|
|
|
|
[Header("Settings")]
|
|
[Range(0f, 1f)]
|
|
public float hpPercentage = 0.1f; // 本组件血量占父体总血量的比例
|
|
public float fireInterval = 0.5f; // 射击间隔 (秒)
|
|
public float bulletSpeed = 20f; // 子弹飞行速度
|
|
public float aimRadius = 1.5f; // 以玩家为中心的随机子弹目标半径
|
|
public bool isLookPlayer;
|
|
|
|
public bool isQteComponent;//是否是Qte组件
|
|
|
|
private bool _isStartLookPlayer;
|
|
|
|
public bool isDead;
|
|
public bool isFire;
|
|
|
|
[Header("Runtime State")]
|
|
public float hp;// 实际血量
|
|
|
|
private float _nextShootTime;
|
|
private Outlinable outlinable;
|
|
private Transform _player;
|
|
|
|
|
|
public float Health { get; set; }
|
|
void Awake()
|
|
{
|
|
outlinable = GetComponent<Outlinable>();
|
|
if (outlinable != null) outlinable.enabled = false;
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
// 初始化血量
|
|
if (parentEnemy != null||!isQteComponent)
|
|
hp = parentEnemy.health * hpPercentage;
|
|
// 缓存玩家Transform
|
|
GameObject playerObj = GameManager.Ins.player;
|
|
if (playerObj != null)
|
|
_player = playerObj.transform;
|
|
|
|
_nextShootTime = Time.time;
|
|
isDead = false;
|
|
isFire = false;
|
|
_isStartLookPlayer = false;
|
|
}
|
|
|
|
public void Play()
|
|
{
|
|
if(isDead) return;
|
|
isFire = true;
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
isFire = false;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (parentEnemy.health <= 0)
|
|
{
|
|
isDead = true;
|
|
}
|
|
if (_player == null|| isDead) return;
|
|
if(!isFire) return;
|
|
|
|
if (isLookPlayer|| _isStartLookPlayer)
|
|
{
|
|
// 朝向玩家
|
|
Vector3 dir = (_player.position - transform.position).normalized;
|
|
transform.rotation = Quaternion.LookRotation(dir);
|
|
}
|
|
|
|
// 射击控制
|
|
if (Time.time >= _nextShootTime)
|
|
{
|
|
// 计算子弹目标点:以玩家位置为中心的随机范围
|
|
Vector2 randCircle = Random.insideUnitCircle * aimRadius;
|
|
Vector3 targetPos = _player.position + new Vector3(randCircle.x, 0, randCircle.y);
|
|
EnemyShoot(targetPos);
|
|
_nextShootTime = Time.time + fireInterval;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 外部调用射击
|
|
/// </summary>
|
|
public void EnemyShoot(Vector3 targetPos)
|
|
{
|
|
if(isDead) return;
|
|
CmdFire(targetPos);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 执行射击逻辑
|
|
/// </summary>
|
|
private void CmdFire(Vector3 targetPos)
|
|
{
|
|
// 火光特效
|
|
if (firePre != null && showPos != null)
|
|
Instantiate(firePre, showPos.position, showPos.rotation, transform);
|
|
|
|
if (bulletPre == null || showPos == null || _player == null)
|
|
return;
|
|
|
|
// 生成子弹
|
|
GameObject bullet = Instantiate(bulletPre, showPos.position, Quaternion.identity);
|
|
bullet.SetActive(true);
|
|
if (bullet.GetComponent<EnemyBullet>())
|
|
{
|
|
bullet.GetComponent<EnemyBullet>().targetPos=targetPos;
|
|
}
|
|
Rigidbody rb = bullet.GetComponent<Rigidbody>();
|
|
if (rb != null)
|
|
{
|
|
Vector3 shootDir = (targetPos - showPos.position).normalized;
|
|
rb.velocity = shootDir * bulletSpeed;
|
|
}
|
|
|
|
// 自动销毁子弹,避免泄漏
|
|
Destroy(bullet, 5f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 组件受到伤害
|
|
/// </summary>
|
|
public void TakeDamage(float damage,bool isBao,Transform target)
|
|
{
|
|
// 自身血量减少
|
|
hp -= damage;
|
|
|
|
// 通知父体每次受击减少血量
|
|
if (parentEnemy != null&& !isQteComponent)
|
|
parentEnemy.ChangeHp(damage,isBao,target);
|
|
|
|
// 血量不足时,触发死亡
|
|
if (hp <= 0f)
|
|
{
|
|
hp = 0f;
|
|
Die();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 组件死亡,触发爆炸并销毁自身
|
|
/// </summary>
|
|
private void Die()
|
|
{
|
|
if(boxCollider!=null)
|
|
boxCollider.enabled = false;
|
|
isFire = false;
|
|
isDead = true;
|
|
enabled = false;
|
|
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
|
{
|
|
if (explosionPre != null)
|
|
Instantiate(explosionPre, transform.position, transform.rotation);
|
|
}, 2.5f);
|
|
}
|
|
|
|
public void ApplyDamage(float value, object info, Transform sender)
|
|
{
|
|
TakeDamage(value,(bool)info,sender);
|
|
}
|
|
|
|
public void StatQteAttack()
|
|
{
|
|
_isStartLookPlayer = true;
|
|
boxCollider.enabled = true;
|
|
}
|
|
|
|
public void QteAttack()
|
|
{
|
|
EnemyShoot(GameManager.Ins.player.transform.position);
|
|
}
|
|
|
|
public void StopQteAttack()
|
|
{
|
|
_isStartLookPlayer = false;
|
|
}
|
|
|
|
public float arcHeight = 2f; // 抛物线最高点高度
|
|
public float flightTime = 1.2f; // 导弹飞行时长
|
|
//抛物线攻击
|
|
public void ShootMissile(Vector3 from, Vector3 to, float flightTime = 1.2f)
|
|
{
|
|
GameObject m = Instantiate(bulletPre, from, Quaternion.identity);
|
|
LeviathanBullet arc = m.GetComponent<LeviathanBullet>();
|
|
arc.Initialize(from, to, flightTime);
|
|
}
|
|
|
|
//弧度攻击
|
|
public void FireThreeMissiles(Vector3 from, Vector3 to)
|
|
{
|
|
var go = Instantiate(bulletPre, from, Quaternion.identity);
|
|
var sm = go.GetComponent<LeviathanBullet>();
|
|
sm.Initialize(
|
|
startPos: from,
|
|
targetPos: to,
|
|
flightTime: flightTime,
|
|
arcHeight: arcHeight
|
|
);
|
|
}
|
|
|
|
//激光攻击
|
|
public IEnumerator FireQteMissiles()
|
|
{
|
|
Debug.LogError("显示激光");
|
|
var go = Instantiate(bulletPre, showPos.position, Quaternion.identity);
|
|
LineRenderer lr= go.GetComponent<LineRenderer>();
|
|
if (lr != null)
|
|
{
|
|
lr.SetPosition(0, showPos.position);
|
|
lr.SetPosition(1, GameManager.Ins.player.transform.position);
|
|
}
|
|
yield return new WaitForSeconds(1f);
|
|
GameManager.Ins.player.GetComponent<IDamagable>().ApplyDamage(GameManager.Ins.player.GetComponent<Player>().Health,null,null);
|
|
yield return new WaitForSeconds(1.5f);
|
|
Destroy(go);
|
|
}
|
|
|
|
|
|
public void CmdFire2(Vector3 targetPos)
|
|
{
|
|
// 火光特效
|
|
if (firePre != null && showPos != null)
|
|
Instantiate(firePre, showPos.position, showPos.rotation, transform);
|
|
|
|
if (bulletPre == null || showPos == null || _player == null)
|
|
return;
|
|
|
|
// 生成子弹
|
|
GameObject bullet = Instantiate(bulletPre, showPos.position, Quaternion.LookRotation(targetPos - showPos.position));
|
|
bullet.SetActive(true);
|
|
|
|
// 设置飞行方向
|
|
if (bullet.TryGetComponent<BossBullet>(out var enemyBullet))
|
|
{
|
|
enemyBullet.SetTarget(targetPos, bulletSpeed);
|
|
}
|
|
|
|
// 自动销毁子弹,避免泄漏
|
|
Destroy(bullet, 5f);
|
|
}
|
|
|
|
}
|