using Spine.Unity; using Spine; using System.Collections; using System.Collections.Generic; using UnityEngine; public enum CharacterState { None = 0, Idle = 1, Run = 2, Rise = 3,//空中上升 Fall = 4,//空中下落 Hurt = 5, Attack = 6, KeepAttack = 7, Summon = 8, Rush = 9, Sprint = 10, Die = 11, Weak = 12, PullRope = 13, Spirits = 14, //召唤英灵 Float = 15, //空中漂浮 FindPlayer = 16, //寻找玩家 ReadyToRush = 17, //瞄准准备冲刺 ReadyToDownRush = 18, //准备落地冲刺 DownRush = 19, //落地冲刺 FinishRush = 20, //结束冲刺 Coma = 21, //昏迷 RushAttack, //带攻击的冲刺 Transfiguration = 23, //变身 } public enum AttackType { Melee = 0,//近战 Shoot = 1,//射击 Dash = 2, //英灵刺客 } public enum HpUpType { Degree = 0, Add = 1, Fixed = 2, } public class Character : MonoBehaviour { public bool isTran; public PlayerController pc; public bool isSpirit; public GameObject[] HitCols; public int cookNum; //能做成多少串肉 public SkeletonMecanim mecanim; public Skeleton skeleton; public MeshRenderer meshRenderer; public Animator ani; public Animator aniCollider; public Rigidbody rb; public Transform bodyTrans; public BeSearchTrigger beSearchTrigger; public UIHP uiHp; public CharacterState state; [HideInInspector] public float attackTime; public float totalAttack1Time = 0.5f; public float totalAttack2Time = 0.5f; public bool isNonAttack = false; public HpUpType hptp; public bool isDie = false; public int totalHp = 100; public int hp; public List attack1Infos; public List attack2Infos; public List attackTriggers; public AttackType attackType; public GameObject bulletPrefab; public List shootPos; [HideInInspector] public float dieKeepTime; public float totalDieKeepTime = 2f; public Character attackTarget; public bool shootTrack = false; [HideInInspector] public float invincibleTime; public float totalInvincibleTime = 2f; public Character targetCharacter; public List beTargetCharacter = new List(); //被哪些锁定 public SearchTrigger searchTrigger; public List targetTypes; public bool canHitFly; public bool linked; public RopeJoint joint; public CharacterRope rope; public bool hasHpUp = false; private float toLargeSize = 0; private Vector3 speed = new Vector3(1, 1, 0); public bool beLarger = false; public bool canHitFloat; //是否概率使敌方漂浮 public float floatProbability; //漂浮概率 public bool attackToFloat = false; //攻击使敌方漂浮 public int floatTimes; //漂浮次数 public int hasFloatTimes; //public bool isSoulUnstable; //灵魂不稳定状态 //public float soulUnstableTime; //灵魂不稳定状态时间 public float criticalChance; //暴击率 public float criticalMultiplier; //暴击倍率 public virtual void Init() { if (!mecanim) { mecanim = GetComponentInChildren(); } if (mecanim && skeleton == null) { skeleton = mecanim.skeleton; } if (!meshRenderer) { meshRenderer = mecanim.GetComponent(); } if (!ani) { ani = GetComponentInChildren(); } hp = totalHp; if (!isNonAttack) { uiHp.Show(hp, totalHp); } ChangeState(CharacterState.Idle); linked = false; if (joint) { Destroy(joint); joint = null; } if (rope) { rope = null; } } public virtual void FixedUpdate() { OnState(); } private void OnEnable() { for (int i = 0; i < attackTriggers.Count; i++) { attackTriggers[i].gameObject.SetActive(false); } } public void Turn() { bodyTrans.localScale = new Vector3(-bodyTrans.localScale.x, bodyTrans.localScale.y, bodyTrans.localScale.z); } public virtual void OnState() { } public virtual void ChangeState(CharacterState newState) { } public virtual void BeHit(int damage, Vector3 force, bool changeHurt, float repelValue) { if (invincibleTime > 0) { return; } hp -= damage; uiHp.Show(hp, totalHp); if (hp <= 0) { rb.AddForce(force); ChangeState(CharacterState.Die); return; } } public virtual void AttackShootEvent(int attackId, int shootId) { AttackInfo attackInfo; if (attackId == 1) { attackInfo = attack1Infos[shootId]; } else { attackInfo = attack2Infos[shootId]; } GameObject bulletObj = PoolManager.Instantiate(bulletPrefab); Bullet bullet = bulletObj.GetComponent(); if (attackToFloat) { bullet.toFloat = true; } Vector3 attackDir = attackInfo.attackDir.normalized; if (bodyTrans.localScale.x < 0) { attackDir.x = -attackDir.x; } bullet.BeShoot(this, shootPos[shootId].position, attackDir, attackInfo.damage, attackInfo.force, attackInfo.changeHurt, attackInfo.repelValue, shootTrack, attackTarget ? attackTarget : null); } public virtual Vector3 GetMoveDir() { Vector3 moveDir = Vector3.zero; return moveDir; } public virtual void Attack1() { ani.Play("attack_summon", 0, 0); if (!isNonAttack) { aniCollider.Play("Attack1", 1, 0); attackTime = totalAttack1Time; switch (attackType) { case AttackType.Melee: for (int i = 0; i < attack1Infos.Count; i++) { attackTriggers[i].damage = attack1Infos[i].damage; attackTriggers[i].changeHurt = attack1Infos[i].changeHurt; attackTriggers[i].repelValue = attack1Infos[i].repelValue; Vector3 attackDir = attack1Infos[i].attackDir.normalized; if (bodyTrans.localScale.x < 0) { attackDir.x = -attackDir.x; } attackTriggers[i].force = attackDir * attack1Infos[i].force; } break; case AttackType.Shoot: case AttackType.Dash: break; default: break; } ChangeState(CharacterState.Attack); } } public virtual void Attack2() { if (canHitFloat) { float k = Random.Range(0, 100); if (hasFloatTimes == 0 || k <= floatProbability) { attackToFloat = true; } } Vector3 leftDir = GetMoveDir(); if (leftDir.x > 0.3f) { if (bodyTrans.localScale.x > 0) { Turn(); } } else if (leftDir.x < -0.3f) { if (bodyTrans.localScale.x < 0) { Turn(); } } ani.Play("attack_march", 0, 0); aniCollider.Play("Attack2", 1, 0); attackTime = totalAttack2Time; switch (attackType) { case AttackType.Melee: case AttackType.Dash: for (int i = 0; i < attack2Infos.Count; i++) { attackTriggers[i].damage = attack2Infos[i].damage; attackTriggers[i].changeHurt = attack2Infos[i].changeHurt; attackTriggers[i].repelValue = attack2Infos[i].repelValue; Vector3 attackDir = attack2Infos[i].attackDir.normalized; if (bodyTrans.localScale.x < 0) { attackDir.x = -attackDir.x; } attackTriggers[i].force = attackDir * attack2Infos[i].force; } break; case AttackType.Shoot: break; default: break; } ChangeState(CharacterState.Attack); } public void SetSortingOrder(int order) { meshRenderer.sortingOrder = order; } public void HpUp(float value, float larger) { int add = 0; switch (hptp) { case HpUpType.Degree: value = value / 100; add = (int)(totalHp * value); break; case HpUpType.Add: add = (int)value; break; case HpUpType.Fixed: add = (int)(totalHp - value); break; } totalHp += add; hp += add; uiHp.Show(hp, totalHp); float cur = transform.localScale.x; toLargeSize = cur * larger; beLarger = true; } public void Enlarge() { transform.localScale = Vector3.SmoothDamp(transform.localScale, new Vector3(1, 1, 1) * toLargeSize, ref speed, 0.3f); if (transform.localScale.x >= toLargeSize + 0.1f) { beLarger = false; transform.localScale = new Vector3(toLargeSize, toLargeSize, 1); toLargeSize = 0; //print(transform.localScale); } } }