/// <summary> /// Use this method to check if a rect bounds intersects a circle bounds /// </summary> /// <param name="r"></param> /// <param name="c"></param> /// <param name="intersectionPoint"></param> /// <returns></returns> public static bool RectIntersectCircle(BoundsRect r, BoundsCircle c) { Vector2 point = c.center; Vector2 A = r.topLeft; Vector2 B = r.topRight; Vector2 D = r.bottomLeft; float height = r.topLeft.y - r.bottomLeft.y; float width = r.topRight.x - r.topRight.x; float APdotAB = Vector2.Dot(point - A, B - A); float ABdotAB = Vector2.Dot(B - A, B - A); float APdotAD = Vector2.Dot(point - A, D - A); float ADdotAD = Vector2.Dot(D - A, D - A); if (0 <= APdotAB && APdotAB <= ABdotAB && 0 <= APdotAD && APdotAD < ADdotAD) { return(true); } return(LineIntersectCircle(c, r.bottomLeft, r.topRight)); //float rectX = r.bottomLeft.x; //float recty = r.bottomLeft.y; //float nearestX = Mathf.Max(rectX, Mathf.Min(point.x, rectX + width)); //float nearestY = Mathf.Max(recty, Mathf.Min(point.y, recty + height)); //float dX = point.x - nearestX; //float dY = point.y - nearestY; //return (dX * dX + dY * dY) < c.radius * c.radius; }
/// <summary> /// /// </summary> /// <param name="bounds"></param> /// <param name="origin"></param> /// <param name="direction"></param> /// <param name="length"></param> /// <returns></returns> public static bool LineIntersectRect(BoundsRect bounds, Vector2 origin, Vector2 direction, float length) { Vector2 v0 = direction * length; Vector2 endpoint = origin + v0; Vector2 tr = bounds.topRight; Vector2 bl = bounds.bottomLeft; if (bl.x < origin.x && origin.x < tr.x && bl.y < origin.y && origin.y < tr.y) { return(true); } if (LineCrossLine(origin, v0, bounds.bottomLeft, (bounds.bottomRight - bounds.bottomLeft))) { return(true); } if (LineCrossLine(origin, v0, bounds.bottomRight, (bounds.topRight - bounds.bottomRight))) { return(true); } if (LineCrossLine(origin, v0, bounds.topRight, (bounds.topLeft - bounds.topRight))) { return(true); } if (LineCrossLine(origin, v0, bounds.topLeft, (bounds.bottomLeft - bounds.topLeft))) { return(true); } return(false); }
/// <summary> /// This should be called by our HitboxManager /// </summary> public override void UpdateBoundsOfCollider() { BoundsRect b = new BoundsRect(); Vector2 localScale; if (!ignoreParentScale) { localScale = this.transform.localScale; localScale = new Vector2(Mathf.Abs(localScale.x), Mathf.Abs(localScale.y)); } else { localScale = Vector2.one; } Vector2 scaledBoxColliderSize = new Vector2(boxColliderSize.x * localScale.x, boxColliderSize.y * localScale.y); Vector2 origin = this.transform.position + (isStatic ? Vector3.zero : Vector3.up * scaledBoxColliderSize.y / 2) + new Vector3(colliderOffset.x * localScale.x, colliderOffset.y * localScale.y); b.center = origin; b.topLeft = origin + (Vector2.up * scaledBoxColliderSize.y / 2) - (Vector2.right * scaledBoxColliderSize.x / 2); b.topRight = origin + (Vector2.up * scaledBoxColliderSize.y / 2) + (Vector2.right * scaledBoxColliderSize.x / 2); b.bottomLeft = origin - (Vector2.up * scaledBoxColliderSize.y / 2) - (Vector2.right * scaledBoxColliderSize.x / 2); b.bottomRight = origin - (Vector2.up * scaledBoxColliderSize.y / 2) + (Vector2.right * scaledBoxColliderSize.x / 2); this.bounds = b; if (!isStatic) { verticalCheckBounds = this.bounds; horizontalCheckBounds = this.bounds; float verticalOffset = 0; float horizontalOffset = 0; verticalCheckBounds.topLeft.x += HorizontalBuffer / 2; verticalCheckBounds.bottomLeft.x += HorizontalBuffer / 2; verticalCheckBounds.topRight.x -= HorizontalBuffer / 2; verticalCheckBounds.bottomRight.x -= HorizontalBuffer / 2; horizontalCheckBounds.topLeft.y -= VerticalBuffer / 2; horizontalCheckBounds.topRight.y -= VerticalBuffer / 2; horizontalCheckBounds.bottomLeft.y += VerticalBuffer / 2; horizontalCheckBounds.bottomRight.y += VerticalBuffer / 2; if (Mathf.Abs(rigid.Velocity.y) > 0) { verticalOffset = Mathf.Sign(rigid.Velocity.y) * Mathf.Max(VerticalBuffer, Mathf.Abs(rigid.Velocity.y * Overseer.DELTA_TIME)); } if (Mathf.Abs(rigid.Velocity.x) > 0) { horizontalOffset = Mathf.Sign(rigid.Velocity.x) * Mathf.Max(HorizontalBuffer, Mathf.Abs(rigid.Velocity.x * Overseer.DELTA_TIME)); } verticalCheckBounds.SetOffset(Vector2.up * verticalOffset); horizontalCheckBounds.SetOffset(Vector2.right * horizontalOffset); } }
void InitilizeRect() { if (startPoint == null || endPoint == null || uiStartPoint == null || uiEndPoint == null) { Debug.LogError("标识点为空无法创建地图"); } else { actualRect = new BoundsRect(startPoint.transform.position, endPoint.transform.position, true); uiRect = new BoundsRect(uiStartPoint.transform.localPosition, uiEndPoint.transform.localPosition, false); } }
/// <summary> /// /// </summary> /// <param name="c"></param> /// <param name="r"></param> /// <returns></returns> public static bool CapsuleIntersectRect(BoundsCapsule c, BoundsRect r) { if (RectIntersectCircle(r, c.bottomCircleBounds)) { return(true); } if (RectIntersectCircle(r, c.bottomCircleBounds)) { return(true); } if (RectIntersectRect(r, c.rectBounds)) { return(true); } return(false); }
/// <summary> /// Use this method to check if a rect bounds intersects another rect bound /// </summary> /// <returns></returns> public static bool RectIntersectRect(BoundsRect r1, BoundsRect r2) { Vector2 tl1 = r1.topLeft; Vector2 br1 = r1.bottomRight; Vector2 tl2 = r2.topLeft; Vector2 br2 = r2.bottomRight; if (tl1.x > br2.x || tl2.x > br1.x) { return(false); } if (tl1.y < br2.y || tl2.y < br1.y) { return(false); } return(true); }
/// <summary> /// /// </summary> /// <param name="boundsToCheck"></param> /// <param name="colliderToCheck"></param> /// <returns></returns> private bool ColliderIntersectBounds(BoundsRect boundsToCheck, CustomCollider2D colliderToCheck) { if (colliderToCheck is CustomBoxCollider2D) { return(RectIntersectRect(boundsToCheck, ((CustomBoxCollider2D)colliderToCheck).bounds)); } else if (colliderToCheck is CustomCircleCollider2D) { return(RectIntersectCircle(boundsToCheck, ((CustomCircleCollider2D)colliderToCheck).bounds)); } else if (colliderToCheck is CustomCapsuleCollider2D) { return(CapsuleIntersectRect(((CustomCapsuleCollider2D)colliderToCheck).bounds, boundsToCheck)); } else { return(false); } }
/// <summary> /// Returns the collision point of the of the two collider bounds /// </summary> /// <param name="r1"></param> /// <param name="c1"></param> /// <returns></returns> public static Vector2 IntersectionPointNonstaticRectOnStaticCircle(CustomBoxCollider2D nonstaticRectCollider, CustomCircleCollider2D staticCircleCollider, bool collidedVertically = true) { BoundsRect r1 = nonstaticRectCollider.bounds; BoundsCircle c1 = staticCircleCollider.bounds; Vector2 centerPointOfCircle = c1.center; Vector2 collisionPoint; if (collidedVertically) { if (centerPointOfCircle.x < r1.bottomLeft.x) { collisionPoint.x = r1.bottomLeft.x; } else if (centerPointOfCircle.x > r1.bottomRight.x) { collisionPoint.x = r1.bottomRight.x; } else { collisionPoint.x = centerPointOfCircle.x; } return(IntersectionPointColliderVerticalAtXPoint(nonstaticRectCollider, staticCircleCollider, collisionPoint.x)); } else { if (centerPointOfCircle.y < r1.bottomLeft.y) { collisionPoint.y = r1.bottomLeft.y; } else if (centerPointOfCircle.y > r1.topLeft.y) { collisionPoint.y = r1.topLeft.y; } else { collisionPoint.y = centerPointOfCircle.y; } return(IntersectionPointColliderHorizontalAtYPoint(nonstaticRectCollider, staticCircleCollider, collisionPoint.y)); } }
/// <summary> /// /// </summary> /// <param name="y"></param> /// <returns></returns> public static Vector2 GetLeftBoundAtYValueRect(BoundsRect rBounds, float y) { return(new Vector2(rBounds.bottomLeft.x, y)); }
/// <summary> /// /// </summary> /// <param name="y"></param> /// <returns></returns> public static Vector2 GetRighBoundAtYValueRect(BoundsRect rBounds, float y) { return(new Vector2(rBounds.topRight.x, y)); }
/// <summary> /// /// </summary> /// <param name="x"></param> /// <returns></returns> public static Vector2 GetUpperBoundsAtXValueRect(BoundsRect rBounds, float x) { return(new Vector2(x, rBounds.topRight.y)); }
/// <summary> /// /// </summary> /// <param name="x"></param> /// <returns></returns> public static Vector2 GetLowerBoundsAtXValueRect(BoundsRect rBounds, float x) { return(new Vector2(x, rBounds.bottomLeft.y)); }
/// <summary> /// Updates the bounds of the capsule collider. The Capsule collider is made up of one rect bounds and two circle bounds /// </summary> public override void UpdateBoundsOfCollider() { BoundsRect b = new BoundsRect(); Vector2 origin = this.transform.position + new Vector3(colliderOffset.x, colliderOffset.y); float xSize = drawHorizontal ? size : radius * 2; float ySize = drawHorizontal ? radius * 2 : size; b.topLeft = origin + Vector2.up * ySize / 2 - Vector2.right * xSize / 2; b.topRight = origin + Vector2.up * ySize / 2 + Vector2.right * xSize / 2; b.bottomLeft = origin - Vector2.up * ySize / 2 - Vector2.right * xSize / 2; b.bottomRight = origin - Vector2.up * ySize / 2 + Vector2.right * xSize / 2; bounds.rectBounds = b; BoundsCircle topCircle = new BoundsCircle(); topCircle.center = b.topLeft + (b.topRight - b.topLeft) / 2f; topCircle.radius = radius; bounds.topCircleBounds = topCircle; BoundsCircle bottomCircle = new BoundsCircle(); bottomCircle.center = b.bottomLeft + (b.bottomRight - b.bottomLeft) / 2f; bottomCircle.radius = radius; bounds.bottomCircleBounds = bottomCircle; if (!isStatic) { verticalBounds = bounds; verticalBounds.topCircleBounds.radius = bounds.topCircleBounds.radius - colliderBuffer; verticalBounds.bottomCircleBounds.radius = bounds.bottomCircleBounds.radius - colliderBuffer; verticalBounds.rectBounds.topLeft.x = bounds.rectBounds.topLeft.x + colliderBuffer / 2; verticalBounds.rectBounds.topRight.x = bounds.rectBounds.topRight.x - colliderBuffer / 2; verticalBounds.rectBounds.bottomLeft.x = verticalBounds.rectBounds.topLeft.x; verticalBounds.rectBounds.bottomRight.x = verticalBounds.rectBounds.topRight.x; horizontalBounds = bounds; horizontalBounds.topCircleBounds.radius -= colliderBuffer; horizontalBounds.bottomCircleBounds.radius -= colliderBuffer; //horizontalBounds.topCircleBounds.center += Vector2.down * colliderBuffer; //horizontalBounds.bottomCircleBounds.center += Vector2.up * colliderBuffer; Vector2 horizontalOffset = Vector2.zero; Vector2 verticalOffset = Vector2.zero; if (rigid.Velocity.y > 0) { verticalOffset = Vector2.up * Mathf.Max(colliderBuffer, rigid.Velocity.y * Overseer.DELTA_TIME); } else if (rigid.Velocity.y < 0) { verticalOffset = Vector2.up * Mathf.Min(-colliderBuffer, rigid.Velocity.y * Overseer.DELTA_TIME); } if (rigid.Velocity.x > 0) { horizontalOffset = Vector2.right * Mathf.Max(colliderBuffer, rigid.Velocity.x * Overseer.DELTA_TIME); } else if (rigid.Velocity.x < 0) { horizontalOffset = Vector2.right * Mathf.Min(-colliderBuffer, rigid.Velocity.x * Overseer.DELTA_TIME); } verticalBounds.SetOffset(verticalOffset); horizontalBounds.SetOffset(horizontalOffset); } }
/// <summary> /// Test the mouse hit /// </summary> /// <param name="hitPoint">The hit point.</param> /// <returns></returns> public bool HitTest(Point hitPoint) { return(BoundsRect.Contains(hitPoint)); }