Files
MRCS/Assets/_MrCs/Scripts/Enemys/Enemy.cs
2025-11-04 14:51:46 +08:00

309 lines
7.2 KiB
C#

using System.Net;
using System.Buffers;
using System.Security.Cryptography.X509Certificates;
using BehaviorDesigner.Runtime;
using DragonLi.Core;
using Mirror;
using Pathfinding;
using Pathfinding.RVO;
using Unity.XR.PXR;
using UnityEngine;
using BehaviorDesigner.Runtime.Tasks;
using TMPro;
using DarkTonic.MasterAudio;
public enum EnemyState
{
// 出生
Borning = 0,
// 强走
Charge = 1,
// 搜索
Search = 2,
// 行军
Run = 3,
// 攻击
Atk = 4,
// 死亡
Die = 99,
}
public class Enemy : Agent
{
private IAstarAI _ai;
public IAstarAI ai
{
get
{
if (_ai == null)
{
_ai = GetComponent<IAstarAI>();
}
return _ai;
}
}
private AIPath _aiPath;
public AIPath aiPath
{
get
{
if (_aiPath == null)
{
_aiPath = GetComponent<AIPath>();
}
return _aiPath;
}
}
private BehaviorTree _behaviorTree;
public BehaviorTree behaviorTree
{
get
{
if (_behaviorTree == null)
{
_behaviorTree = GetComponent<BehaviorTree>();
}
return _behaviorTree;
}
}
private RVOController _rvoController;
public RVOController rvoController
{
get
{
if (_rvoController == null)
{
_rvoController = GetComponent<RVOController>();
}
return _rvoController;
}
}
private Collider _collider;
public Collider selfCollider
{
get
{
if (_collider == null)
{
_collider = GetComponent<Collider>();
}
return _collider;
}
}
public Transform weakness;
[Header("死亡音效")]
[SoundGroup]
public string dieSound;
public GameObject explosion_prefab;
[Header("编号")]
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
[SyncVar]
public int id = 0;
/// <summary>
/// 怪物类型
/// </summary>
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
[SyncVar]
public EnemyType type;
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
public EnemyState state;
[Header("等级")]
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
[SyncVar]
public int lvl = 0;
[Header("速度")]
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
[SyncVar]
public float speed = 0;
[Header("攻击力")]
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
[SyncVar]
public float atk = 0;
[Header("高度")]
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
public float height = 0;
[Header("韧性")]
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
public float toughness = 0;
#if UNITY_EDITOR
[UnityEngine.DisplayOnly]
#endif
public GameObject target = null;
private bool updateAniamtorSpeedvalue = false;
private bool updateAniamtorSpeedFvalue = false;
private bool updateAniamtorSpeedRvalue = false;
public void Awake()
{
InitAnimator();
}
public virtual void Update()
{
if (isServer && IsAlive)
{
if (aiPath != null & aiPath.enabled)
{
UpdateAniamtorValues(aiPath.velocity);
}
else if (RigidbodyComponent)
{
UpdateAniamtorValues(RigidbodyComponent.velocity);
}
UpdateRotation();
OnUpdate();
}
}
[Server]
public virtual void OnSpawn(int id, EnemyType type, int lvl)
{
base.OnSpawn();
this.id = id;
this.type = type;
state = EnemyState.Borning;
this.lvl = lvl;
EnemyInfo enemyInfo = GameManager.Ins.EnemyInfos[type][lvl];
speed = enemyInfo.Speed;
atk = enemyInfo.Atk;
health = enemyInfo.Hp;
originHealth = enemyInfo.Hp;
height = enemyInfo.Height;
ai.radius = enemyInfo.Radius;
toughness = enemyInfo.Toughness;
aiPath.enabled = true;
aiPath.maxSpeed = speed;
rvoController.enabled = true;
behaviorTree.enabled = true;
if (selfCollider != null) selfCollider.enabled = true;
GameManager.Ins.CreateEnemyUI(this);
}
private void InitAnimator()
{
if (AnimatorComponent == null)
{
return;
}
AnimatorControllerParameter[] parameters = AnimatorComponent.parameters;
foreach (AnimatorControllerParameter val in parameters)
{
if ((int)val.type == 1)
{
switch (val.name)
{
case "speed":
updateAniamtorSpeedvalue = true;
break;
case "speedr":
updateAniamtorSpeedRvalue = true;
break;
case "speedf":
updateAniamtorSpeedFvalue = true;
break;
}
}
}
}
protected void UpdateAniamtorValues(Vector3 vel)
{
if (AnimatorComponent != null)
{
if (updateAniamtorSpeedvalue)
{
AnimatorComponent.SetFloat("speed", vel.magnitude);
}
Vector3 val;
if (updateAniamtorSpeedFvalue)
{
val = Vector3.Project(vel, transform.forward);
float num = val.magnitude / (vel.magnitude * (float)((!(Vector3.Angle(vel, transform.forward) > 90f)) ? 1 : (-1)));
AnimatorComponent.SetFloat("speedf", num);
}
if (updateAniamtorSpeedRvalue)
{
val = Vector3.Project(vel, transform.right);
float num2 = val.magnitude / (vel.magnitude * (float)((!(Vector3.Angle(vel, transform.right) > 90f)) ? 1 : (-1)));
AnimatorComponent.SetFloat("speedr", num2);
}
}
}
public virtual void UpdateRotation()
{
if (target != null)
{
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(target.transform.position - transform.position), Time.deltaTime * 10);
}
}
public override void Die(object info, Transform _sender)
{
GameManager.Ins.DeleteEnemyUI(id);
state = EnemyState.Die;
if (selfCollider != null) selfCollider.enabled = false;
behaviorTree.enabled = false;
aiPath.enabled = false;
rvoController.enabled = false;
AnimatorComponent.SetBool("dead", true);
PlaySound(dieSound);
}
[ClientRpc]
public void PlaySound(string sound)
{
MasterAudio.PlaySound3DAtVector3(sound, transform.position);
}
public void CreatExplosion()
{
GameObject explosion = Instantiate(explosion_prefab);
NetworkServer.Spawn(explosion);
explosion.transform.position = transform.position;
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(explosion);
}, 2F);
}
public virtual void Shoot() { }
}