| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672 |
- using System.Collections.Generic;
- using UnityEngine;
- using System;
- using Sirenix.OdinInspector;
- using DG.Tweening;
- //各个状态
- public enum SpecialState
- {
- Null = -1,
- FloatState = 0,
- BlownUp = 1,
- ShotDown = 2,
- Weak = 3,
- }
- public class AttributeStatus : MonoBehaviour
- {
- //组件
- private MoveCharacter character;
- private Rigidbody rb;
- private Foot foot;
- private HitFeedbackSystem hitFeedbackSystem;
- //behit参数
- [DisplayOnly] public SpecialState curSpecialStates = SpecialState.Null;
- public AttackController.AttackMethod attackMethod;
- [LabelText("控制时间")] [DisplayOnly] public float attributeTime;
- [TabGroup("漂浮")]
- [DisplayOnly] public int floatingState; //0:不漂浮;1:漂浮中;2:飘着;3:掉下去
- private Vector3 origPos; //初始位置
- private float curHeight; //当前所在高度
- private float riseTime; //上升时间
- private float backSpeed; //返回速度
- private float rotateSpeed; //旋转速度
- private float rotateDir; //旋转方向
- private float height; //漂浮高度
- private float rise = 1;
- private float normalFallSpeed = 15f;
- [TabGroup("击飞击落")] [DisplayOnly] public int hitState;
- [TabGroup("击飞击落")] [DisplayOnly] public bool isFly;
- [TabGroup("击飞击落")] [DisplayOnly] public int jumpNum;
- [TabGroup("击飞击落")] [LabelText("弹跳力比例")] public float jumpNumRate;
- [TabGroup("击飞击落")] [LabelText("X方向阻力")] public float decelerationRatioX = 2f;
- [TabGroup("击飞击落")] [LabelText("Y方向重力")] public float decelerationRatioY = 15f;
- public Character landingDamageFrom;
- private Vector3 startFlyPos;
- [TabGroup("击飞击落")] [LabelText("旋转中心高度")] public float rotateCenterHeight = 1f;
- [TabGroup("击飞击落")] [LabelText("起飞预设角度")] public float startFlyAngle = 15f;
- [Tooltip("x为最小值,y为最大值")]
- [TabGroup("击飞击落")] [LabelText("飞行预设角速度随机范围")] public Vector2 flyingRotateSpeedRange = new Vector2(15, 45);
- private float flyingRotateSpeed;
- private Vector3 scale;
- [TabGroup("击飞击落")] [LabelText("压缩程度")] public float compressionDegree = 0.8f;
- [Tooltip("x为向下压缩经过的时间,y为回弹经过的时间")]
- [TabGroup("击飞击落")] [LabelText("压缩速度")] public Vector2 compressionSpeed = new Vector2(0.2f, 0.4f);
- [TabGroup("击飞击落")] [LabelText("弹跳速度")] public float jumpVel = 5f;
- [TabGroup("击飞击落")] private Vector3 flyForce;
- [TabGroup("易伤")]
- [DisplayOnly] public bool haveVulnerable = false;
- [TabGroup("易伤")]
- [DisplayOnly] public float vulnerableRate = 0f;
- [DisplayOnly] public float vulnerableTime;
- [TabGroup("累伤")] [DisplayOnly] public float stackingWoudsTime;
- [TabGroup("累伤")] [DisplayOnly] public float stackingWords;
- //抗性
- [Serializable]
- public struct Resistances
- {
- [LabelText("控制层级")] public int controlOrder;
- //控制效果抗性
- [Range(0, 1)]
- [LabelText("漂浮抗性")]
- public float Float;
- [Range(0, 1)]
- [LabelText("击飞抗性")]
- public float BlowUp;
- [Range(0, 1)]
- [LabelText("击落抗性")]
- public float ShotDown;
- [Range(0, 1)]
- [LabelText("击晕抗性")]
- public float Weak;
- [Space]
- //非控制效果抗性
- [LabelText("护甲值")] public int armor;
- [LabelText("闪避")] public int dodge;
- }
- [LabelText("抗性")] public Resistances resistances;
- public void Init()
- {
- stackingWoudsTime = 0;
- stackingWords = 0;
- }
- private void Awake()
- {
- character = GetComponentInParent<MoveCharacter>();
- rb = character.rb;
- foot = character.foot;
- hitFeedbackSystem = GetComponent<HitFeedbackSystem>();
- scale = character.mecanim.transform.localScale;
- }
- public void Update()
- {
- //易伤
- if (haveVulnerable)
- {
- vulnerableTime -= Time.deltaTime;
- if (vulnerableTime <= 0)
- {
- vulnerableRate = 0f;
- haveVulnerable = false;
- }
- }
- //累伤
- if (stackingWords > 0)
- {
- stackingWoudsTime -= Time.deltaTime;
- if (stackingWoudsTime <= 0)
- {
- stackingWords = 0;
- }
- }
- }
- public void AddSpecialState(AttackController.AttackMethod attackMethod, Character attackFrom)
- {
- if (attackMethod.attackInfo.attackEffect.Count > 0)
- {
- AttackEffect attackEffect = AttackEffect.Null;
- foreach (AttackEffect ae in attackMethod.attackInfo.attackEffect)
- {
- switch (attackMethod.attackInfo.attackEffect[0])
- {
- /*控制*/
- //漂浮
- case AttackEffect.FloatState:
- if (resistances.Float == 1)
- {
- break;
- }
- if (PriorityOrder(SpecialState.FloatState, attackMethod.attackInfo.floatState.ControlOrder))
- {
- attackEffect = AttackEffect.FloatState;
- }
- break;
- //击飞
- case AttackEffect.BlowUp:
- if (resistances.BlowUp == 1)
- {
- break;
- }
- if (!character.nowCanFly)
- {
- if (PriorityOrder(SpecialState.BlownUp,attackMethod.attackInfo.blowUp.ControlOrder))
- {
- attackEffect = AttackEffect.BlowUp;
- }
- }
- break;
- //击落
- case AttackEffect.ShotDown:
- if (resistances.ShotDown == 1)
- {
- break;
- }
- if (character.nowCanFly || !character.canNotShotDown)
- {
- if (PriorityOrder(SpecialState.ShotDown,attackMethod.attackInfo.shotDown.ControlOrder))
- {
- attackEffect = AttackEffect.ShotDown;
- }
- }
- break;
- //击晕
- case AttackEffect.Weak:
- if (resistances.Weak == 1)
- {
- break;
- }
- if (PriorityOrder(SpecialState.Weak,attackMethod.attackInfo.weak.ControlOrder))
- {
- attackEffect = AttackEffect.Weak;
- }
- break;
- }
- }
- if (attackEffect != AttackEffect.Null)
- {
- switch (attackEffect)
- {
- /*控制*/
- //漂浮
- case AttackEffect.FloatState:
- AddFloat(attackMethod);
- break;
- //击飞
- case AttackEffect.BlowUp:
- AddBlowUp(attackMethod, attackFrom.bodyTrans);
- if (attackMethod.attackInfo.blowUp.haveLandingDamage)
- {
- landingDamageFrom = attackFrom;
- }
- break;
- //击落
- case AttackEffect.ShotDown:
- AddShotDown(attackMethod, attackFrom.bodyTrans);
- if (attackMethod.attackInfo.shotDown.haveLandingDamage)
- {
- landingDamageFrom = attackFrom;
- }
- break;
- //击晕
- case AttackEffect.Weak:
- AddWeak(attackMethod);
- break;
- }
- return;
- }
- }
- if (curSpecialStates == SpecialState.Null)
- {
- hitFeedbackSystem.EnterHitStun(attackFrom);
- }
- else
- {
- hitFeedbackSystem.canBeHitStun = false;
- }
- }
- //CharacterState为SpecialStatus时调用此函数
- public void SpecialStateEffect(SpecialState specialState)
- {
- switch (specialState)
- {
- //漂浮
- case SpecialState.FloatState:
- switch (floatingState)
- {
- case 1:
- character.transform.localEulerAngles += new Vector3(0, 0, 1) * rotateDir * rotateSpeed * Time.deltaTime;
- curHeight = Mathf.SmoothDamp(curHeight, height, ref rise, riseTime);
- character.transform.position = new Vector3(origPos.x, curHeight, origPos.z);
- if (curHeight >= height - 0.02f)
- {
- floatingState = 2;
- height = character.transform.position.y;
- }
- break;
- case 2:
- character.transform.localEulerAngles += new Vector3(0, 0, 1) * rotateDir * rotateSpeed * Time.deltaTime;
- break;
- case 3:
- if (character.transform.position.y >= origPos.y + 0.05f)
- {
- curHeight -= normalFallSpeed * Time.deltaTime;
- character.transform.position = new Vector3(origPos.x, curHeight, origPos.z);
- }
- else if (foot.TrigGround || curHeight <= origPos.y + 0.05f)
- {
- floatingState = 0;
- character.bodyCollider.layer = character.gameObject.layer;
- character.isAdjustHeight = 1;
- OutSpecialState();
- return;
- }
- break;
- }
- PlayerController playerController = GetComponent<PlayerController>();
- if (playerController != null)
- {
- if (playerController.mp > 0)
- {
- playerController.lostMp += playerController.mpReplySpeed * Time.deltaTime;
- playerController.mp -= playerController.mpReplySpeed * Time.deltaTime;
- }
- if (playerController.lostMp >= playerController.addMp)
- {
- PoolManager.Instantiate(playerController.soul, character.transform.position, new Quaternion(0, 0, 0, 0), null);
- playerController.lostMp = 0;
- }
- }
- attributeTime -= Time.deltaTime;
- if (attributeTime <= 0)
- {
- character.transform.localEulerAngles = Vector3.zero;
- floatingState = 3;
- rb.useGravity = true;
- }
- break;
- //击飞
- case SpecialState.BlownUp:
- //击落
- case SpecialState.ShotDown:
- Vector3 vel = rb.velocity;
- switch (hitState)
- {
- case -1:
- break;
- case 0:
- if (isFly && foot.TrigGround && vel.y < 0.1f)
- {
- if (!foot.haveGravity)
- {
- character.transform.position = new Vector3(transform.position.x, character.platformPosY, transform.position.z);
- }
- int landingDamage;
- if (specialState == SpecialState.BlownUp)
- {
- if (attackMethod.attackInfo.blowUp.haveLandingDamage)
- {
- landingDamage = (int)(Mathf.Abs(transform.position.x - startFlyPos.x) * attackMethod.attackInfo.blowUp.landingDamageRate)/* + GameManager.instance.blowUpDamage*/;
- if (landingDamage > 0)
- {
- character.BeHit(attackMethod, landingDamageFrom, landingDamage);
- }
- }
- }
- else
- {
- AttackInfo.ShotDown shotDown = attackMethod.attackInfo.shotDown;
- if (shotDown.haveLandingDamage)
- {
- landingDamage = (int)(Mathf.Abs(transform.position.y - startFlyPos.y) * shotDown.landingDamageRate * (1 - resistances.ShotDown)) /*+ GameManager.instance.downDamage*/;
- landingDamage = Mathf.Clamp(landingDamage, shotDown.minLandingDamage, landingDamage);
- if (landingDamage > 0)
- {
- character.BeHit(attackMethod, landingDamageFrom, landingDamage);
- }
- }
- }
- jumpNum--;
- if (jumpNum < 0)
- {
- vel = vel / 5f;
- vel.y = jumpVel;
- character.mecanim.transform.localPosition = Vector3.zero;
- character.mecanim.transform.localRotation = Quaternion.Euler(0, 0, 0);
- character.transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, character.platformRotZ);
- character.ani.Play(AnimatorHash.ANIMATOR_weak, 0, 0);
- character.bodyCollider.layer = character.gameObject.layer;
- hitState = 1;
- }
- else
- {
- flyForce *= jumpNumRate;
- rb.AddForce(flyForce, ForceMode.Impulse);
-
- }
- BounceEffect();
- }
- else
- {
- if (vel.x > 0)
- {
- vel.x -= decelerationRatioX * Time.deltaTime;
- }
- else
- {
- vel.x += decelerationRatioX * Time.deltaTime;
- }
- vel.y -= decelerationRatioY * Time.deltaTime;
- character.mecanim.transform.RotateAround(
- character.transform.position + rotateCenterHeight * Vector3.up,
- Vector3.forward,
- flyingRotateSpeed * Time.deltaTime);
- isFly = true;
- }
- break;
- case 1:
- //眩晕状态
- if (attributeTime <= 0)
- {
- character.isAdjustHeight = 1;
- character.nowCanFly = character.canFly;
- OutSpecialState();
- }
- else
- {
- if (vel.x > 0)
- {
- vel.x -= decelerationRatioX * Time.deltaTime;
- }
- else
- {
- vel.x += decelerationRatioX * Time.deltaTime;
- }
- if (!foot.TrigGround || vel.y > 0.1f)
- {
- vel.y -= decelerationRatioY * Time.deltaTime;
- }
- attributeTime -= Time.deltaTime;
- }
- break;
- }
- rb.velocity = vel;
- break;
- //眩晕
- case SpecialState.Weak:
- if (attributeTime <= 0)
- {
- OutSpecialState();
- }
- else
- {
- if (!character.isFrozen) rb.velocity = Vector3.zero;
- attributeTime -= Time.deltaTime;
- }
- break;
- }
- }
- void BounceEffect()
- {
- Transform spine = character.mecanim.transform;
- Sequence landSequence = DOTween.Sequence();
- landSequence.Append(spine.DOScaleY(scale.y * compressionDegree, compressionSpeed.x));
- landSequence.Append(spine.DOScaleY(scale.y, compressionSpeed.y));
- }
- public void OutSpecialState()
- {
- character.mecanim.transform.localRotation = Quaternion.Euler(0, 0, 0);
- curSpecialStates = SpecialState.Null;
- if (character.canFly)
- {
- rb.useGravity = false;
- character.isAdjustHeight = 1;
- }
- character.ChangeState(CharacterState.Idle);
- }
- //判断优先级,ture为优先级高于当前控制
- public bool PriorityOrder(SpecialState specialState, int controlOrder)
- {
- //控制层级小于控制抗性层级,该控制效果无效
- if (controlOrder < resistances.controlOrder)
- {
- return false;
- }
- if (curSpecialStates == SpecialState.Null)
- {
- curSpecialStates = specialState;
- return true;
- }
- else
- {
- if (curSpecialStates >= specialState)
- {
- curSpecialStates = specialState;
- return true;
- }
- }
- return false;
- }
- //受到漂浮
- public void AddFloat(AttackController.AttackMethod attackMethod)
- {
- if (resistances.Float == 1)
- {
- return;
- }
- this.attackMethod = attackMethod;
- AttackInfo.FloatState floatState = attackMethod.attackInfo.floatState;
- rb.isKinematic = false;
- rb.useGravity = false;
- floatingState = 1;
- origPos = character.transform.position;
- curHeight = origPos.y;
- riseTime = UnityEngine.Random.Range(floatState.upTime.x, floatState.upTime.y);
- backSpeed = UnityEngine.Random.Range(floatState.backSpeed.x, floatState.backSpeed.y);
- if (gameObject.tag == "Enemy" || gameObject.tag == "Player")
- {
- backSpeed = -backSpeed;
- }
- rotateSpeed = UnityEngine.Random.Range(floatState.rotateSpeed.x, floatState.rotateSpeed.y);
- rotateDir = (1.5f - UnityEngine.Random.Range(1, 3)) * 2;
- height = UnityEngine.Random.Range(floatState.height.x, floatState.height.y);
- attributeTime = floatState.time * (1 - resistances.Float);
- character.ChangeState(CharacterState.SpecialStatus_Float);
- character.ChangeStateText(CharacterState.SpecialStatus_Float);
- }
- //受到击飞
- public void AddBlowUp(AttackController.AttackMethod attackMethod, Transform attackFrom)
- {
- if (resistances.BlowUp == 1)
- {
- return;
- }
- this.attackMethod = attackMethod;
- AttackInfo.BlowUp blowUp = attackMethod.attackInfo.blowUp;
- attributeTime = blowUp.time * (1 - resistances.BlowUp);
- Vector3 vec3 = new Vector3(
- blowUp.dir.x + UnityEngine.Random.Range(-blowUp.dirRandom.x / 2f, blowUp.dirRandom.x / 2f),
- blowUp.dir.y + UnityEngine.Random.Range(-blowUp.dirRandom.y / 2f, blowUp.dirRandom.y / 2f),
- 0).normalized;
- int attackDir = 0;
- switch (blowUp.directionType)
- {
- case AttackInfo.BlowUp.DirectionType.Common:
- attackDir = attackFrom.localScale.x < 0 ? -1 : 1;
- break;
- case AttackInfo.BlowUp.DirectionType.Spread:
- attackDir = attackFrom.position.x < transform.position.x ? -1 : 1;
- break;
- case AttackInfo.BlowUp.DirectionType.Explosion:
- attackDir = 1;
- vec3 = transform.position - attackFrom.transform.position;
- vec3.y += 0.5f;
- break;
- }
- if (attackDir < 0)
- {
- vec3.x = -vec3.x;
- }
- hitState = -1;
- character.ChangeState(CharacterState.SpecialStatus_BlowUp);
- character.ChangeStateText(CharacterState.SpecialStatus_BlowUp);
- rb.useGravity = true;
- rb.constraints = RigidbodyConstraints.FreezeRotation | RigidbodyConstraints.FreezePositionZ;
- rb.velocity = Vector3.zero;
- flyForce = vec3 * blowUp.force * (1 - resistances.BlowUp);
- rb.AddForce(flyForce, ForceMode.Impulse);
-
- rb.transform.rotation = Quaternion.Euler(0, 0, 0);
- character.mecanim.transform.RotateAround(
- character.transform.position + rotateCenterHeight * Vector3.up,
- Vector3.forward,
- startFlyAngle * attackDir);
- flyingRotateSpeed = UnityEngine.Random.Range(flyingRotateSpeedRange.x, flyingRotateSpeedRange.y) * attackDir;
- startFlyPos = transform.position;
- hitState = 0;
- isFly = false;
- jumpNum = blowUp.jumpNum;
- character.ani.Play("hitted", 0, 0);
- }
- //受到击落
- public void AddShotDown(AttackController.AttackMethod attackMethod, Transform attackFrom)
- {
- if (resistances.ShotDown == 1)
- {
- return;
- }
- this.attackMethod = attackMethod;
- AttackInfo.ShotDown shotDown = attackMethod.attackInfo.shotDown;
- attributeTime = shotDown.time;
- Vector3 vec3 = new Vector3(
- shotDown.dir.x + UnityEngine.Random.Range(-shotDown.dirRandom.x / 2f, shotDown.dirRandom.x / 2f),
- shotDown.dir.y + UnityEngine.Random.Range(-shotDown.dirRandom.y / 2f, shotDown.dirRandom.y / 2f),
- 0).normalized;
- int attackDir = 0;
- switch (shotDown.directionType)
- {
- case AttackInfo.ShotDown.DirectionType.Common:
- attackDir = attackFrom.localScale.x < 0 ? -1 : 1;
- break;
- case AttackInfo.ShotDown.DirectionType.Spread:
- attackDir = attackFrom.position.x < transform.position.x ? -1 : 1;
- break;
- }
- if (attackDir < 0)
- {
- vec3.x = -vec3.x;
- }
- rb.useGravity = true;
- rb.constraints = RigidbodyConstraints.FreezeRotation | RigidbodyConstraints.FreezePositionZ;
- rb.velocity = Vector3.zero;
- rb.AddForce(vec3 * shotDown.force, ForceMode.Impulse);
- rb.transform.rotation = Quaternion.Euler(0, 0, 0);
- character.ani.Play("hitted", 0, 0);
- character.nowCanFly = false;
- startFlyPos = transform.position;
- hitState = 0;
- isFly = false;
- character.ChangeState(CharacterState.SpecialStatus_ShotDown);
- character.ChangeStateText(CharacterState.SpecialStatus_ShotDown);
- }
- //受到击晕
- public void AddWeak(AttackController.AttackMethod attackMethod)
- {
- if (resistances.Weak == 1)
- {
- return;
- }
- this.attackMethod = attackMethod;
- AttackInfo.Weak weak = attackMethod.attackInfo.weak;
- attributeTime = weak.time * (1 - resistances.Weak);
- character.ani.Play("weak", 0, 0);
- character.ChangeState(CharacterState.SpecialStatus_Weak);
- character.ChangeStateText(CharacterState.SpecialStatus_Weak);
- }
- public void AddWeak(float _attributeTime)
- {
- if (resistances.Weak == 1 || character.isDie)
- {
- return;
- }
- attributeTime = _attributeTime;
- character.ani.Play("weak", 0, 0);
- character.ChangeState(CharacterState.SpecialStatus_Weak);
- character.ChangeStateText(CharacterState.SpecialStatus_Weak);
- }
- //受到穿甲
- public int AddArmorPiercing(AttackController.AttackMethod attackMethod)
- {
- this.attackMethod = attackMethod;
- AttackInfo.ArmorPiercing armor = attackMethod.attackInfo.armorPiercing;
- //计算护甲减免
- int am = resistances.armor;
- if (am > 0)
- {
- am = am - armor.rate;
- if (am < 0)
- {
- am = 0;
- }
- }
- return am;
- }
- //受到易伤
- public void AddVulnerable(float _vulnerableRate,float _vulnerableTime)
- {
- if(vulnerableRate < _vulnerableRate) vulnerableRate += _vulnerableRate;
- vulnerableTime = _vulnerableTime;
- haveVulnerable = true;
- Debug.Log("添加易伤,vulnerableTime:" + vulnerableTime + ",vulnerableRate:" + vulnerableRate);
- }
- //受到累伤
- public void AddStackingWouds(AttackController.AttackMethod attackMethod)
- {
- this.attackMethod = attackMethod;
- AttackInfo.StackingWounds stackingWounds = attackMethod.attackInfo.stackingWounds;
- if(stackingWoudsTime > 0)
- {
- stackingWords += attackMethod.attackInfo.stackingWounds.damage;
- }
- stackingWoudsTime = stackingWounds.time;
- }
- }
|