/// <summary> /// 检测攻击 /// </summary> /// <param name="skillType">技能类型</param> /// <param name="WeaponType">武器类型</param> /// <param name="attackSpeed">攻击速度</param> /// <param name="attackLayerMask">内部设置的检测层</param> /// <param name="CheckResultAction">检测到碰撞对象后的回调</param> /// <param name="otherCheck">其他的检测</param> public void CheckAttack(EnumSkillType skillType, EnumWeaponTypeByPlayerState WeaponType, float attackSpeed, LayerMask?attackLayerMask, Func <int, GameObject, bool> CheckResultAction, int otherCheck = 0) { this.CheckResultAction = CheckResultAction; this.AttackSpeed = attackSpeed; if (attackLayerMask != null) { tempAttackLayerMask = attackLayerMask.Value; } else { tempAttackLayerMask = null; } if (checkStructCollectionArray != null) { checkStructCollection = checkStructCollectionArray .Where(temp => temp.SkillType == skillType) //判断技能类型 .Where(temp => temp.WeaponType == WeaponType || temp.WeaponType == EnumWeaponTypeByPlayerState.None) //判断武器类型(如果设置的是None表示什么武器都可以) .Where(temp => (temp.OtherCheck == 0 || otherCheck == 0) ? true : temp.OtherCheck == otherCheck) //判断是否存在其他的检测,并判断是否通过检测 .FirstOrDefault(); } else { checkStructCollection = null; } if (checkStructCollection != null) { //进行设置 checkStructCollection.CheckStructs.ToList().ForEach(temp => { temp.Collider.gameObject.SetActive(true);//打开检测对象 //查找检测脚本 PhysicSkillInjuryDetection_Check physicSkillInjuryDetection_Check = temp.Collider.gameObject.GetComponent <PhysicSkillInjuryDetection_Check>(); //如果为空则添加 if (physicSkillInjuryDetection_Check == null) { physicSkillInjuryDetection_Check = temp.Collider.gameObject.AddComponent <PhysicSkillInjuryDetection_Check>(); } //设置检测层 physicSkillInjuryDetection_Check.checkMask = tempAttackLayerMask != null ? tempAttackLayerMask.Value : this.attackLayerMask; }); } nowCheckTime = 0; skillOrderToObjList = new Dictionary <int, List <GameObject> >(); }
private void Update() { if (checkStructCollection != null && skillOrderToObjList != null && CheckResultAction != null) //开始检测 { bool hasNextCheck = true; //是否存在下次一的检测 float lastCheckTime = nowCheckTime; nowCheckTime += Time.deltaTime * AttackSpeed; //根据攻击速度乘以对应的时间 //当时间到时生成粒子 SoildSkillPartical[] soildSkillParticals = checkStructCollection.SoildSkillParticals.Where(temp => temp.StartParticalTime > lastCheckTime && temp.StartParticalTime < nowCheckTime).ToArray(); foreach (SoildSkillPartical soildSkillPartical in soildSkillParticals) { if (soildSkillPartical.ParticalPrefab == null) { continue; } GameObject createPartical = GameObject.Instantiate <GameObject>(soildSkillPartical.ParticalPrefab); if (soildSkillPartical.ShowTarget != null) { switch (soildSkillPartical.ShowType) { case SoildSkillPartical.EnumShowType.Soild: createPartical.transform.position = transform.position; createPartical.transform.forward = transform.forward; break; case SoildSkillPartical.EnumShowType.Follow: createPartical.transform.SetParent(soildSkillPartical.ShowTarget); createPartical.transform.localPosition = Vector3.zero; createPartical.transform.localEulerAngles = Vector3.zero; break; } } else { createPartical.transform.position = transform.position; createPartical.transform.forward = transform.forward; } float stillTime = soildSkillPartical.Duration / (AttackSpeed > 0 ? AttackSpeed : 1); ParticleSystem particleSystem = createPartical.GetComponent <ParticleSystem>(); if (particleSystem) { ParticleSystem.MainModule mainModule = particleSystem.main; mainModule.duration = stillTime; particleSystem.Play(); } GameObject.Destroy(createPartical, 5); } //取出复合当前时间范围的检测 CheckStruct[] checkStructArray = checkStructCollection.CheckStructs.Where(temp => temp.StartCheckTime < nowCheckTime && (temp.StartCheckTime + temp.DurationCheck > nowCheckTime)).ToArray(); foreach (CheckStruct checkStruct in checkStructArray) { if (!skillOrderToObjList.ContainsKey(checkStruct.InnerDamageOrder)) { skillOrderToObjList.Add(checkStruct.InnerDamageOrder, new List <GameObject>()); } PhysicSkillInjuryDetection_Check physicSkillInjuryDetection_Check = checkStruct.Collider.gameObject.GetComponent <PhysicSkillInjuryDetection_Check>(); if (physicSkillInjuryDetection_Check == null) { continue; } GameObject[] targetObjs = physicSkillInjuryDetection_Check.GetTargets; if (targetObjs.Length > 0) { foreach (GameObject targetObj in targetObjs) { if (!skillOrderToObjList[checkStruct.InnerDamageOrder].Contains(targetObj)) { skillOrderToObjList[checkStruct.InnerDamageOrder].Add(targetObj); hasNextCheck = CheckResultAction(checkStruct.InnerDamageOrder, targetObj);//返回是否存在下一次的检测 //生成(命中)粒子 //从对象身上获取偏差值数据,暂时为0 if (checkStruct.ParticalPrefab != null) { GameObject partaicalObj = GameObject.Instantiate <GameObject>(checkStruct.ParticalPrefab); partaicalObj.transform.position = targetObj.transform.position + Vector3.up; Destroy(partaicalObj, 5); } } } } } //判断之后是否还有检测的东西 int canCheckCount = checkStructCollection.CheckStructs.Count(temp => temp.StartCheckTime + temp.DurationCheck > nowCheckTime); if (canCheckCount <= 0 || !hasNextCheck)//如果都检测完了则初始化 如果没有下次检测了也要初始化 { checkStructCollection.CheckStructs.ToList().ForEach(temp => { temp.Collider.gameObject.SetActive(false); }); checkStructCollection = null; nowCheckTime = 0; skillOrderToObjList = null; AttackSpeed = 0; CheckResultAction = null; tempAttackLayerMask = null; } } }