Files
XMen/Assets/Scripts/Enemys/Shadow/Shadow.cs
2025-07-10 14:49:53 +08:00

245 lines
5.7 KiB
C#

using BehaviorDesigner.Runtime;
using DG.Tweening;
using DragonLi.Core;
using DragonLi.Frame;
using Mirror;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class Shadow : XAgent
{
public BehaviorTree behavior;
public float xSpeed = 10f;
public float xAcc = 30f;
public float xHealth = 100f;
public float xAtk = 10;
public float attackArea = 2.0f;
public SkinnedMeshRenderer[] models;
public MeshRenderer[] swords;
public BloodSlider BloodSlider;
public GameObject explosion_prefab;
public float explosion_despawn_time = 4f;
private List<GameObject> casts = new List<GameObject>();
public AudioSource enemyAudio;
public AudioClip atkClip;
[Server]
public override void OnSpawn()
{
base.OnSpawn();
NavAgent.enabled = true;
behavior.enabled = true;
ColliderComponent.enabled = true;
behavior.RegisterEvent("Attack", Attack);
behavior.RegisterEvent("Cast", Cast);
DOVirtual.Float(0, 255, 1f, (res) =>
{
UpdateFade(res);
});
}
public void SetPathId(string pathid)
{
transform.GetComponent<BehaviorTree>().SetVariableValue("pathId", pathid);
}
[Server]
internal override void Update()
{
base.Update();
if (IsAlive && NavAgent.isActiveAndEnabled)
{
//UpdateFade(NavAgent.velocity);
//UpdateUI(NavAgent.velocity);
}
}
private void FixedUpdate()
{
if (IsAlive && isServer)
{
UpdateRotation();
}
}
[Server]
public void Attack()
{
Debug.Log("Attack");
Shield shield = GameManager.Ins.GetCanAttackShield(transform.position, LockPlayer, attackArea);
if (shield != null)
{
shield.ApplyDamage(xAtk, null, null);
}
else
{
if (GameManager.Ins.IsCanAttackPlayer(transform, LockPlayer, attackArea))
{
IDamagable damagable = MRNetworkManager.Ins.roomSlots[LockPlayer].GetComponent<IDamagable>();
if (damagable != null)
{
damagable.ApplyDamage(xAtk, null, transform);
}
};
}
}
[Server]
public override void ApplyDamage(float value, object info, Transform _sender)
{
base.ApplyDamage(value, info, _sender);
if (_sender != null)
{
int ownerIndx = _sender.GetComponent<Bullet>().ownerIndex;
RpcDamage(value, (bool)info, ownerIndx);
}
}
[ClientRpc]
public void RpcDamage(float value, bool info, int ownerIndx)
{
if (GameInit.Ins.self.index == ownerIndx)
{
BloodSlider.CreateDamagePre(value, info);
Debug.Log("收到伤害 ClientRpc:");
}
}
[Server]
public void Cast()
{
if (IsAlive)
{
Debug.Log("召唤");
for (int i = 0; i < 2; i++)
{
Vector3 pos = DragonLi.Frame.Utils.GetNearRandomPositionOnNavmesh(transform.position, 2f);
GameObject cast = GameManager.Ins.GenerateEnemy(EnemyType.ShadowCast, pos, Vector3.zero, new Vector3(0.85F, 0.85F, 0.85F));
casts.Add(cast);
}
}
}
[Server]
public void SpawnExplosion()
{
if (explosion_prefab != null)
{
GameObject explosion = Instantiate(explosion_prefab);
explosion.transform.position = transform.position;
NetworkServer.Spawn(explosion);
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
NetworkServer.Destroy(explosion);
}, Data["explosion_despawn_time"].FloatValue);
}
}
public override void InitData()
{
base.InitData();
type = (int)EnemyType.Shadow;
EnemyInfo enemyInfo = GameManager.Ins.EnemyDescInfos[(int)EnemyType.Shadow];
DifficultyInfo difficultyInfo = GameManager.Ins.DifficultyescInfos[StoryManager.Ins.gameDifficulty];
BloodSlider.SetName(enemyInfo.NameCN);
xHealth = enemyInfo.Hp * difficultyInfo.enemyHpCoefficient * MRNetworkManager.Ins.roomSlots.Count * 0.7f;
xAtk = enemyInfo.Atk * difficultyInfo.damageCoefficient;
//xHealth *= GameManager.Ins.difficulty[GameManager.Ins.players.Count - 1];
Data["health"].FloatValue = xHealth;
OriginHealth = xHealth;
Data["acc"].FloatValue = xAcc;
Data["speed"].FloatValue = xSpeed;
Data["atk"].FloatValue = xAtk;
Data.Add("explosion_despawn_time", new DataRow(SupportDataType.Float)
{
Name = "explosion_despawn_time",
FloatValue = explosion_despawn_time
});
}
private void UpdateFade(float fadeRate)
{
for (int i = 0; i < models.Length; i++)
{
models[i].material.SetFloat("_RongJieIntensity", fadeRate / 255f);
}
for (int i = 0; i < swords.Length; i++)
{
swords[i].material.SetFloat("_RongJieIntensity", fadeRate / 255f);
}
}
private void UpdateRotation()
{
if (IsAlive && (bool)(behavior.GetVariable("face2Player").GetValue()))
{
Transform player = MRNetworkManager.Ins.roomSlots[LockPlayer].transform;
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(player.position - transform.position), 20 * Time.deltaTime);
}
}
[Server]
public override void OnHeathChanged(float currentHealth)
{
base.OnHeathChanged(currentHealth);
HealthChange(currentHealth);
}
[ClientRpc]
public void HealthChange(float currentHealth)
{
if (BloodSlider != null)
{
// Debug.Log("当前血量" + currentHealth);
BloodSlider.SetValue2(currentHealth, OriginHealth);
}
}
[Server]
public override void OnDeath(object info, Transform _sender)
{
ColliderComponent.enabled = false;
AnimatorComponent.SetBool("Dead", true);
DisappearCasts();
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
// DisappearCasts();
NetworkServer.Destroy(transform.gameObject);
SpawnExplosion();
GameManager.Ins.CreateItemDrop(index, transform.position);
if (GameManager.Ins.EnemyDie())
{
StoryManager.Ins.CreateStoryItem();
GameManager.Ins.ShowLandmark(10, 11);
}
}, 3.5f);
}
public void DisappearCasts()
{
foreach (GameObject cast in casts)
{
if (cast != null && !cast.IsDestroyed())
{
cast.GetComponent<IDamagable>().ApplyDamage(9999999f, true, null);
}
}
}
public void PlayAttackClip()
{
enemyAudio.clip = atkClip;
enemyAudio.Play();
}
}