You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			168 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			168 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C#
		
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using UnityEngine;
 | |
| 
 | |
| namespace Game
 | |
| {
 | |
|     public class SkillHitInfo
 | |
|     {
 | |
|         public AttackBehaviour SkillParam;
 | |
|         public Vector3 HitDir;
 | |
|         public int OwnerEntity;
 | |
|         public int HitEntity; //0为非实体对象
 | |
|         public float AttackRate;
 | |
|         public float StunkRate;
 | |
|         public string SkillId; //是否技能造成的伤害
 | |
|         public bool IsBreak;
 | |
|         public int hitIndex;
 | |
|         public int hitCount;
 | |
|     }
 | |
| 
 | |
|     public class ClipAttack : TimelineClipBase
 | |
|     {
 | |
|         private AttackClip _mRealAsset;
 | |
|         private List<GameEntity> _tempTargetList = new List<GameEntity>();
 | |
| 
 | |
|         public override void OnEnter()
 | |
|         {
 | |
|             _mRealAsset = Asset as AttackClip;
 | |
|         }
 | |
| 
 | |
|         public override void OnStay()
 | |
|         {
 | |
|             var param = _mRealAsset.template;
 | |
|             var skill = Owner.skill;
 | |
|             var castShape = param.Shape;
 | |
|             var castDir = skill.CastDir;
 | |
|             castDir = new Vector3(castDir.x, 0, castDir.z); //忽略y
 | |
|             var rot = Quaternion.FromToRotation(Vector3.right, castDir);
 | |
|             var castPos = rot * castShape.Offset + Owner.Pos();
 | |
| 
 | |
|             Util.DrawShape(castShape, castPos, castDir, Color.red);
 | |
|             _tempTargetList.Clear();
 | |
|             Util.ForeachEnemies(Owner.Team(), target =>
 | |
|             {
 | |
|                 var isHit = UtilShape.IsOverlap(castShape, castPos, castDir, target.hp.HitBoxShape, target.Pos());
 | |
|                 if (!isHit) return;
 | |
| 
 | |
|                 var hitKey = new Tuple<int, int>(target.ID(), param.hitId);
 | |
|                 if (skill.HitSet.Contains(hitKey)) return;
 | |
|                 skill.HitSet.Add(hitKey);
 | |
| 
 | |
|                 _tempTargetList.Add(target);
 | |
|             });
 | |
|             _tempTargetList.Sort((l, r) =>
 | |
|             {
 | |
|                 var lRank = GetRank(param.hitOrderType, l, castPos, castDir);
 | |
|                 var rRank = GetRank(param.hitOrderType, r, castPos, castDir);
 | |
|                 return lRank.CompareTo(rRank);
 | |
|             });
 | |
|             var hitNum = _tempTargetList.Count;
 | |
|             for (var i = 0; i < hitNum; i++)
 | |
|             {
 | |
|                 var target = _tempTargetList[i];
 | |
|                 var targetID = target.ID();
 | |
|                 var skillHitInfo = new SkillHitInfo
 | |
|                 {
 | |
|                     SkillParam = param,
 | |
|                     AttackRate = 1,
 | |
|                     StunkRate = 1,
 | |
|                     OwnerEntity = Owner.ID(),
 | |
|                     HitEntity = targetID,
 | |
|                     HitDir = GetHitDir(param.hitDirType, target, castPos, castDir),
 | |
|                     SkillId = skill.SkillId.Value,
 | |
|                     IsBreak = true,
 | |
|                     hitIndex = i,
 | |
|                     hitCount = hitNum
 | |
|                 };
 | |
|                 if (!string.IsNullOrEmpty(skillHitInfo.SkillId))
 | |
|                 {
 | |
|                     var skillCfg = Util.GetSkillMasterConfigData(skillHitInfo.SkillId);
 | |
|                     if (skillCfg != null)
 | |
|                     {
 | |
|                         var featureSkill = skillCfg.GetFeatureSkill();
 | |
|                         skillHitInfo.AttackRate = featureSkill.AttackRate;
 | |
|                         skillHitInfo.StunkRate = featureSkill.StunRate;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 skill.HitInfo.Enqueue(skillHitInfo);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private Vector3 GetHitDir(EHitDirType hitOrderType, GameEntity target, Vector3 castPos, Vector3 castDir)
 | |
|         {
 | |
|             var targetPos = target.Pos();
 | |
|             var targetDir = targetPos - castPos;
 | |
|             targetDir.y = 0;
 | |
|             switch (hitOrderType)
 | |
|             {
 | |
|                 case EHitDirType.Center:
 | |
|                     //从中心到外围
 | |
|                     return targetDir;
 | |
|                 case EHitDirType.Backward:
 | |
|                     //从前往后
 | |
|                     return -castDir;
 | |
|                 case EHitDirType.Forward:
 | |
|                     //从后往前
 | |
|                     return castDir;
 | |
|                 case EHitDirType.Clockwise:
 | |
|                     //顺时针
 | |
|                     return GetDirRot(targetDir, true);
 | |
|                 case EHitDirType.CounterClockwise:
 | |
|                     //逆时针
 | |
|                     return GetDirRot(targetDir, false);
 | |
|                 case EHitDirType.CenterForward:
 | |
|                     //中心向前
 | |
|                     return targetDir + castDir;
 | |
|                 case EHitDirType.ClockwiseForward:
 | |
|                     //顺时针向前
 | |
|                     return GetDirRot(targetDir, true) + castDir;
 | |
|                 case EHitDirType.CounterClockwiseForward:
 | |
|                     //逆时针向前
 | |
|                     return GetDirRot(targetDir, false) + castDir;
 | |
|             }
 | |
| 
 | |
|             return targetDir;
 | |
|         }
 | |
| 
 | |
|         private Vector3 GetDirRot(Vector3 targetDir, bool isClockwise)
 | |
|         {
 | |
|             var sub = (Owner.move.IsRight ? -1 : 1) * (isClockwise ? 1 : -1);
 | |
|             return Vector3.Cross(targetDir, Vector3.up * sub).normalized;
 | |
|         }
 | |
| 
 | |
|         private float GetRank(EHitOrderType hitOrderType, GameEntity target, Vector3 castPos, Vector3 castDir)
 | |
|         {
 | |
|             //小在前
 | |
|             var targetPos = target.Pos();
 | |
|             var targetDir = targetPos - castPos;
 | |
|             switch (hitOrderType)
 | |
|             {
 | |
|                 case EHitOrderType.Center:
 | |
|                     //按距离
 | |
|                     return Vector3.Distance(targetPos, castPos);
 | |
|                 case EHitOrderType.Backward:
 | |
|                     //从前往后
 | |
|                     return -Vector3.Dot(targetDir, castDir);
 | |
|                 case EHitOrderType.Forward:
 | |
|                     //从后往前
 | |
|                     return Vector3.Dot(targetDir, castDir);
 | |
|                 case EHitOrderType.Clockwise:
 | |
|                     //顺时针
 | |
|                     return -GetRankRot(castDir, targetDir);
 | |
|                 case EHitOrderType.CounterClockwise:
 | |
|                     //逆时针
 | |
|                     return GetRankRot(castDir, targetDir);
 | |
|             }
 | |
| 
 | |
|             return 0;
 | |
|         }
 | |
| 
 | |
|         private float GetRankRot(Vector3 castDir, Vector3 targetDir)
 | |
|         {
 | |
|             var rot = Quaternion.FromToRotation(-castDir, Vector3.right);
 | |
|             return Util.Vec3ToRot(rot * targetDir) * (Owner.move.IsRight ? 1 : -1);
 | |
|         }
 | |
|     }
 | |
| } |