2025-12-27 15:29:20 +08:00

173 lines
4.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

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 DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.AI;
using Random = UnityEngine.Random;
public class Enemy : MonoBehaviour
{
[Tooltip("最小生命值百分比")]
[Range(0, 100)]
public int minHealthPercent = 30;
[Tooltip("最大生命值百分比")]
[Range(0, 100)]
public int maxHealthPercent = 100;
[Tooltip("初始化生命值")]
public int health = 100;
[Tooltip("爆炸音效")]
public AudioClip boomClip;
[Tooltip("爆炸音效的音量")]
public float boomVolumeScale = 1f;
[Tooltip("X角度偏移")]
public float addEulerX = 0f;
[Tooltip("是否开始的时候修改主材质颜色")]
public bool isChangeInitColor = false;
public List<Color> randomColors = new List<Color>()
{
new Color(33f / 255f, 144f /255f, 223f / 255f),
new Color(13f / 255f, 174f /255f, 58f / 255f),
new Color(212f / 255f, 128f /255f, 24f / 255f),
new Color(198f / 255f, 11f /255f, 12f / 255f),
new Color(187f / 255f, 12f /255f, 164f / 255f),
new Color(255f / 255f, 51f /255f, 255f / 255f),
new Color(102f / 255f, 178f /255f, 255f / 255f),
};
public int ToPosIndex { get; set; } = 0;
public Action<int> OnReachDestination = null;
private NavMeshAgent _agent;
// 到达目标的距离阈值根据场景物体大小调整比如角色半径0.5则设为0.6
public float arrivalThreshold = 0.5f;
// 是否已到达目标的标记
private bool _hasReachedDestination = false;
private TextMeshPro _textMeshPro;
private Renderer _renderer;
private void Awake()
{
_renderer = GetComponentInChildren<Renderer>();
if (isChangeInitColor)
{
var color = randomColors[Random.Range(0, randomColors.Count)];
_renderer.material.color = color;
}
_agent = GetComponent<NavMeshAgent>();
health = Mathf.RoundToInt(health * Random.Range(minHealthPercent, maxHealthPercent + 1) * 0.01f);
_textMeshPro = GetComponentInChildren<TextMeshPro>();
//_textMeshPro.color = new Color(1f - color.r, 1f - color.g, 1f - color.b);
if (_textMeshPro != null)
{
_textMeshPro.text = health.ToString();
}
arrivalThreshold = _agent.radius * 1.1f; // 根据Agent半径动态设置阈值
}
// Start is called before the first frame update
void Start()
{
}
public void ResetMaterial()
{
var color = _renderer.material.color;
color.a = 1;
_renderer.material.color = color;
}
public void SetAlphaMaterial()
{
var color = _renderer.material.color;
color.a = 0;
_renderer.material.color = color;
}
// Update is called once per frame
void Update()
{
// 实时检查是否到达目标
CheckIfReachedDestination();
// 示例:到达目标后的逻辑
if (_hasReachedDestination)
{
if (OnReachDestination != null)
{
ToPosIndex++;
OnReachDestination(ToPosIndex);
}
}
}
/// <summary>
/// 检查是否到达目标位置
/// </summary>
private void CheckIfReachedDestination()
{
//// 1. 无目标或无路径时,直接标记为未到达
//if (!_agent.hasPath || _agent.pathStatus != NavMeshPathStatus.PathComplete)
//{
// _hasReachedDestination = false;
// return;
//}
// 2. 有路径时,检查剩余距离
// remainingDistanceAgent当前位置到路径终点的剩余距离
if (_agent.remainingDistance <= arrivalThreshold)
{
// 3. 额外检查是否停止移动(避免因障碍物卡住但剩余距离达标)
//if (!_agent.hasPath || _agent.velocity.sqrMagnitude < 0.01f)
//{
_hasReachedDestination = true;
//}
}
else
{
_hasReachedDestination = false;
}
}
/// <summary>
/// 伤害
/// </summary>
/// <param name="damage">伤害值</param>
/// <returns>返回true表示被击毁false表示还未被击毁</returns>
public bool TakeDamage(int damage)
{
if (!this.IsDestroyed())
{
health -= damage;
health = Mathf.Max(health, 0);
if (_textMeshPro != null)
{
_textMeshPro.text = health.ToString();
}
if (health == 0)
{
Respawn();
return true;
}
}
return false;
}
public void Respawn()
{
if (boomClip != null)
{
AudioTool.AudioSource.PlayOneShot(boomClip, boomVolumeScale);
}
gameObject.transform.DOKill(true);
Global.LockedEnemies.Remove(GetHashCode());
Global.DespawnEnemy(this);
}
}