示例#1
0
    public static void PutBallToThePoint(PoolBall ball, ref Vector3 p)
    {
        float r = ball.GetRadius();

        while (Physics.OverlapSphere(p, r, 1 << LayerMask.NameToLayer("Ball") | 1 << LayerMask.NameToLayer("WhiteBall")).Length != 0)
        {
            p.x -= r;
        }
        SupportTools.SetPosition(ball.gameObject, p, SupportTools.AxisIgnore.IgnoreY, true);
        p.x -= r;
    }
示例#2
0
        private float GetPlacedSpace(PoolBall ball, Vector3 dir)
        {
            ball.collider.enabled      = false;
            ball.rigidbody.isKinematic = true;
            RaycastHit hit;
            float      space = 0;

            if (Physics.SphereCast(ball.transform.position, ball.GetRadius(), dir, out hit, ConstantData.OulineAndBallLayer))
            {
                space = (hit.transform.position - ball.transform.position).magnitude * .5f;
            }
            ball.collider.enabled      = true;
            ball.rigidbody.isKinematic = false;
            return(space);
        }
示例#3
0
        private bool CheckObastacleBetweenBallAndPocket(PoolBall originBall, PocketTrigger pocket)
        {
            Vector3 dir = pocket.pointerPosition - originBall.transform.position;

            RaycastHit[] hit = Physics.SphereCastAll(originBall.transform.position, originBall.GetRadius(),
                                                     dir, dir.magnitude, ConstantData.OulineAndBallLayer);
            foreach (RaycastHit h in hit)
            {
                //Debug.Log("Obastacle between " + originBall.name + " and " + pocket.name + " : " + h.transform.name);
                if (h.collider.name.CompareTo(originBall.name) != 0)
                {
                    return(true);
                }
            }
            return(false);
        }
示例#4
0
 public static void PutBallToThePoint(PoolBall ball, ref Vector3 p)
 {
     float r = ball.GetRadius();
     while (Physics.OverlapSphere(p, r, 1 << LayerMask.NameToLayer("Ball") | 1 << LayerMask.NameToLayer("WhiteBall")).Length != 0)
     {
         p.x -= r;
     }
     SupportTools.SetPosition(ball.gameObject, p, SupportTools.AxisIgnore.IgnoreY, true);
     p.x -= r;
 }
示例#5
0
 private float GetPlacedSpace(PoolBall ball, Vector3 dir)
 {
     ball.collider.enabled = false;
     ball.rigidbody.isKinematic = true;
     RaycastHit hit;
     float space = 0;
     if (Physics.SphereCast(ball.transform.position, ball.GetRadius(), dir, out hit, ConstantData.OulineAndBallLayer))
     {
         space = (hit.transform.position - ball.transform.position).magnitude * .5f;
     }
     ball.collider.enabled = true;
     ball.rigidbody.isKinematic = false;
     return space;
 }
示例#6
0
 private Vector3 ConsiderHitPointWithDrag(Dictionary<PoolBall, List<PocketTrigger>> considerBalls, out Vector3 cueBallPosition, out PoolBall targetBall, out PocketTrigger targetTrigger)
 {
     Dictionary<PoolBall, PocketTrigger> optimalBalls = FilterTheBestPocketForEachBall(considerBalls);
     cueBallPosition = Vector3.zero;
     targetTrigger = null;
     targetBall = null;
     if(optimalBalls.Count == 0)
     {
         return Vector3.zero;
     }
     else
     {
         foreach (KeyValuePair<PoolBall, PocketTrigger> kvp in optimalBalls)
         {
             targetBall = kvp.Key;
             targetTrigger = kvp.Value;
             if (!targetTrigger) continue;
             Vector3 dir = targetBall.transform.position - targetTrigger.pointerPosition;
             //白球摆成和目标球和袋口一条直线
             cueBallPosition = targetBall.transform.position + (dir.normalized * Mathf.Min(GetPlacedSpace(targetBall, targetBall.transform.position - targetTrigger.pointerPosition), 5 * targetBall.GetRadius()));
             //这里随机会跳出循环,代表随机取一个球的意思, optimalBalls.count 为了使概率平均
             if (Random.Range(1, optimalBalls.Count) == 1)
                 break;
         }
         if (!targetTrigger)
         {
             return Vector3.zero;
         }
         return ConsiderHitPoint(targetBall, targetTrigger);
     }
 }
示例#7
0
 private Vector3 ConsiderHitPoint(PoolBall ball, PocketTrigger trigger)
 {
     Vector3 vec = ball.transform.position - trigger.pointerPosition;
     return ball.transform.position + vec.normalized * ball.GetRadius() * 2;
 }
示例#8
0
 private bool CheckObastacleBetweenBallAndPocket(PoolBall originBall, PocketTrigger pocket)
 {
     Vector3 dir = pocket.pointerPosition - originBall.transform.position;
     RaycastHit[] hit = Physics.SphereCastAll(originBall.transform.position, originBall.GetRadius(),
         dir, dir.magnitude, ConstantData.OulineAndBallLayer);
     foreach (RaycastHit h in hit)
     {
         //Debug.Log("Obastacle between " + originBall.name + " and " + pocket.name + " : " + h.transform.name);
         if (h.collider.name.CompareTo(originBall.name) != 0)
             return true;
     }
     return false;
 }
示例#9
0
        private List <KeyValuePair <PoolBall, Vector3> > GetShootableBalls()
        {
            List <KeyValuePair <PoolBall, Vector3> > shootableBalls = new List <KeyValuePair <PoolBall, Vector3> >();
            Vector3 cueBallPosition = Pools.CueBall.GetPosition();

            for (int i = 0; i < cMsg.ballList.Count; i++)
            {
                PoolBall ball     = cMsg.ballList[i];
                Vector3  hitPoint = Vector3.zero;
                if (ball.BallState != PoolBall.State.IDLE)
                {
                    continue;
                }

                //求出dir的2条Y坐标为0的垂直向量, 得到目标球正对于白球的左侧和右侧的击球点,判断白球是否能击中 2个点或者白球中心的点的其中一个
                Vector3   dir = ball.transform.position - cueBallPosition;
                Vector2[] perpendicularVectors = MathTools.PerpendicularVector2D(new Vector2(dir.x, dir.z));


                Vector3[] point3 = new Vector3[]
                {
                    ball.transform.position,
                    ball.transform.position + new Vector3(perpendicularVectors[0].x, 0, perpendicularVectors[0].y) * ball.GetRadius(),
                    ball.transform.position + new Vector3(perpendicularVectors[1].x, 0, perpendicularVectors[1].y) * ball.GetRadius()
                };

                for (int j = 0; j < point3.Length; j++)
                {
                    hitPoint = point3[j];
                    if (!CheckObastacleBetweenTargetPositionAndCueball(ball, hitPoint, cueBallPosition))
                    {
                        shootableBalls.Add(new KeyValuePair <PoolBall, Vector3>(ball, hitPoint));
                        break;
                    }
                }
            }
            return(shootableBalls);
        }
示例#10
0
        private Vector3 ConsiderHitPoint(PoolBall ball, PocketTrigger trigger)
        {
            Vector3 vec = ball.transform.position - trigger.pointerPosition;

            return(ball.transform.position + vec.normalized * ball.GetRadius() * 2);
        }
示例#11
0
        private Dictionary <PoolBall, PocketTrigger> FilterTheBestPocketForEachBall(Dictionary <PoolBall, List <PocketTrigger> > considerBalls)
        {
            Dictionary <PoolBall, PocketTrigger> optimalBalls = new Dictionary <PoolBall, PocketTrigger>();

            foreach (var v in considerBalls)
            {
                PoolBall      ball         = v.Key;
                float         bestDistance = float.MaxValue;
                PocketTrigger bestPocket   = null;
                for (int i = 0, count = v.Value.Count; i < count; i++)
                {
                    PocketTrigger pocket = v.Value[i];

                    if (GetPlacedSpace(ball, ball.transform.position - pocket.pointerPosition) < ball.GetRadius() * 2)
                    {
                        continue;
                    }

                    float distance = Vector3.Distance(ball.transform.position, pocket.pointerPosition);
                    if (distance < bestDistance)
                    {
                        bestPocket   = pocket;
                        bestDistance = distance;
                    }
                }
                optimalBalls.Add(ball, bestPocket);
            }
            return(optimalBalls);
        }
示例#12
0
        private Vector3 ConsiderHitPointWithDrag(Dictionary <PoolBall, List <PocketTrigger> > considerBalls, out Vector3 cueBallPosition, out PoolBall targetBall, out PocketTrigger targetTrigger)
        {
            Dictionary <PoolBall, PocketTrigger> optimalBalls = FilterTheBestPocketForEachBall(considerBalls);

            cueBallPosition = Vector3.zero;
            targetTrigger   = null;
            targetBall      = null;
            if (optimalBalls.Count == 0)
            {
                return(Vector3.zero);
            }
            else
            {
                foreach (KeyValuePair <PoolBall, PocketTrigger> kvp in optimalBalls)
                {
                    targetBall    = kvp.Key;
                    targetTrigger = kvp.Value;
                    if (!targetTrigger)
                    {
                        continue;
                    }
                    Vector3 dir = targetBall.transform.position - targetTrigger.pointerPosition;
                    //白球摆成和目标球和袋口一条直线
                    cueBallPosition = targetBall.transform.position + (dir.normalized * Mathf.Min(GetPlacedSpace(targetBall, targetBall.transform.position - targetTrigger.pointerPosition), 5 * targetBall.GetRadius()));
                    //这里随机会跳出循环,代表随机取一个球的意思, optimalBalls.count 为了使概率平均
                    if (Random.Range(1, optimalBalls.Count) == 1)
                    {
                        break;
                    }
                }
                if (!targetTrigger)
                {
                    return(Vector3.zero);
                }
                return(ConsiderHitPoint(targetBall, targetTrigger));
            }
        }