2
0
Fork 0
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.

191 lines
7.0 KiB
C#

2 years ago
using System;
using System.Collections.Generic;
2 years ago
using UnityEngine;
namespace Game
{
public class SkillHitInfo
{
public AttackBehaviour SkillParam;
2 years ago
public Vector3 HitDir;
2 years ago
public int OwnerEntity;
public int HitEntity;
2 years ago
public float AttackRate;
public float StunkRate;
2 years ago
public string SkillId; //是否技能造成的伤害
public bool IsBreak;
public int HitIndex;
public int HitCount;
public float Rank;
public bool Continue;
2 years ago
}
2 years ago
public class ClipAttack : TimelineClipBase
{
private AttackClip _mRealAsset;
private readonly List<SkillHitInfo> _tempHitInfoList = new List<SkillHitInfo>();
2 years ago
public override void OnEnter()
{
_mRealAsset = Asset as AttackClip;
}
2 years ago
public override void OnStay()
{
var param = _mRealAsset.template;
2 years ago
var skill = Owner.skill;
var castShape = param.Shape;
var castDir = Util.IgnoreY(skill.CastDir);
var rot = Quaternion.FromToRotation(Vector3.right, castDir);
var castPos = rot * castShape.Offset + Owner.Pos();
2 years ago
Util.DrawShape(castShape, castPos, castDir, Color.red);
_tempHitInfoList.Clear();
var (rankMin, rankMax) = (float.MaxValue, float.MinValue);
Util.ForeachEnemies(Owner.Team(), target =>
2 years ago
{
//检测命中
var isHit = UtilShape.IsOverlap(castShape, castPos, castDir, target.hp.HitBoxShape, target.Pos());
2 years ago
if (!isHit) return;
//排除重复命中
var hitKey = new Tuple<int, int>(target.ID(), param.hitId);
if (skill.HitSet.Contains(hitKey)) return;
skill.HitSet.Add(hitKey);
2 years ago
//计算结算顺序rank
var rank = GetRank(param.hitOrderType, target, castPos, castDir);
if (rank < rankMin) rankMin = rank;
if (rank > rankMax) rankMax = rank;
2 years ago
var skillHitInfo = new SkillHitInfo
2 years ago
{
2 years ago
SkillParam = param,
AttackRate = 1,
StunkRate = 1,
OwnerEntity = Owner.ID(),
HitEntity = target.ID(),
2 years ago
HitDir = GetHitDir(param.hitDirType, target, castPos, castDir),
2 years ago
SkillId = skill.SkillId.Value,
IsBreak = true,
Rank = rank,
2 years ago
};
if (!string.IsNullOrEmpty(skillHitInfo.SkillId))
{
var skillCfg = Util.GetSkillMasterConfigData(skillHitInfo.SkillId);
if (skillCfg != null)
2 years ago
{
2 years ago
var featureSkill = skillCfg.GetFeatureSkill();
skillHitInfo.AttackRate = featureSkill.AttackRate;
skillHitInfo.StunkRate = featureSkill.StunRate;
2 years ago
}
}
2 years ago
_tempHitInfoList.Add(skillHitInfo);
});
_tempHitInfoList.Sort((l, r) => l.Rank.CompareTo(r.Rank));
var hitNum = _tempHitInfoList.Count;
var rankGroup = 0;
var rankRange = rankMax - rankMin; //rank范围大小
var rankRangeEach = rankRange / GameConst.HitMaxSettle; //单个group的rank范围大小
for (var i = 0; i < hitNum; i++)
{
var info = _tempHitInfoList[i];
info.HitIndex = i;
info.HitCount = hitNum;
var rate = (info.Rank - rankMin) / rankRange;
if (rate > rankGroup * rankRangeEach)
{
rankGroup++;
}
else
{
info.Continue = true;
}
skill.HitInfo.Enqueue(info);
if (!info.SkillParam.isAoe)
{
break;
}
}
}
2 years ago
private Vector3 GetHitDir(EHitDirType hitOrderType, GameEntity target, Vector3 castPos, Vector3 castDir)
2 years ago
{
var targetPos = target.Pos();
var targetDir = targetPos - castPos;
2 years ago
targetDir.y = 0;
switch (hitOrderType)
2 years ago
{
case EHitDirType.Center:
//从中心到外围
return targetDir;
case EHitDirType.Backward:
//从前往后
return -castDir;
case EHitDirType.Forward:
//从后往前
return castDir;
case EHitDirType.Clockwise:
//顺时针
2 years ago
return GetDirRot(targetDir, true);
2 years ago
case EHitDirType.CounterClockwise:
//逆时针
2 years ago
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;
2 years ago
}
return targetDir;
}
2 years ago
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;
2 years ago
switch (hitOrderType)
{
2 years ago
case EHitOrderType.Center:
//按距离
return Vector3.Distance(targetPos, castPos);
2 years ago
case EHitOrderType.Backward:
//从前往后
return -Vector3.Dot(targetDir, castDir);
2 years ago
case EHitOrderType.Forward:
//从后往前
return Vector3.Dot(targetDir, castDir);
2 years ago
case EHitOrderType.Clockwise:
//顺时针
return -GetRankRot(castDir, targetDir);
2 years ago
case EHitOrderType.CounterClockwise:
//逆时针
return GetRankRot(castDir, targetDir);
}
return 0;
2 years ago
}
private float GetRankRot(Vector3 castDir, Vector3 targetDir)
2 years ago
{
var rot = Quaternion.FromToRotation(-castDir, Vector3.right);
return Util.Vec3ToRot(rot * targetDir) * (Owner.move.IsRight ? 1 : -1);
2 years ago
}
}
}