Last active
February 12, 2025 04:14
-
-
Save unitycoder/58f4b5d80f423d29e35c814a9556f9d9 to your computer and use it in GitHub Desktop.
Draw Bounds with Debug.DrawLine , Draw Box, Draw Runtime Gizmos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void DrawBounds(Bounds b, float delay=0) | |
{ | |
// bottom | |
var p1 = new Vector3(b.min.x, b.min.y, b.min.z); | |
var p2 = new Vector3(b.max.x, b.min.y, b.min.z); | |
var p3 = new Vector3(b.max.x, b.min.y, b.max.z); | |
var p4 = new Vector3(b.min.x, b.min.y, b.max.z); | |
Debug.DrawLine(p1, p2, Color.blue, delay); | |
Debug.DrawLine(p2, p3, Color.red, delay); | |
Debug.DrawLine(p3, p4, Color.yellow, delay); | |
Debug.DrawLine(p4, p1, Color.magenta, delay); | |
// top | |
var p5 = new Vector3(b.min.x, b.max.y, b.min.z); | |
var p6 = new Vector3(b.max.x, b.max.y, b.min.z); | |
var p7 = new Vector3(b.max.x, b.max.y, b.max.z); | |
var p8 = new Vector3(b.min.x, b.max.y, b.max.z); | |
Debug.DrawLine(p5, p6, Color.blue, delay); | |
Debug.DrawLine(p6, p7, Color.red, delay); | |
Debug.DrawLine(p7, p8, Color.yellow, delay); | |
Debug.DrawLine(p8, p5, Color.magenta, delay); | |
// sides | |
Debug.DrawLine(p1, p5, Color.white, delay); | |
Debug.DrawLine(p2, p6, Color.gray, delay); | |
Debug.DrawLine(p3, p7, Color.green, delay); | |
Debug.DrawLine(p4, p8, Color.cyan, delay); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://forum.unity.com/threads/debug-drawbox-function-is-direly-needed.1038499/ | |
public void DrawBox(Vector3 pos, Quaternion rot, Vector3 scale, Color c) | |
{ | |
// create matrix | |
Matrix4x4 m = new Matrix4x4(); | |
m.SetTRS(pos, rot, scale); | |
var point1 = m.MultiplyPoint(new Vector3(-0.5f, -0.5f, 0.5f)); | |
var point2 = m.MultiplyPoint(new Vector3(0.5f, -0.5f, 0.5f)); | |
var point3 = m.MultiplyPoint(new Vector3(0.5f, -0.5f, -0.5f)); | |
var point4 = m.MultiplyPoint(new Vector3(-0.5f, -0.5f, -0.5f)); | |
var point5 = m.MultiplyPoint(new Vector3(-0.5f, 0.5f, 0.5f)); | |
var point6 = m.MultiplyPoint(new Vector3(0.5f, 0.5f, 0.5f)); | |
var point7 = m.MultiplyPoint(new Vector3(0.5f, 0.5f, -0.5f)); | |
var point8 = m.MultiplyPoint(new Vector3(-0.5f, 0.5f, -0.5f)); | |
Debug.DrawLine(point1, point2, c); | |
Debug.DrawLine(point2, point3, c); | |
Debug.DrawLine(point3, point4, c); | |
Debug.DrawLine(point4, point1, c); | |
Debug.DrawLine(point5, point6, c); | |
Debug.DrawLine(point6, point7, c); | |
Debug.DrawLine(point7, point8, c); | |
Debug.DrawLine(point8, point5, c); | |
Debug.DrawLine(point1, point5, c); | |
Debug.DrawLine(point2, point6, c); | |
Debug.DrawLine(point3, point7, c); | |
Debug.DrawLine(point4, point8, c); | |
// optional axis display | |
Debug.DrawRay(m.GetPosition(), m.GetForward(), Color.magenta); | |
Debug.DrawRay(m.GetPosition(), m.GetUp(), Color.yellow); | |
Debug.DrawRay(m.GetPosition(), m.GetRight(), Color.red); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void DrawPlane(Vector3 position, float distance, Vector3 normal, float duration = 0) | |
{ | |
Vector3 v3; | |
position -= normal * distance; | |
if (normal.normalized != Vector3.forward) | |
{ | |
v3 = Vector3.Cross(normal, Vector3.forward).normalized * normal.magnitude*32; | |
} | |
else | |
{ | |
v3 = Vector3.Cross(normal, Vector3.up).normalized * normal.magnitude*16; | |
} | |
var corner0 = position + v3; | |
var corner2 = position - v3; | |
var q = Quaternion.AngleAxis(90.0f, normal); | |
v3 = q * v3; | |
var corner1 = position + v3; | |
var corner3 = position - v3; | |
Debug.DrawLine(corner0, corner2, Color.green, duration); | |
Debug.DrawLine(corner1, corner3, Color.green, duration); | |
Debug.DrawLine(corner0, corner1, Color.green, duration); | |
Debug.DrawLine(corner1, corner2, Color.green, duration); | |
Debug.DrawLine(corner2, corner3, Color.green, duration); | |
Debug.DrawLine(corner3, corner0, Color.green, duration); | |
Debug.DrawRay(position, normal * 0.2f, Color.cyan); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://forum.unity.com/threads/how-to-see-spherecast.759233/#post-5057492 | |
using UnityEngine; | |
#if UNITY_EDITOR | |
using Handles = UnityEditor.Handles; | |
using HandleUtility = UnityEditor.HandleUtility; | |
#endif | |
namespace Kit | |
{ | |
public struct ColorScope : System.IDisposable | |
{ | |
Color oldColor; | |
public ColorScope(Color color) | |
{ | |
oldColor = Gizmos.color; | |
Gizmos.color = color == default(Color) ? oldColor : color; | |
} | |
public void Dispose() | |
{ | |
Gizmos.color = oldColor; | |
} | |
} | |
/// <summary>Gizmo Extension - Static class that extends Unity's gizmo functionallity.</summary> | |
public static class GizmosExtend | |
{ | |
#region GizmoDrawFunctions | |
/// <summary>- Draws a point.</summary> | |
/// <param name='position'>- The point to draw.</param> | |
/// <param name='color'>- The color of the drawn point.</param> | |
/// <param name='scale'>- The size of the drawn point.</param> | |
public static void DrawPoint(Vector3 position, Color color = default(Color), float scale = 1.0f) | |
{ | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawRay(position + (Vector3.up * (scale * 0.5f)), -Vector3.up * scale); | |
Gizmos.DrawRay(position + (Vector3.right * (scale * 0.5f)), -Vector3.right * scale); | |
Gizmos.DrawRay(position + (Vector3.forward * (scale * 0.5f)), -Vector3.forward * scale); | |
} | |
} | |
public static void DrawRay(Vector3 position, Vector3 direction, Color color = default(Color)) | |
{ | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawRay(position, direction); | |
} | |
} | |
/// <summary>Override DrawLine</summary> | |
/// <param name="from"></param> | |
/// <param name="to"></param> | |
/// <param name="color"></param> | |
public static void DrawLine(Vector3 from, Vector3 to, Color color = default(Color)) | |
{ | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawLine(from, to); | |
} | |
} | |
/// <summary>- Draws an axis-aligned bounding box.</summary> | |
/// <param name='bounds'>- The bounds to draw.</param> | |
/// <param name='color'>- The color of the bounds.</param> | |
public static void DrawBounds(Bounds bounds, Color color = default(Color)) | |
{ | |
Vector3 | |
ruf = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, bounds.extents.z), | |
rub = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, -bounds.extents.z), | |
luf = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, bounds.extents.z), | |
lub = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, -bounds.extents.z), | |
rdf = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, bounds.extents.z), | |
rdb = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, -bounds.extents.z), | |
lfd = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, bounds.extents.z), | |
lbd = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, -bounds.extents.z); | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawLine(ruf, luf); | |
Gizmos.DrawLine(ruf, rub); | |
Gizmos.DrawLine(luf, lub); | |
Gizmos.DrawLine(rub, lub); | |
Gizmos.DrawLine(ruf, rdf); | |
Gizmos.DrawLine(rub, rdb); | |
Gizmos.DrawLine(luf, lfd); | |
Gizmos.DrawLine(lub, lbd); | |
Gizmos.DrawLine(rdf, lfd); | |
Gizmos.DrawLine(rdf, rdb); | |
Gizmos.DrawLine(lfd, lbd); | |
Gizmos.DrawLine(lbd, rdb); | |
} | |
} | |
/// <summary>- Draws a circle.</summary> | |
/// <param name='position'>- Where the center of the circle will be positioned.</param> | |
/// <param name='up'>- The direction perpendicular to the surface of the circle.</param> | |
/// <param name='color'>- The color of the circle.</param> | |
/// <param name='radius'>- The radius of the circle.</param> | |
public static void DrawCircle(Vector3 position, Vector3 up = default(Vector3), Color color = default(Color), float radius = 1.0f) | |
{ | |
up = ((up == default(Vector3)) ? Vector3.up : up).normalized * radius; | |
Vector3 | |
forward = Vector3.Slerp(up, -up, 0.5f), | |
right = Vector3.Cross(up, forward).normalized * radius; | |
Matrix4x4 matrix = new Matrix4x4() | |
{ | |
m00 = right.x, | |
m10 = right.y, | |
m20 = right.z, | |
m01 = up.x, | |
m11 = up.y, | |
m21 = up.z, | |
m02 = forward.x, | |
m12 = forward.y, | |
m22 = forward.z | |
}; | |
Vector3 | |
lastPoint = position + matrix.MultiplyPoint3x4(new Vector3(Mathf.Cos(0), 0, Mathf.Sin(0))), | |
nextPoint = Vector3.zero; | |
using (new ColorScope(color)) | |
{ | |
for (int i = 0; i <= 90; i++) | |
{ | |
nextPoint = position + matrix.MultiplyPoint3x4( | |
new Vector3( | |
Mathf.Cos((i * 4) * Mathf.Deg2Rad), | |
0f, | |
Mathf.Sin((i * 4) * Mathf.Deg2Rad) | |
) | |
); | |
Gizmos.DrawLine(lastPoint, nextPoint); | |
lastPoint = nextPoint; | |
} | |
} | |
} | |
/// <summary>- Draws a cylinder.</summary> | |
/// <param name='start'>- The position of one end of the cylinder.</param> | |
/// <param name='end'>- The position of the other end of the cylinder.</param> | |
/// <param name='color'>- The color of the cylinder.</param> | |
/// <param name='radius'>- The radius of the cylinder.</param> | |
public static void DrawCylinder(Vector3 start, Vector3 end, Color color = default(Color), float radius = 1.0f) | |
{ | |
Vector3 | |
up = (end - start).normalized * radius, | |
forward = Vector3.Slerp(up, -up, 0.5f), | |
right = Vector3.Cross(up, forward).normalized * radius; | |
//Radial circles | |
DrawCircle(start, up, color, radius); | |
DrawCircle(end, -up, color, radius); | |
DrawCircle((start + end) * 0.5f, up, color, radius); | |
using (new ColorScope(color)) | |
{ | |
//Side lines | |
Gizmos.DrawLine(start + right, end + right); | |
Gizmos.DrawLine(start - right, end - right); | |
Gizmos.DrawLine(start + forward, end + forward); | |
Gizmos.DrawLine(start - forward, end - forward); | |
//Start endcap | |
Gizmos.DrawLine(start - right, start + right); | |
Gizmos.DrawLine(start - forward, start + forward); | |
//End endcap | |
Gizmos.DrawLine(end - right, end + right); | |
Gizmos.DrawLine(end - forward, end + forward); | |
} | |
} | |
/// <summary>- Draws a cone.</summary> | |
/// <param name='position'>- The position for the tip of the cone.</param> | |
/// <param name='direction'>- The direction for the cone to get wider in.</param> | |
/// <param name='color'>- The color of the cone.</param> | |
/// <param name='angle'>- The angle of the cone.</param> | |
public static void DrawCone(Vector3 position, Vector3 direction, Color color = default(Color), float angle = 45) | |
{ | |
float length = direction.magnitude; | |
angle = Mathf.Clamp(angle, 0f, 90f); | |
Vector3 | |
forward = direction, | |
up = Vector3.Slerp(forward, -forward, 0.5f), | |
right = Vector3.Cross(forward, up).normalized * length, | |
slerpedVector = Vector3.Slerp(forward, up, angle / 90.0f); | |
Plane farPlane = new Plane(-direction, position + forward); | |
Ray distRay = new Ray(position, slerpedVector); | |
float dist; | |
farPlane.Raycast(distRay, out dist); | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawRay(position, slerpedVector.normalized * dist); | |
Gizmos.DrawRay(position, Vector3.Slerp(forward, -up, angle / 90.0f).normalized * dist); | |
Gizmos.DrawRay(position, Vector3.Slerp(forward, right, angle / 90.0f).normalized * dist); | |
Gizmos.DrawRay(position, Vector3.Slerp(forward, -right, angle / 90.0f).normalized * dist); | |
} | |
DrawCircle(position + forward, direction, color, (forward - (slerpedVector.normalized * dist)).magnitude); | |
DrawCircle(position + (forward * 0.5f), direction, color, ((forward * 0.5f) - (slerpedVector.normalized * (dist * 0.5f))).magnitude); | |
} | |
/// <summary>- Draws an arrow.</summary> | |
/// <param name='position'>- The start position of the arrow.</param> | |
/// <param name='direction'>- The direction the arrow will point in.</param> | |
/// <param name='color'>- The color of the arrow.</param> | |
/// <param name="angle">- The angle of arrow head.0 ~ 90f</param> | |
/// <param name="headLength">- The angle length of arrow head. 0 ~ 1 in percent</param> | |
public static void DrawArrow(Vector3 position, Vector3 direction, Color color = default(Color), float angle = 15f, float headLength = 0.3f) | |
{ | |
if (direction == Vector3.zero) | |
return; // can't draw a thing | |
if (angle < 0f) | |
angle = Mathf.Abs(angle); | |
if (angle > 0f) | |
{ | |
float length = direction.magnitude; | |
float arrowLength = length * Mathf.Clamp01(headLength); | |
Vector3 headDir = direction.normalized * -arrowLength; | |
DrawCone(position + direction, headDir, color, angle); | |
} | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawRay(position, direction); | |
} | |
} | |
/// <summary>- Draws a capsule.</summary> | |
/// <param name='point1'>- The position of one end of the capsule.</param> | |
/// <param name='point2'>- The position of the other end of the capsule.</param> | |
/// <param name='color'>- The color of the capsule.</param> | |
/// <param name='radius'>- The radius of the capsule.</param> | |
public static void DrawCapsule(Vector3 point1, Vector3 point2, float radius = 1f, Color color = default(Color)) | |
{ | |
if (point1 == point2) | |
{ | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawWireSphere(point1, radius); | |
} | |
} | |
else | |
{ | |
float | |
height = (point1 - point2).magnitude, | |
sideLength = Mathf.Max(0, (height * 0.5f)); | |
Vector3 | |
up = (point2 - point1).normalized * radius, | |
forward = Vector3.Slerp(up, -up, 0.5f), | |
right = Vector3.Cross(up, forward).normalized * radius, | |
middle = (point2 + point1) * 0.5f; | |
point1 = middle + ((point1 - middle).normalized * sideLength); | |
point2 = middle + ((point2 - middle).normalized * sideLength); | |
//Radial circles | |
DrawCircle(point1, up, color, radius); | |
DrawCircle(point2, -up, color, radius); | |
using (new ColorScope(color)) | |
{ | |
//Side lines | |
Gizmos.DrawLine(point1 + right, point2 + right); | |
Gizmos.DrawLine(point1 - right, point2 - right); | |
Gizmos.DrawLine(point1 + forward, point2 + forward); | |
Gizmos.DrawLine(point1 - forward, point2 - forward); | |
for (int i = 1; i < 26; i++) | |
{ | |
//Start endcap | |
Gizmos.DrawLine(Vector3.Slerp(right, -up, i / 25.0f) + point1, Vector3.Slerp(right, -up, (i - 1) / 25.0f) + point1); | |
Gizmos.DrawLine(Vector3.Slerp(-right, -up, i / 25.0f) + point1, Vector3.Slerp(-right, -up, (i - 1) / 25.0f) + point1); | |
Gizmos.DrawLine(Vector3.Slerp(forward, -up, i / 25.0f) + point1, Vector3.Slerp(forward, -up, (i - 1) / 25.0f) + point1); | |
Gizmos.DrawLine(Vector3.Slerp(-forward, -up, i / 25.0f) + point1, Vector3.Slerp(-forward, -up, (i - 1) / 25.0f) + point1); | |
//End endcap | |
Gizmos.DrawLine(Vector3.Slerp(right, up, i / 25.0f) + point2, Vector3.Slerp(right, up, (i - 1) / 25.0f) + point2); | |
Gizmos.DrawLine(Vector3.Slerp(-right, up, i / 25.0f) + point2, Vector3.Slerp(-right, up, (i - 1) / 25.0f) + point2); | |
Gizmos.DrawLine(Vector3.Slerp(forward, up, i / 25.0f) + point2, Vector3.Slerp(forward, up, (i - 1) / 25.0f) + point2); | |
Gizmos.DrawLine(Vector3.Slerp(-forward, up, i / 25.0f) + point2, Vector3.Slerp(-forward, up, (i - 1) / 25.0f) + point2); | |
} | |
} | |
} | |
} | |
/// <summary>Draw Camera based on give reference.</summary> | |
/// <param name="camera"></param> | |
/// <param name="color"></param> | |
public static void DrawFrustum(Camera camera, Color color = default(Color)) | |
{ | |
using (new ColorScope(color)) | |
{ | |
Gizmos.matrix = Matrix4x4.TRS(camera.transform.position, camera.transform.rotation, Vector3.one); | |
Gizmos.DrawFrustum(Vector3.zero, camera.fieldOfView, camera.farClipPlane, camera.nearClipPlane, camera.aspect); | |
Gizmos.matrix = Matrix4x4.identity; | |
} | |
} | |
/// <summary>Draw Plane, based on giving points start to end (forward)</summary> | |
/// <param name="start"></param> | |
/// <param name="end"></param> | |
/// <param name="upward"></param> | |
/// <param name="height"></param> | |
/// <param name="color"></param> | |
/// <remarks>pivot point is start point</remarks> | |
public static void DrawPlane(Vector3 start, Vector3 end, Vector3 upward, float height = 1f, Color color = default(Color)) | |
{ | |
float width = Vector3.Distance(start, end); | |
if (Mathf.Approximately(width, 0f)) | |
return; | |
using (new ColorScope(color)) | |
{ | |
Quaternion rotation = | |
Quaternion.LookRotation(end - start, upward) * | |
Quaternion.Euler(0f, -90f, 0f); | |
Gizmos.matrix = Matrix4x4.TRS(start, rotation, Vector3.one); | |
Gizmos.DrawCube( | |
new Vector3(width * 0.5f, height * 0.5f, 0f), | |
new Vector3(width, height, float.Epsilon)); | |
Gizmos.matrix = Matrix4x4.identity; | |
} | |
} | |
/// <summary>Draw Plane, based on transform's forward</summary> | |
/// <param name="self"></param> | |
/// <param name="width"></param> | |
/// <param name="height"></param> | |
/// <param name="color"></param> | |
public static void DrawPlane(Transform self, float width, float height = 1f, Color color = default(Color)) | |
{ | |
DrawPlane(self.position, self.position + (self.forward * width), self.up, height, color); | |
} | |
public static void DrawSphere(Transform self, Color color = default(Color)) | |
{ | |
DrawSphere(self.position, self.localScale.x, color); | |
} | |
/// <summary>Draw Sphere</summary> | |
/// <param name="position"></param> | |
/// <param name="radius"></param> | |
/// <param name="color"></param> | |
public static void DrawSphere(Vector3 position, float radius, Color color = default(Color)) | |
{ | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawSphere(position, radius); | |
} | |
} | |
public static void DrawDirection(Transform self, Color color = default(Color)) | |
{ | |
DrawDirection(self.position, Vector3.forward, self.localScale.x, color); | |
} | |
/// <summary>Draw Direction</summary> | |
/// <param name="position"></param> | |
/// <param name="direction"></param> | |
/// <param name="distance"></param> | |
/// <param name="color"></param> | |
public static void DrawDirection(Vector3 position, Vector3 direction, float distance = 1f, Color color = default(Color)) | |
{ | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawLine(position, position + (direction * distance)); | |
} | |
} | |
#endregion | |
#region Handles | |
#if UNITY_EDITOR | |
private static bool IsHandleHackAvailable => | |
UnityEditor.SceneView.currentDrawingSceneView != null || | |
(Application.isPlaying && Camera.main != null); | |
#else | |
private const bool IsHandleHackAvailable = false; | |
#endif | |
public static float GetHandleSize(Vector3 center) | |
{ | |
#if UNITY_EDITOR | |
if (IsHandleHackAvailable) | |
return HandleUtility.GetHandleSize(center); | |
else | |
#endif | |
return 1f; | |
} | |
/// <summary>Draw label on current SceneView</summary> | |
/// <param name="position"></param> | |
/// <param name="text"></param> | |
/// <param name="style"></param> | |
/// <param name="color"></param> | |
[System.Diagnostics.Conditional("UNITY_EDITOR")] | |
public static void DrawLabel(Vector3 position, string text, GUIStyle style = default(GUIStyle), Color color = default(Color), float offsetX = 0f, float offsetY = 0f) | |
{ | |
#if UNITY_EDITOR | |
if (IsHandleHackAvailable) | |
{ | |
Transform cam = UnityEditor.SceneView.currentDrawingSceneView != null ? | |
UnityEditor.SceneView.currentDrawingSceneView.camera.transform : // Scene View | |
Camera.main.transform; // Only Game View | |
if (Vector3.Dot(cam.forward, position - cam.position) > 0) | |
{ | |
Vector3 pos = position; | |
if (offsetX != 0f || offsetY != 0f) | |
{ | |
Vector3 camRightVector = cam.right * offsetX; // base on view | |
pos += camRightVector + new Vector3(0f, offsetY, 0f); // base on target | |
} | |
if (style == default(GUIStyle)) | |
{ | |
if (color == default(Color)) | |
Handles.Label(pos, text, GUI.skin.textArea); | |
else | |
{ | |
style = new GUIStyle(GUI.skin.textArea); | |
Color old = style.normal.textColor; | |
style.normal.textColor = color; | |
Handles.Label(pos, text, style); | |
style.normal.textColor = old; | |
} | |
} | |
else | |
{ | |
if (color == default(Color)) | |
Handles.Label(pos, text, style); | |
else | |
{ | |
Color old = style.normal.textColor; | |
style.normal.textColor = color; | |
Handles.Label(pos, text, style); | |
style.normal.textColor = old; | |
} | |
} | |
} | |
} | |
#endif | |
} | |
/// <summary>Draw a circular sector (pie piece) in 3D space.</summary> | |
/// <param name="center">The center of the circle</param> | |
/// <param name="normal">The normal of the circle</param> | |
/// <param name="from">The direction of the point on the circumference, relative to the center, where the sector begins</param> | |
/// <param name="angle">The angle of the sector, in degrees.</param> | |
/// <param name="radius">The radius of the circle</param> | |
/// <param name="constantScreenSize">Have constant screen-sized</param> | |
[System.Diagnostics.Conditional("UNITY_EDITOR")] | |
public static void DrawArc(Vector3 center, Vector3 normal, Vector3 from, float angle, float radius, Color color, bool constantScreenSize = true) | |
{ | |
#if UNITY_EDITOR | |
if (IsHandleHackAvailable) | |
{ | |
if (constantScreenSize) | |
radius *= HandleUtility.GetHandleSize(center); | |
using (new HandleColorScope(color)) | |
{ | |
Handles.DrawSolidArc(center, normal, from, angle, radius); | |
} | |
} | |
#endif | |
} | |
/// <summary></summary> | |
/// <param name="center">position</param> | |
/// <param name="from">direction</param> | |
/// <param name="to">direction</param> | |
/// <param name="axis">A vector around, which the other vectors are rotated.</param> | |
/// <param name="radius"></param> | |
/// <param name="constantScreenSize"></param> | |
[System.Diagnostics.Conditional("UNITY_EDITOR")] | |
public static void DrawAngleBetween(Vector3 center, Vector3 from, Vector3 to, Vector3 axis, float radius, Color color, bool constantScreenSize = true, bool label = false) | |
{ | |
#if UNITY_EDITOR | |
if (IsHandleHackAvailable) | |
{ | |
float angle = Vector3.SignedAngle(from, to, axis); | |
DrawArc(center, axis, from, angle, radius, color, constantScreenSize); | |
if (label) | |
{ | |
float factor = constantScreenSize ? HandleUtility.GetHandleSize(center) : 1f; | |
Vector3 labelPos = center + (Vector3.Lerp(from, to, 0.5f) * factor); | |
DrawLabel(labelPos, $"{angle:F2}"); | |
} | |
} | |
#endif | |
} | |
private struct HandleColorScope : System.IDisposable | |
{ | |
Color oldColor; | |
public HandleColorScope(Color color) | |
{ | |
#if UNITY_EDITOR | |
oldColor = Handles.color; | |
Handles.color = color == default(Color) ? oldColor : color; | |
#else | |
oldColor = Color.white; | |
#endif | |
} | |
public void Dispose() | |
{ | |
#if UNITY_EDITOR | |
Handles.color = oldColor; | |
#endif | |
} | |
} | |
#endregion // Handles | |
#region Cube | |
public static void DrawBox(Vector3 origin, Vector3 halfExtents, Quaternion orientation, Color color = default(Color)) | |
{ | |
DrawBox(new Box(origin, halfExtents, orientation), color); | |
} | |
public static void DrawBox(Box box, Color color = default(Color)) | |
{ | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawLine(box.frontTopLeft, box.frontTopRight); | |
Gizmos.DrawLine(box.frontTopRight, box.frontBottomRight); | |
Gizmos.DrawLine(box.frontBottomRight, box.frontBottomLeft); | |
Gizmos.DrawLine(box.frontBottomLeft, box.frontTopLeft); | |
Gizmos.DrawLine(box.backTopLeft, box.backTopRight); | |
Gizmos.DrawLine(box.backTopRight, box.backBottomRight); | |
Gizmos.DrawLine(box.backBottomRight, box.backBottomLeft); | |
Gizmos.DrawLine(box.backBottomLeft, box.backTopLeft); | |
Gizmos.DrawLine(box.frontTopLeft, box.backTopLeft); | |
Gizmos.DrawLine(box.frontTopRight, box.backTopRight); | |
Gizmos.DrawLine(box.frontBottomRight, box.backBottomRight); | |
Gizmos.DrawLine(box.frontBottomLeft, box.backBottomLeft); | |
} | |
} | |
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() | |
{ | |
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); | |
} | |
} | |
//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 = default(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 = default(Color)) | |
{ | |
direction.Normalize(); | |
Box bottomBox = new Box(origin, halfExtents, orientation); | |
Box topBox = new Box(origin + (direction * distance), halfExtents, orientation); | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawLine(bottomBox.backBottomLeft, topBox.backBottomLeft); | |
Gizmos.DrawLine(bottomBox.backBottomRight, topBox.backBottomRight); | |
Gizmos.DrawLine(bottomBox.backTopLeft, topBox.backTopLeft); | |
Gizmos.DrawLine(bottomBox.backTopRight, topBox.backTopRight); | |
Gizmos.DrawLine(bottomBox.frontTopLeft, topBox.frontTopLeft); | |
Gizmos.DrawLine(bottomBox.frontTopRight, topBox.frontTopRight); | |
Gizmos.DrawLine(bottomBox.frontBottomLeft, topBox.frontBottomLeft); | |
Gizmos.DrawLine(bottomBox.frontBottomRight, topBox.frontBottomRight); | |
} | |
DrawBox(bottomBox, color); | |
DrawBox(topBox, color); | |
} | |
//This should work for all cast types | |
private static Vector3 CastCenterOnCollision(Vector3 origin, Vector3 direction, float hitInfoDistance) | |
{ | |
return origin + (direction.normalized * hitInfoDistance); | |
} | |
private static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Quaternion rotation) | |
{ | |
Vector3 direction = point - pivot; | |
return pivot + rotation * direction; | |
} | |
[System.Obsolete("Use DrawBox", true)] | |
private static void DrawLocalCube(ref Color color, ref Vector3 lbb, ref Vector3 rbb, ref Vector3 lbf, ref Vector3 rbf, ref Vector3 lub, ref Vector3 rub, ref Vector3 luf, ref Vector3 ruf) | |
{ | |
using (new ColorScope(color)) | |
{ | |
Gizmos.DrawLine(lbb, rbb); | |
Gizmos.DrawLine(rbb, lbf); | |
Gizmos.DrawLine(lbf, rbf); | |
Gizmos.DrawLine(rbf, lbb); | |
Gizmos.DrawLine(lub, rub); | |
Gizmos.DrawLine(rub, luf); | |
Gizmos.DrawLine(luf, ruf); | |
Gizmos.DrawLine(ruf, lub); | |
Gizmos.DrawLine(lbb, lub); | |
Gizmos.DrawLine(rbb, rub); | |
Gizmos.DrawLine(lbf, luf); | |
Gizmos.DrawLine(rbf, ruf); | |
} | |
} | |
[System.Obsolete("Use DrawBox", true)] | |
/// <summary>- Draws a local cube.</summary> | |
/// <param name='transform'>- The transform the cube will be local to.</param> | |
/// <param name='size'>- The local size of the cube.</param> | |
/// <param name='center'>- The local position of the cube.</param> | |
/// <param name='color'>- The color of the cube.</param> | |
public static void DrawLocalCube(Transform transform, Vector3 size, Color color = default(Color), Vector3 center = default(Vector3)) | |
{ | |
Box box = new Box(transform.position, size * 0.5f, transform.rotation); | |
DrawBox(box, color); | |
} | |
[System.Obsolete("Use DrawBox", true)] | |
/// <summary>- Draws a local cube.</summary> | |
/// <param name='space'>- The space the cube will be local to.</param> | |
/// <param name='size'>- The local size of the cube.</param> | |
/// <param name='center'>- The local position of the cube.</param> | |
/// <param name='color'>- The color of the cube.</param> | |
public static void DrawLocalCube(Matrix4x4 space, Vector3 size = default(Vector3), Color color = default(Color), Vector3 center = default(Vector3)) | |
{ | |
// Box box = new Box(space.GetPosition(), size * 0.5f, space.GetRotation()); | |
size = (size == default(Vector3)) ? Vector3.one : size; | |
Vector3 | |
lbb = space.MultiplyPoint3x4(center + ((-size) * 0.5f)), | |
rbb = space.MultiplyPoint3x4(center + (new Vector3(size.x, -size.y, -size.z) * 0.5f)), | |
lbf = space.MultiplyPoint3x4(center + (new Vector3(size.x, -size.y, size.z) * 0.5f)), | |
rbf = space.MultiplyPoint3x4(center + (new Vector3(-size.x, -size.y, size.z) * 0.5f)), | |
lub = space.MultiplyPoint3x4(center + (new Vector3(-size.x, size.y, -size.z) * 0.5f)), | |
rub = space.MultiplyPoint3x4(center + (new Vector3(size.x, size.y, -size.z) * 0.5f)), | |
luf = space.MultiplyPoint3x4(center + ((size) * 0.5f)), | |
ruf = space.MultiplyPoint3x4(center + (new Vector3(-size.x, size.y, size.z) * 0.5f)); | |
DrawLocalCube(ref color, ref lbb, ref rbb, ref lbf, ref rbf, ref lub, ref rub, ref luf, ref ruf); | |
} | |
[System.Obsolete("Use DrawBox", true)] | |
/// <summary>- Draws a local cube.</summary> | |
/// <param name="position">- The position of the cube.</param> | |
/// <param name="rotation">- The rotation of the cube.</param> | |
/// <param name='size'>- The local size of the cube.</param> | |
/// <param name='color'>- The color of the cube.</param> | |
public static void DrawLocalCube(Vector3 position, Quaternion rotation, Vector3 size = default(Vector3), Color color = default(Color)) | |
{ | |
DrawLocalCube(Matrix4x4.TRS(position, rotation, Vector3.one), size, color, Vector3.zero); | |
} | |
#endregion // Cube | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment