UnityCommon/Role/Role.cs
2024-12-16 17:48:50 +08:00

327 lines
8.7 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 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
{/// <summary>
/// 玩家
/// </summary>
Player,
/// <summary>
/// 怪物
/// </summary>
Enemy,
/// <summary>
/// 中立
/// </summary>
Neutral
}
/// <summary>
/// 角色基类,玩家处理事件
/// </summary>
[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("扣血填充")] public GameObject HpTextPrefab;
[Header("自己的画布")]public Canvas _Canvas;
[Header("自己的图片")] public SpriteRenderer spriteRenderers; // 存储所有的SpriteRenderer组件
public float Hp
{
get => hp;
set
{
float temp = hp;
hp = value;
if (Hpfiil!=null)
{
Hpfiil.fillAmount = hp / maxHp;
}
if (HpTextPrefab != null&& hp<maxHp)
{
GameObject go = GameObject.Instantiate(HpTextPrefab, _Canvas.transform);
go.GetComponent<Text>().text= (temp - hp).ToString();
FlashRedEffect();
StopDoTween(0.2f);
}
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<BUff> buffList = new List<BUff>();
[Header("导航组件")] public SimplePathfindingDoTween Navigation;
[System.Serializable ]
public class AnimationList//动画list
{
//[Header("动画是否循环")] public bool isloop = false;
[Header("动画图片")] public List<Sprite> value; // 字典的值
[Header("角色动画帧数间隔(毫秒)")] public int CharacterAnimationFrameInterval = 50;
}
[Header("角色动画")] public List<AnimationList> AnimationTree = new List<AnimationList>();
[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 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;
}
/// <summary>
/// 角色动画更新
/// </summary>
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<Sprite> 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();
}
}
}
/// <summary>
/// 角色死亡
/// </summary>
public virtual void die()
{
if (Application.isPlaying)
{
animationHighlight = dieIndex;
Navigation.PauseAnimation();
Debug.Log("die");
}
}
/// <summary>
/// 单位更新buff
/// </summary>
async void UpdateBuff()//单位buff更新
{
while (true)
{
List<BUff> deleteArr = new List<BUff>();
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秒执行一次
}
}
/// <summary>
/// 重置角色所有状态
/// </summary>
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();
});
}
}