| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using System;
- using Sirenix.OdinInspector;
- using System.Linq;
- //攻击所附带的状态
- public enum AttackEffect
- {
- Null = -1,
- //控制
- [LabelText("漂浮")]FloatState = 0,
- [LabelText("击飞")]BlowUp = 1,
- [LabelText("击落")]ShotDown = 2,
- [LabelText("击晕")]Weak = 3,
- //非控制
- [LabelText("穿甲")]Armor,
- [LabelText("易伤")]Vulnerable,
- ChangeDamage, //更改攻击力
- SustainedInjury, //持续伤害
- Burn = 104, //灼烧
- //中毒
- //麻痹
- }
- [Serializable]
- public class AttackInfo
- {
- [LabelText("击打值")] public int attackValue;
- public int damage;
- public Vector3 attackDir;
- public AttackEffect[] attackEffect;
- //漂浮
- [Serializable]public struct FloatState
- {
- [LabelText("持续时间")]
- public float time;
- [LabelText("上升最大耗时")]
- public Vector2 upTime;
- [LabelText("往后退的速度")]
- public Vector2 backSpeed;
- [LabelText("旋转速度")]
- public Vector2 rotateSpeed;
- [LabelText("上升高度")]
- public Vector2 height;
- }
- private bool ShowFloatStateValue() => attackEffect.Contains(AttackEffect.FloatState);
- [ShowIf("ShowFloatStateValue")][LabelText("漂浮参数")]
- public FloatState floatState;
- //击飞
- [Serializable]public struct BlowUp
- {
- [LabelText("方向")]
- public Vector3 dir;
- [LabelText("力")]
- public float force;
- [LabelText("落地后眩晕时间")]
- public float time;
- }
- private bool ShowBlowUpValue() => attackEffect.Contains(AttackEffect.BlowUp);
- [ShowIf("ShowBlowUpValue")][LabelText("击飞参数")]
- public BlowUp blowUp;
- //击落
- [Serializable]public struct ShotDown
- {
- [LabelText("方向")]
- public Vector3 dir;
- [LabelText("力")]
- public float force;
- [LabelText("落地后眩晕时间")]
- public float time;
- }
- private bool ShowShotDownValue() => attackEffect.Contains(AttackEffect.ShotDown);
- [ShowIf("ShowShotDownValue")][LabelText("击落参数")]
- public ShotDown shotDown;
- //击晕
- [Serializable]public struct Weak
- {
- [LabelText("持续时间")]
- public float time;
- }
- private bool ShowWeakValue() => attackEffect.Contains(AttackEffect.Weak);
- [ShowIf("ShowWeakValue")][LabelText("击晕参数")]
- public Weak weak;
- //穿甲
- [Serializable]public struct Armor
- {
- [LabelText("穿甲值")]
- public int rate;
- }
- private bool ShowArmorValue() => attackEffect.Contains(AttackEffect.Armor);
- [ShowIf("ShowArmorValue")][LabelText("穿甲参数")]
- public Armor armor;
- //易伤
- [Serializable]public struct Vulnerable
- {
- [LabelText("倍率")]
- public float rate;
- [LabelText("持续时间")]
- public float time;
- }
- private bool ShowVulnerable() => attackEffect.Contains(AttackEffect.Vulnerable);
- [ShowIf("ShowVulnerable")][LabelText("易伤参数")]
- public Vulnerable vulnerable;
- //增加和减少攻击力
- [Serializable]public struct ChangeDamage
- {
- public float rate; //增加或减少攻击倍率
- }
- private bool ShowChangeDamageValue() => attackEffect.Contains(AttackEffect.ChangeDamage);
- [ShowIf("ShowChangeDamageValue")][LabelText("更改攻击力参数")]
- public ChangeDamage changeDamage;
- //持续伤害
- [Serializable]public struct SustainedInjury
- {
- public float damage; //每次造成的伤害数值
- }
- private bool ShowSustainedInjuryValue() => attackEffect.Contains(AttackEffect.SustainedInjury);
- [ShowIf("ShowSustainedInjuryValue")][LabelText("持续伤害参数")]
- public SustainedInjury sustainedInjury;
- [DisplayOnly]
- public bool isDemSummon;
- public void CopyTo(AttackInfo ai)
- {
- ai.damage = damage;
- ai.attackDir = attackDir;
- ai.blowUp = blowUp;
- ai.shotDown = shotDown;
- ai.weak = weak;
- ai.armor = armor;
- ai.changeDamage = changeDamage;
- ai.sustainedInjury = sustainedInjury;
- }
- }
- public class AttackController : MonoBehaviour
- {
- //攻击类型
- public enum AttackType
- {
- Melee = 0, //近战
- Shoot = 1, //射击
- Special = 2, //非普攻
- Dash = 3, //英灵刺客,后面请删掉
- }
- [System.Serializable]
- public struct SpineAniKey
- {
- public string aniName;
- public List<AttackKeyType> keys;
- }
- public enum KeyType
- {
- AttackStart,
- AttackEnd,
- }
- [System.Serializable]
- public struct AttackKeyType
- {
- public int attackMethod;
- public KeyType attackType;
- public string startKeyName;
- public float startKeyTime;
- public KeyType endType;
- public string endKeyName;
- public float endKeyTime;
- }
- [System.Serializable]
- public struct AttackMethod
- {
- [Header("起手式id=0,行军式id>=1")]
- public int id;
- [LabelText("攻击名称")]
- public string attackName;
- [LabelText("攻击类型")]
- public AttackType attackType;
- [Header("攻击参数")]
- public AttackInfo attackInfo;
- public AttackTrigger attackTrigger;
- [Header("攻击距离")]
- public float attackDistance;
- [ShowIf("needToChange")]
- public float maxAttackDis, minAttackDis;
- public bool needToChange;
- [Header("目标")]
- public List<TargetType> targetTypes;
- public bool canHitFly;
- public int armorPiercing; //穿甲率
- [Header("远程单位")]
- [ShowIf("attackType",AttackType.Shoot)]
- public GameObject bulletPrefab; //子弹
- [ShowIf("attackType", AttackType.Shoot)]
- public List<Transform> shootPos; //子弹发射位置
- [ShowIf("attackType", AttackType.Shoot)][LabelText("水平向上最大夹角")]
- public float maxUpAngle;
- [ShowIf("attackType", AttackType.Shoot)][LabelText("水平向下最大夹角")]
- public float maxDownAngle;
- [ShowIf("attackType", AttackType.Shoot)]
- public bool shootTrack; //是否初始时瞄准目标
- [ShowIf("attackType", AttackType.Shoot)]
- public bool shootAlwaysTrack; //是否始终追踪
- [Header("特殊攻击")]
- [ShowIf("attackType", AttackType.Special)]
- public GameObject skillPrefab;
- [HideInInspector]
- public SpecialSkills skill;
- }
- private Character owner;
- [Header("所有攻击帧事件及时间")]
- public List<SpineAniKey> attackKeys;
- public List<float> keyTimes; //所有的帧事件时间
- [DisplayOnly]
- public float attackTime; //攻击剩余时间
- [HideInInspector]
- public float attackKeyCount; //攻击进行时间
- [HideInInspector]
- public float nextStartKeyTime, nextEndKeyTime;
- [HideInInspector]
- public int curKeyNum; //当前锁定到第几个帧事件
- [Header("攻击类型")]
- public AttackType attackType;
- [Header("攻击参数")]
- [LabelText("攻击间隔")]
- public float attackInterval;
- [DisplayOnly]
- public int curDamage;
- [DisplayOnly]
- public bool canHitFly;
- [DisplayOnly]
- public int armorPiercing; //穿甲率
- [DisplayOnly]
- public AttackInfo attackInfo;
- [DisplayOnly]
- public GameObject addAttackEffect;
- [DisplayOnly]
- public SpecialSkills skill;
- [DisplayOnly]
- public GameObject attackEffect;
- [DisplayOnly]
- public Dictionary<string, GameObject> effects;
- [DisplayOnly]
- public GameObject effect;
- [DisplayOnly]
- public float attackDistance;
- [Header("攻击范围")]
- [HideInInspector]
- public AttackTrigger attackTrigger;
- [HideInInspector]
- public bool isAttackTriggerOn = false; //当前Attack Trigger是否开启
- [Header("远程单位")]
- [HideInInspector]
- public GameObject bulletPrefab; //子弹
- [HideInInspector]
- public List<Transform> shootPos; //子弹发射位置
- [HideInInspector]
- public bool shootTrack = false; //是否初始时瞄准目标
- [HideInInspector]
- public bool shootAlwaysTrack = false; //是否始终追踪
- [Header("目标")]
- [HideInInspector]
- public List<TargetType> targetTypes;
- [DisplayOnly]
- public List<Character> beTargetCharacter = new List<Character>(); //被哪些锁定
- //public float getDistanceOffset = 0f;
- [Header("攻击模式")]
- public AttackMethod[] attackMethod;
- [HideInInspector]
- public AttackMethod curAttackMethod;
- private SoldierLevelRecord slr;
- public void Init()
- {
- owner = GetComponent<Character>();
- if (attackMethod.Length > 0)
- {
- attackInfo = attackMethod[0].attackInfo;
- curDamage = attackInfo.damage;
- }
- effects = new Dictionary<string, GameObject>();
- for (int i = 0; i < attackMethod.Length; i++)
- {
- if (attackMethod[i].needToChange)
- {
- attackMethod[i].attackDistance = UnityEngine.Random.Range(attackMethod[i].minAttackDis,
- attackMethod[i].maxAttackDis);
- }
- }
- slr = GameManager.instance.GetComponent<SoldierLevelRecord>();
- }
- private void OnEnable()
- {
- if (attackTrigger != null)
- {
- attackTrigger.gameObject.SetActive(false);
- }
- }
- public void ChooseAttack(int id)
- {
- //默认起手式只使用一次,id=0为起手式
- curAttackMethod = attackMethod[id];
- attackType = curAttackMethod.attackType;
- canHitFly = curAttackMethod.canHitFly;
- armorPiercing = curAttackMethod.armorPiercing;
- Demonic dem = owner.GetComponent<Demonic>();
- if (dem)
- {
- for(int i = 0; i < 3; i++)
- {
- if (GameManager.curSoldiers[i] == dem.soldierType)
- {
- armorPiercing += slr.seb[i].armorPiercing;
- }
- }
- }
- attackInfo = curAttackMethod.attackInfo;
- curDamage = attackInfo.damage;
- attackTrigger = curAttackMethod.attackTrigger;
- bulletPrefab = curAttackMethod.bulletPrefab;
- shootPos = curAttackMethod.shootPos;
- shootTrack = curAttackMethod.shootTrack;
- shootAlwaysTrack = curAttackMethod.shootAlwaysTrack;
- targetTypes = curAttackMethod.targetTypes;
- if (attackType == AttackType.Special && skill == null)
- {
- curAttackMethod.skill= Instantiate(curAttackMethod.skillPrefab, owner.bodyTrans.position,
- new Quaternion(0, 0, 0, 0), owner.bodyTrans).GetComponent<SpecialSkills>();
- skill = curAttackMethod.skill;
- skill.owner = owner;
- }
- attackDistance = curAttackMethod.attackDistance;
- if (id == 0 && GetComponent<Demonic>())
- {
- attackInfo.isDemSummon = true;
- }
- else
- {
- attackInfo.isDemSummon = false;
- }
- }
- public void SetNextKeyTimes()
- {
- if (curKeyNum < keyTimes.Count)
- {
- nextStartKeyTime = keyTimes[curKeyNum];
- nextEndKeyTime = keyTimes[curKeyNum + 1];
- curKeyNum += 2;
- }
- }
- public virtual void Attack_summon()
- {
- owner.ani.Play("attack_summon", 0, 0);
- if (attackType == AttackType.Shoot)
- {
- attackTrigger.isShoot = true;
- attackTrigger.type = AttackTrigger.attackType.summon;
- }
- attackTime = owner.totalAttack_summonTime;
- attackKeyCount = 0;
- keyTimes = new List<float>();
- foreach (SpineAniKey sak in attackKeys)
- {
- if (sak.aniName == "attack_summon")
- {
- foreach (AttackKeyType akt in sak.keys)
- {
- keyTimes.Add(akt.startKeyTime);
- keyTimes.Add(akt.endKeyTime);
- }
- break;
- }
- }
- curKeyNum = 0;
- SetNextKeyTimes();
- switch (attackType)
- {
- case AttackType.Melee:
- attackTrigger.attackInfo = attackInfo;
- break;
- default:
- break;
- }
- ChooseAttack(attackMethod[0].id);
- owner.ChangeState(CharacterState.Attack);
- }
- public virtual void Attack_march(int id)
- {
- if (attackEffect != null)
- {
- if (effects.ContainsKey(attackEffect.name))
- {
- effect = effects[attackEffect.name];
- effect.SetActive(true);
- }
- else
- {
- effects[attackEffect.name] = Instantiate(attackEffect, owner.bodyTrans);
- effect = effects[attackEffect.name];
- effect.SetActive(true);
- }
- }
- Vector3 leftDir = owner.GetMoveDir();
- if (leftDir.x > 0.3f)
- {
- if (owner.bodyTrans.localScale.x > 0)
- {
- owner.Turn();
- }
- }
- else if (leftDir.x < -0.3f)
- {
- if (owner.bodyTrans.localScale.x < 0)
- {
- owner.Turn();
- }
- }
- owner.ani.Play("attack_march", 0, 0);
- if (attackType == AttackType.Shoot)
- {
- attackTrigger.isShoot = true;
- attackTrigger.type = AttackTrigger.attackType.march;
- }
- if (attackType == AttackType.Special)
- {
- skill.Attack();
- }
- attackTime = owner.totalAttack_marchTime;
- attackKeyCount = 0;
- keyTimes = new List<float>();
- foreach (SpineAniKey sak in attackKeys)
- {
- if (sak.aniName == "attack_march")
- {
- foreach (AttackKeyType akt in sak.keys)
- {
- keyTimes.Add(akt.startKeyTime);
- keyTimes.Add(akt.endKeyTime);
- break;
- }
- }
- }
- curKeyNum = 0;
- SetNextKeyTimes();
- attackTrigger.attackInfo = attackInfo;
- owner.ChangeState(CharacterState.Attack);
- }
- public virtual void AttackShootEvent(int attackId, int shootId)
- {
- GameObject bulletObj = PoolManager.Instantiate(bulletPrefab);
- Bullet bullet = bulletObj.GetComponent<Bullet>();
- Vector3 attackDir = attackInfo.attackDir.normalized;
- if (owner.bodyTrans.localScale.x < 0)
- {
- attackDir.x = -attackDir.x;
- }
- if (attackId == 1 && owner.Attack_summonShootCanTransmit)
- {
- bullet.canTransmit = true;
- }
- bullet.BeShoot(owner, shootPos[shootId].position, attackDir, shootTrack,
- shootAlwaysTrack, owner.attackTarget ? owner.attackTarget : null);
- }
- public void JudgeTriggerOnOff()
- {
- attackTime -= Time.deltaTime;
- attackKeyCount += Time.deltaTime;
- if (!isAttackTriggerOn && attackKeyCount >= nextStartKeyTime && attackKeyCount <= nextEndKeyTime)
- {
- isAttackTriggerOn = true;
- attackTrigger.gameObject.SetActive(true);
- }
- else if (isAttackTriggerOn && attackKeyCount >= nextEndKeyTime)
- {
- isAttackTriggerOn = false;
- attackTrigger.gameObject.SetActive(false);
- SetNextKeyTimes();
- }
- }
- }
|