예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }