public void CollisionBetweenCircleAndCircle(CustomCircleCollider circleA, CustomCircleCollider circleB)
    {
        if (circleA == null || circleB == null)
        {
            return;
        }

        float Ax = circleA.transform.position.x;
        float Ay = circleA.transform.position.y;
        float Bx = circleB.transform.position.x;
        float By = circleB.transform.position.y;

        float distanceBetweenCircles = Vector2.Distance(circleA.transform.position, circleB.gameObject.transform.position);

        //UnityEngine.Debug.Log($"d: {distanceBetweenCircles} | diam: {circleA.CircleRadius + circleB.CircleRadius}");

        if (distanceBetweenCircles < circleA.CircleRadius + circleB.CircleRadius)
        {
            //Colisao ocorreu

            float angle = Mathf.Atan2(circleA.transform.position.x - circleB.gameObject.transform.position.x, circleA.transform.position.y - circleB.gameObject.transform.position.y);

            float distanceToMove = (circleA.CircleRadius + circleB.CircleRadius) - distanceBetweenCircles;

            Vector3 movement = new Vector3(angle * distanceBetweenCircles * Time.deltaTime
                                           , angle * distanceBetweenCircles * Time.deltaTime
                                           , 0);

            if (circleB.PhysicsProperties != null)
            {
                if (circleB.PhysicsProperties.canBounce)
                {
                    BounceCollision(circleA, circleB);
                }
                else if (circleB.PhysicsProperties.stopOnCollide || circleA.PhysicsProperties.stopOnCollide)
                {
                    if (circleA.PhysicsProperties.stopOnCollide)
                    {
                        StopOnCollide(circleA, circleB);
                    }
                    else
                    {
                        StopOnCollide(circleB, circleA);
                    }
                }
            }

            //UnityEngine.Debug.Log($"{circleA.name} | {circleB.name}");
            eventBus.Publish(new OnPhysicsObjectCollide(circleA, circleB)); // chamando o evento. Analogo ao "Invoke".
        }
    }
    public void CollisionBetweenCircleAndSquare(CustomCircleCollider circle, CustomSquareCollider square)
    {
        if (circle == null || square == null)
        {
            return;
        }

        float Cx = circle.transform.position.x;
        float Cy = circle.transform.position.y;
        float Sx = square.transform.position.x;
        float Sy = square.transform.position.y;

        //float minDistanceTest = square.transform.position.x + square.size.x - circle.transform.position.x + circle.CircleDiameter;

        //float distanceBetweenObjects = (Cx - Sx * Cx - Sx) + (Cy - Sy * Cy - Sy);
        float distanceBetweenObjects = Vector2.Distance(square.transform.position, circle.gameObject.transform.position);

        if (distanceBetweenObjects < circle.CircleDiameter + square.size.x)
        {
            /*Testando se as bordas do circulo (circulo + raio) estão sobreponto alguma das bordas do quadrilatero em questão*/
            if (Cx + circle.CircleRadius > square.LeftEdge && Cx - circle.CircleRadius < square.RightEdge &&
                (Cy + circle.CircleRadius > square.BottomEdge && square.TopEdge > Cy - circle.CircleRadius ||
                 Cy - circle.CircleRadius < square.TopEdge && square.BottomEdge < Cy + circle.CircleRadius))
            {
                if (circle.PhysicsProperties.canBounce)
                {
                    BounceCollision(circle, square);
                }

                if (circle.PhysicsProperties.stopOnCollide || square.PhysicsProperties.stopOnCollide)
                {
                    if (circle.PhysicsProperties.stopOnCollide)
                    {
                        StopOnCollide(circle, square);
                    }
                    else
                    {
                        StopOnCollide(square, circle);
                    }
                }
                eventBus.Publish(new OnPhysicsObjectCollide(circle, square)); // chamando o evento. Analogo ao "Invoke".
            }
            else
            {
                return;
            }

            eventBus.Publish(new OnPhysicsObjectCollide(square, circle)); // chamando o evento. Analogo ao "Invoke".
        }
    }
Example #3
0
    /// <summary>
    /// Determines whether this instance is colliding with the specified other.
    /// </summary>
    /// <returns><c>true</c> if this instance is colliding with the specified other; otherwise, <c>false</c>.</returns>
    /// <param name="other">Other collider.</param>
    internal bool IsColliding(CustomCircleCollider other)
    {
        if (other == null ||
            !other.isActiveAndEnabled ||
            !isActiveAndEnabled)
        {
            return(false);
        }

        Vector3 delta = transform.position - other.transform.position;

        float distanceSquared = Vector3.Dot(delta, delta);

        float radiusSum = radius + other.radius;

        return(distanceSquared < radiusSum * radiusSum);
    }
Example #4
0
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        CustomCircleCollider col = target as CustomCircleCollider;

        GUILayoutOption option1 = GUILayout.Width(50);
        GUILayoutOption option2 = GUILayout.Width(80);

        //半径
        GUILayout.BeginHorizontal();
        GUILayout.Label("Radius", option1);
        float value = 0;

        if (float.TryParse(GUILayout.TextField(col.mRadius.value.ToString(), option2), out value))
        {
            col.mRadius = new FixedPointF(value);
        }
        GUILayout.EndHorizontal();
    }
Example #5
0
    /// <summary>
    /// 检查凸两个圆是否重合
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static bool CheckCircleAndCircle(CustomCircleCollider a, CustomCircleCollider b)
    {
        //障碍物之间的碰撞不处理
        if (a.mIsobstacle && b.mIsobstacle)
        {
            return(false);
        }

        bool mInit = false;
        //a在左
        bool a_at_left = true;
        //偏移向量
        CustomVector2 offsetvec = new CustomVector2(0, 0);
        //偏移值
        FixedPointF offsetfac = new FixedPointF(0);

        //圆心连线
        CustomVector3 vec3 = a.mTrans.Position - b.mTrans.Position;
        CustomVector2 axis = new CustomVector2(vec3.x, vec3.z);

        FixedPointF x    = axis.x;
        FixedPointF y    = axis.y;
        FixedPointF temp = x * x + y * y;
        FixedPointF z    = FixedPointF.Sqrt(temp);

        //圆心重合,x轴推开
        if (z == FixedPointF.zero)
        {
            axis.x = new FixedPointF(1000, 1000);
            axis.y = new FixedPointF(0, 1000);
        }
        else
        {
            axis.x = x / z;
            axis.y = y / z;
        }


        CustomVector3 apos     = a.mTrans.Position;
        CustomVector2 point    = new CustomVector2(apos.x, apos.z);
        FixedPointF   mapPoint = CustomVector2.Dot(point, axis);
        FixedPointF   min      = mapPoint - a.mRadius;
        FixedPointF   max      = mapPoint + a.mRadius;
        CustomVector2 proj_a   = new CustomVector2(min, max);

        CustomVector3 bpos = b.mTrans.Position;

        point    = new CustomVector2(bpos.x, bpos.z);
        mapPoint = CustomVector2.Dot(point, axis);
        min      = mapPoint - b.mRadius;
        max      = mapPoint + b.mRadius;
        CustomVector2 proj_b = new CustomVector2(min, max);

        if (!Check_Overlap(proj_a, proj_b))
        {
            return(false);
        }
        else
        {
            bool        a_at_left_temp = false;
            FixedPointF offsetfac_temp = new FixedPointF(0);
            Set_PushVec(proj_a, proj_b, ref a_at_left_temp, ref offsetfac_temp);

            if (!mInit)
            {
                a_at_left = a_at_left_temp;
                offsetfac = offsetfac_temp;
                offsetvec = axis;
                mInit     = true;
            }
            else
            {
                if (offsetfac_temp < offsetfac)
                {
                    a_at_left = a_at_left_temp;
                    offsetfac = offsetfac_temp;
                    offsetvec = axis;
                }
            }
        }
        Push(a, b, offsetfac, offsetvec, a_at_left);
        return(true);
    }
Example #6
0
    /// <summary>
    /// 检查凸多边形和圆是否重合
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static bool CheckPolygonAndCircle(CustomPolygonCollider a, CustomCircleCollider b)
    {
        //障碍物之间的碰撞不处理
        if (a.mIsobstacle && b.mIsobstacle)
        {
            return(false);
        }

        List <CustomVector3> a_worldBound = a.LocalToWorldBound;

        bool mInit = false;
        //a在左
        bool a_at_left = true;
        //偏移向量
        CustomVector2 offsetvec = new CustomVector2(0, 0);
        //偏移值
        FixedPointF offsetfac = new FixedPointF(0);

        //顶点连线
        //斜率k
        List <CustomVector2> a_edges = new List <CustomVector2>();

        for (int i = 0; i < a_worldBound.Count; i++)
        {
            int           point1_index = i;
            int           point2_index = (i + 1) % a_worldBound.Count;
            CustomVector3 offset       = a_worldBound[point2_index] - a_worldBound[point1_index];
            a_edges.Add(new CustomVector2(offset.x, offset.z));
        }
        for (int i = 0; i < a_edges.Count; i++)
        {
            CustomVector2 axis = a_edges[i];
            axis = Vec_normal(axis);

            FixedPointF x    = axis.x;
            FixedPointF y    = axis.y;
            FixedPointF temp = x * x + y * y;
            FixedPointF z    = FixedPointF.Sqrt(temp);
            axis.x = x / z;
            axis.y = y / z;

            //求圆在法线上的投影边界
            CustomVector3 vec3     = b.mTrans.Position;
            CustomVector2 point    = new CustomVector2(vec3.x, vec3.z);
            FixedPointF   mapPoint = CustomVector2.Dot(point, axis);
            FixedPointF   min      = mapPoint - b.mRadius;
            FixedPointF   max      = mapPoint + b.mRadius;
            CustomVector2 proj_b   = new CustomVector2(min, max);

            CustomVector2 proj_a = GetMapPointMinMaxDis(a_worldBound, axis);

            if (!Check_Overlap(proj_a, proj_b))
            {
                return(false);
            }
            else
            {
                bool        a_at_left_temp = false;
                FixedPointF offsetfac_temp = new FixedPointF(0);
                Set_PushVec(proj_a, proj_b, ref a_at_left_temp, ref offsetfac_temp);
                if (!mInit)
                {
                    a_at_left = a_at_left_temp;
                    offsetfac = offsetfac_temp;
                    offsetvec = axis;
                    mInit     = true;
                }
                else
                {
                    if (offsetfac_temp < offsetfac)
                    {
                        a_at_left = a_at_left_temp;
                        offsetfac = offsetfac_temp;
                        offsetvec = axis;
                    }
                }
            }
        }
        Push(a, b, offsetfac, offsetvec, a_at_left);
        return(true);
    }