using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.UIElements;
using Debug = UnityEngine.Debug;
using Image = UnityEngine.UI.Image;
using DG.Tweening;
public enum Camp
{///
/// 玩家
///
Player,
///
/// 怪物
///
Enemy,
///
/// 中立
///
Neutral
}
///
/// 角色基类,玩家处理事件
///
[ExecuteInEditMode]
public class Role : Fun
{
[Header("Id")] public int id;
[Header("阵营")] public Camp camp ;
[Header("血量")] public float hp = 100f;//血量
private float maxHp;
[Header(("死亡动画编号"))] public int dieIndex=-1;
[Header("hp填充直接扣")] public Image Hpfiil;
[Header("hp填充慢慢扣")] public Image HpfiilYello;
[Header("扣血填充")] public GameObject HpTextPrefab;
[Header("自己的画布")]public Canvas _Canvas;
[Header("自己的图片")] public SpriteRenderer spriteRenderers; // 存储所有的SpriteRenderer组件
[Header("被打的方向")] public int HurtDirectin;
public float Hp
{
get => hp;
set
{
float temp = hp;
hp = value;
// 更新血条显示
if (Hpfiil != null)
{
Hpfiil.fillAmount = hp / maxHp;
// 使用 DOTween 动画平滑过渡血条填充
DOTween.To(() => HpfiilYello.fillAmount, x => HpfiilYello.fillAmount = x, hp / maxHp, 0.8f) // 0.5f 为过渡时间
.SetEase(Ease.InOutQuad); // 使用缓动效果,使血条变化更加平滑
}
// 更新血量文本效果
if (HpTextPrefab != null && hp < maxHp)
{
hit();
Navigation.StopPathDoTween(0.2f); // 停止任何进行中的 DoTween 动画,0.2s为示例值
GameObject go = GameObject.Instantiate(HpTextPrefab, _Canvas.transform);
go.GetComponent().direction = HurtDirectin;
go.GetComponent().CreateText();
go.GetComponent().text = (temp - hp).ToString(); // 显示伤害值
FlashRedEffect(); // 血量减少时的红色闪烁效果
}
// 判断角色是否死亡
if (hp <= 0)
{
die(); // 执行死亡处理
}
}
}
[Header("掉落")] public float gold = 10f;
public float Gold
{
[DebuggerStepThrough]
get => gold;
[DebuggerStepThrough]
set => gold = value;
}
[Header("攻击力")] private float attack = 10f;
public float Attack
{
get => attack;
set => attack = value;
}
[Header("等级")] private int level = 1;
public int Level
{
[DebuggerStepThrough] get => level;
[DebuggerStepThrough] set => level = value;
}
[Header("物理护甲")] public int physicalArmor = 10;//物理护甲
[Header("魔法护甲")] public int magicArmor = 5;//魔法护甲
public List buffList = new List();
[Header("导航组件")] public SimplePathfindingDoTween Navigation;
[System.Serializable ]
public class AnimationList//动画list
{
//[Header("动画是否循环")] public bool isloop = false;
[Header("动画图片")] public List value; // 字典的值
[Header("角色动画帧数间隔(毫秒)")] public int CharacterAnimationFrameInterval = 50;
}
[Header("角色动画")] public List AnimationTree = new List();
[Header("角色动画播放")] public int animationHighlight = 0;
[Header("角色精灵位置")] public SpriteRenderer spriteRenderer;
[Header("角色Image位置")] public Image image;
public delegate void AnimationItem(int AnimationItem);
public event AnimationItem OnAnimationStart;
public event AnimationItem OnAnimationIng;
public event AnimationItem OnAnimationEnd;
[Header("动画是否正常播放")] public bool isAnimationPlay = false;//动画是否正常播放
[Header("碰撞体")]public CircleCollider2D mycollider;
[Header("攻击脚本")] public Attack attackClass;
[Header("当前播放图片序列")] public int CurrentIndex;
public int hitIndex = 2;//受击动画索引
public int normalIndex = 0;//移动动画索引
public bool isHit=false;//
public virtual async void Start()
{
maxHp = hp;
if (Application.isPlaying)
{
if (attackClass)
{
attackClass.role = this;
}
UpdateBuff();
//Navigation.MoveToNextWaypoint(gameObject);
}
tag = Enum.GetName(typeof(Camp), camp);
updateAnimation();
//AttackScope=1f;
}
///
/// 角色动画更新
///
public async void updateAnimation()
{
while (true)
{
if (AnimationTree.Count == 0)
{
isAnimationPlay = false;
return;
}
isAnimationPlay = true;
if (animationHighlight >= AnimationTree.Count)
{
animationHighlight = AnimationTree.Count - 1;
}
else if (animationHighlight < 0)
{
animationHighlight = 0;
}
//EditorUtility.SetDirty(this);
List LightSprite = AnimationTree[animationHighlight].value;
if (LightSprite == null)
{
isAnimationPlay = false;
return;
};
OnAnimationStart?.Invoke(animationHighlight);
var lsanimationHighlight = animationHighlight;
foreach (Sprite sprite in LightSprite)
{
if (lsanimationHighlight == animationHighlight)
{
if (image != null)
{
image.sprite = sprite;
}
else if (spriteRenderer != null)
{
spriteRenderer.sprite = sprite;
}
if (animationHighlight >= 0 && animationHighlight < AnimationTree.Count)
{
OnAnimationIng?.Invoke(animationHighlight);
await Task.Delay(AnimationTree[animationHighlight].CharacterAnimationFrameInterval);
}
}
else
{
break;
}
}
OnAnimationEnd?.Invoke(lsanimationHighlight);
if (lsanimationHighlight == dieIndex)
{
SpawnPool.intance.ReturnEnemyToPool(this.gameObject); // 回收当前敌人到池中
ResetAllStatus();
}
if (lsanimationHighlight == hitIndex)
{
animationHighlight = normalIndex;
}
}
}
///
/// 角色死亡
///
public virtual void die()
{
if (Application.isPlaying)
{
animationHighlight = dieIndex;
Navigation.PauseAnimation();
Debug.Log("die");
}
}
///
/// 角色受到攻击
///
public virtual void hit()
{
if (Application.isPlaying)
{
animationHighlight = hitIndex;
}
}
///
/// 角色减速
///
public void SlowDown(float num)
{
Navigation.speedFactor *= num;
}
///
/// 单位更新buff
///
async void UpdateBuff()//单位buff更新
{
while (true)
{
List deleteArr = new List();
foreach (BUff buffItem in buffList)
{
if (buffItem.executionInterval <= 0)
{
buffItem.executionInterval = buffItem.executionInterval_max;
buffItem.Funaction.Invoke(buffItem.value);
}
buffItem.executionInterval -= 0.1f;
buffItem.timeLeft -= 0.1f;
if (buffItem.timeLeft <= 0)
{
deleteArr.Add(buffItem);
}
}
foreach (BUff item in deleteArr)
{
buffList.Remove(item);
}
await Task.Delay(100);//buff检测最小时间0.1秒执行一次
}
}
///
/// 重置角色所有状态
///
public void ResetAllStatus()
{
// 重置血量
Hp = 100f;
// 重置攻击力
Attack = 10f;
// 重置护甲
physicalArmor = 10;
magicArmor = 5;
// 重置等级
Level = 1;
// 重置金币
Gold = 10f;
// 清空 Buff 列表
buffList.Clear();
// 如果有导航组件,停止当前的导航行为
if (Navigation != null)
{
//Navigation.Stop(); // 假设你有 Stop 方法来停止导航
}
// 重置角色动画
animationHighlight = 0;
isAnimationPlay = false;
// 重置碰撞体(根据需求是否需要调整)
if (mycollider != null)
{
mycollider.enabled = true; // 启用碰撞体
}
// 如果有其他需要重置的状态,可以在这里添加
}
private void FlashRedEffect()
{
// 遍历所有的SpriteRenderer组件,让它们变红
if (spriteRenderer != null)
{
spriteRenderer.DOColor(UnityEngine.Color.red, 0.2f)
.OnComplete(() =>
{
// 恢复原始颜色
spriteRenderer.DOColor(UnityEngine.Color.white, 0.2f);
});
}
}
public void StopDoTween(float stopTime)
{
// 暂停当前的动画
transform.DOPause();
// 插入一个自定义的延迟(僵直时间)
DOTween.To(() => 0f, x => { }, 0f, stopTime).OnKill(() =>
{
// 在延迟结束后恢复动画
transform.DOPlay();
});
}
}