public override List <ActorObj> CalculationHit(SkillData skilldata, GTargetInfo targetInfo) { float minDis = skilldata.MSV_AreaParam1 / 10.0f; float maxDis = skilldata.MSV_AreaParam2 / 10.0f; int angle = skilldata.MSV_AreaParam3; Vector3 pos = skilldata.IsAreaUseTarPos() ? targetInfo.m_vTarPos : targetInfo.m_vSrcPos; Vector3 dir = targetInfo.m_vAimDir; SSector sSector = new SSector(pos, dir, maxDis, minDis, angle); List <ActorObj> pActorList = ActorMgr.GetAllActor(); if (pActorList.Count <= 0) { return(null); } List <ActorObj> list = new List <ActorObj>(); foreach (ActorObj actor in pActorList) { if (actor == m_pLocalPlayer) { continue; } ActorObj obj = (ActorObj)actor; if (obj.CollisionCom == null) { continue; } for (int i = 0; i < obj.CollisionCom.GetShapeCount(); i++) { SShapeData shp = obj.CollisionCom.GetShape(i); if (shp != null) { SSphere sTarSphere = new SSphere(shp.Pos, shp.r); if (GCollider.SectorCollideCheck(sSector, sTarSphere, dir)) { list.Add(actor); break; } } } } return(list); }
/// <summary> /// 扇形判定 /// 共有三种分离轴 /// 1、扇形圆心和圆盘圆心的方向(扇形的圆弧部分) /// 2、扇形两边的法线 /// 3、扇形三个顶点和圆盘圆心的方向 /// /// 1、先判断扇形与圆盘的方向 /// 2、计算圆盘圆心与扇形的最近点的向量 p /// 3、计算当前圆心是否在扇形内部 /// 4、计算扇形左边半径是否与圆形相交 /// </summary> /// <returns></returns> public static bool SectorCollideCheck(SSector sSector, SSphere pTarget, Vector3 vDir) { Vector2 sSectorPos = new Vector2(sSector.pos.x, sSector.pos.z); Vector2 sTargetPos = new Vector2(pTarget.pos.x, pTarget.pos.z); vDir.Normalize(); Vector2 vAimDir = new Vector2(vDir.x, vDir.z); Vector2 vOpAimDir = new Vector2(-vDir.z, vDir.x); float angle = sSector.angle * 0.5f; // 1. 如果扇形圆心和圆盘圆心的方向 Vector2 vOffest = sTargetPos - sSectorPos; if (vOffest.sqrMagnitude >= (sSector.r_max + pTarget.r) * (sSector.r_max + pTarget.r)) { return(false); } if (vOffest.sqrMagnitude <= (sSector.r_min - pTarget.r) * (sSector.r_min - pTarget.r)) { return(false); } // 2. 计算出扇形局部空间的 p float px = Vector2.Dot(vOffest, vAimDir); float py = Mathf.Abs(Vector2.Dot(vOffest, vOpAimDir)); //取仅为第一\二象限的情况化简难度 // 3. 如果 p_x > ||p|| cos theta,两形状相交 当前圆心在扇形内部 if (px > vOffest.magnitude * Mathf.Cos(angle)) { return(true); } // 4. 求左边线段与圆盘是否相交 Vector2 q = sSector.r_max * new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)); //得到扇形左边坐标 Vector2 p = new Vector2(px, py); //得到扇形与圆形相对坐标 //计算出左边线段与圆盘的分离轴,之后通过长度对比即可 float t = Vector2.Dot(p - Vector2.zero, q) / q.sqrMagnitude; float length = (p - (Vector2.zero + Mathf.Clamp(t, 0, 1) * q)).sqrMagnitude; return(length <= pTarget.r * pTarget.r); }