- Home /
How can you visualize a BoxCast, BoxCheck, etc...
I would like to have the equivalent of a Debug.DrawRay for a BoxCast , BoxCheck, etc...
Answer by HiddenMonk · Mar 16, 2016 at 10:04 PM
With the help of this http://answers.unity3d.com/questions/461588/drawing-a-bounding-box-similar-to-box-collider.html I was able to make the below.
using UnityEngine;
public static class ExtDebug
{
//Draws just the box at where it is currently hitting.
public static void DrawBoxCastOnHit(Vector3 origin, Vector3 halfExtents, Quaternion orientation, Vector3 direction, float hitInfoDistance, Color color)
{
origin = CastCenterOnCollision(origin, direction, hitInfoDistance);
DrawBox(origin, halfExtents, orientation, color);
}
//Draws the full box from start of cast to its end distance. Can also pass in hitInfoDistance instead of full distance
public static void DrawBoxCastBox(Vector3 origin, Vector3 halfExtents, Quaternion orientation, Vector3 direction, float distance, Color color)
{
direction.Normalize();
Box bottomBox = new Box(origin, halfExtents, orientation);
Box topBox = new Box(origin + (direction * distance), halfExtents, orientation);
Debug.DrawLine(bottomBox.backBottomLeft, topBox.backBottomLeft, color);
Debug.DrawLine(bottomBox.backBottomRight, topBox.backBottomRight, color);
Debug.DrawLine(bottomBox.backTopLeft, topBox.backTopLeft, color);
Debug.DrawLine(bottomBox.backTopRight, topBox.backTopRight, color);
Debug.DrawLine(bottomBox.frontTopLeft, topBox.frontTopLeft, color);
Debug.DrawLine(bottomBox.frontTopRight, topBox.frontTopRight, color);
Debug.DrawLine(bottomBox.frontBottomLeft, topBox.frontBottomLeft, color);
Debug.DrawLine(bottomBox.frontBottomRight, topBox.frontBottomRight, color);
DrawBox(bottomBox, color);
DrawBox(topBox, color);
}
public static void DrawBox(Vector3 origin, Vector3 halfExtents, Quaternion orientation, Color color)
{
DrawBox(new Box(origin, halfExtents, orientation), color);
}
public static void DrawBox(Box box, Color color)
{
Debug.DrawLine(box.frontTopLeft, box.frontTopRight, color);
Debug.DrawLine(box.frontTopRight, box.frontBottomRight, color);
Debug.DrawLine(box.frontBottomRight, box.frontBottomLeft, color);
Debug.DrawLine(box.frontBottomLeft, box.frontTopLeft, color);
Debug.DrawLine(box.backTopLeft, box.backTopRight, color);
Debug.DrawLine(box.backTopRight, box.backBottomRight, color);
Debug.DrawLine(box.backBottomRight, box.backBottomLeft, color);
Debug.DrawLine(box.backBottomLeft, box.backTopLeft, color);
Debug.DrawLine(box.frontTopLeft, box.backTopLeft, color);
Debug.DrawLine(box.frontTopRight, box.backTopRight, color);
Debug.DrawLine(box.frontBottomRight, box.backBottomRight, color);
Debug.DrawLine(box.frontBottomLeft, box.backBottomLeft, color);
}
public struct Box
{
public Vector3 localFrontTopLeft {get; private set;}
public Vector3 localFrontTopRight {get; private set;}
public Vector3 localFrontBottomLeft {get; private set;}
public Vector3 localFrontBottomRight {get; private set;}
public Vector3 localBackTopLeft {get {return -localFrontBottomRight;}}
public Vector3 localBackTopRight {get {return -localFrontBottomLeft;}}
public Vector3 localBackBottomLeft {get {return -localFrontTopRight;}}
public Vector3 localBackBottomRight {get {return -localFrontTopLeft;}}
public Vector3 frontTopLeft {get {return localFrontTopLeft + origin;}}
public Vector3 frontTopRight {get {return localFrontTopRight + origin;}}
public Vector3 frontBottomLeft {get {return localFrontBottomLeft + origin;}}
public Vector3 frontBottomRight {get {return localFrontBottomRight + origin;}}
public Vector3 backTopLeft {get {return localBackTopLeft + origin;}}
public Vector3 backTopRight {get {return localBackTopRight + origin;}}
public Vector3 backBottomLeft {get {return localBackBottomLeft + origin;}}
public Vector3 backBottomRight {get {return localBackBottomRight + origin;}}
public Vector3 origin {get; private set;}
public Box(Vector3 origin, Vector3 halfExtents, Quaternion orientation) : this(origin, halfExtents)
{
Rotate(orientation);
}
public Box(Vector3 origin, Vector3 halfExtents)
{
this.localFrontTopLeft = new Vector3(-halfExtents.x, halfExtents.y, -halfExtents.z);
this.localFrontTopRight = new Vector3(halfExtents.x, halfExtents.y, -halfExtents.z);
this.localFrontBottomLeft = new Vector3(-halfExtents.x, -halfExtents.y, -halfExtents.z);
this.localFrontBottomRight = new Vector3(halfExtents.x, -halfExtents.y, -halfExtents.z);
this.origin = origin;
}
public void Rotate(Quaternion orientation)
{
localFrontTopLeft = RotatePointAroundPivot(localFrontTopLeft , Vector3.zero, orientation);
localFrontTopRight = RotatePointAroundPivot(localFrontTopRight , Vector3.zero, orientation);
localFrontBottomLeft = RotatePointAroundPivot(localFrontBottomLeft , Vector3.zero, orientation);
localFrontBottomRight = RotatePointAroundPivot(localFrontBottomRight, Vector3.zero, orientation);
}
}
//This should work for all cast types
static Vector3 CastCenterOnCollision(Vector3 origin, Vector3 direction, float hitInfoDistance)
{
return origin + (direction.normalized * hitInfoDistance);
}
static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Quaternion rotation)
{
Vector3 direction = point - pivot;
return pivot + rotation * direction;
}
}
After a few tests.I think the value "halfExtents" in constructor "Box" should be divided by 2 will be more accurate.
public Box(Vector3 origin, Vector3 halfExtents)
{
halfExtents /= 2;
this.localFrontTopLeft = new Vector3(-halfExtents.x, halfExtents.y, -halfExtents.z);
this.localFrontTopRight = new Vector3(halfExtents.x, halfExtents.y, -halfExtents.z);
this.localFrontBottomLeft = new Vector3(-halfExtents.x, -halfExtents.y, -halfExtents.z);
this.localFrontBottomRight = new Vector3(halfExtents.x, -halfExtents.y, -halfExtents.z);
this.origin = origin;
}
I designed the code in a way similar to the Physics.BoxCast method. To do a BoxCast, you must provide the already divided by 2 extents. It does not divide for you. So too for the BoxCast visualizer code above, it is expecting you to provide the already divided by 2 extents. Thats why its named "halfExtents", it wants the half extents.
For example...
Vector3 origin = transform.position
Vector3 halfExtents = Vector3.One / 2f;
Vector3 direction = transform.forward;
Quaternion orientation = transform.rotation;
float distance = 10f;
RaycastHit hitInfo;
if(Physics.BoxCast(origin, halfExtents, direction, out hitInfo, orientation, distance))
{
ExtDebug.DrawBoxCastOnHit(origin, halfExtents, orientation, direction, hitInfo.distance, Color.red)
}
If this confusion was not the issue and there is actually something wrong with the code, please let me know and I will look into it more =)
Also, I should probably swap the orientation and direction parameter order in the visualizer code so that it is even more like the Physics.BoxCast parameter order.
Ah...you're right, and I think I know what make me confuse.
I was using Physic2D.BoxCast for testing, and I thought it worked the same way as 3D BoxCast, but I was wrong, 2D BoxCast second value is "size", and it's no need to divide into 2.
So I decided to add a method "DrawBoxCast2D" in the code you provided so that I won't feel strange every time I use it. :P
Can you provide method that work with Physics2D.BoxCast ??
here:
public static void DrawBoxCast2D(Vector2 origin, Vector2 size, float angle, Vector2 direction, float distance, Color color)
{
Quaternion angle_z = Quaternion.Euler(0f, 0f, angle);
DrawBoxCast(origin, size / 2f, direction, angle_z, distance, color);
}
This was amazingly helpful to discern why my BoxCast does not work! Thank you.
Answer by felix11 · Jun 26, 2016 at 07:19 AM
What about Gizmos? Gizmos.DrawCube();
I preferred a method similar to Debug.DrawRay so that I could put it anywhere in my code and not rely on OnDrawGizmos.
Answer by WarOnGravity · Nov 24, 2018 at 11:57 AM
Can anyone help me understand how to use this code? I don't understand where it goes.
I managed to get boxcasts reporting correctly, but my Gizmos.DrawWireCube(), do not rotate properly. I'd love to be able to see them. Thanks!
'my Gizmos.DrawWireCube(), do not rotate properly'
Use Gizmos.matrix ^^
Answer by ModernArtery · Oct 22, 2020 at 04:48 AM
Really helpful code, thanks! I'm currently trying to get hitboxes figured out, and having an effective visual reference like this is fantastically helpful.
Your answer
Follow this Question
Related Questions
2D 360 degress platformer example needed 0 Answers
OnCollision events are not always fired 2 Answers
Rigidbodies get huge amount of velocity when clipping into other Rigidbodies 2 Answers
Fist Passing Through The Target 2 Answers
How is drag applied to force? 3 Answers