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(); } return _ai; } } private AIPath _aiPath; public AIPath aiPath { get { if (_aiPath == null) { _aiPath = GetComponent(); } return _aiPath; } } private BehaviorTree _behaviorTree; public BehaviorTree behaviorTree { get { if (_behaviorTree == null) { _behaviorTree = GetComponent(); } return _behaviorTree; } } private RVOController _rvoController; public RVOController rvoController { get { if (_rvoController == null) { _rvoController = GetComponent(); } return _rvoController; } } private Collider _collider; public Collider selfCollider { get { if (_collider == null) { _collider = GetComponent(); } 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; /// /// 怪物类型 /// #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() { } }