You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/Feel/MMTools/Tools/MMHelpers/MMDebug.cs

1108 lines
36 KiB
C#

3 months ago
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Reflection;
using System.Linq;
using Debug = UnityEngine.Debug;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
/// <summary>
/// Debug helpers
/// </summary>
public static class MMDebug
{
#region Commands
// the cached list of debug log commands
private static MethodInfo[] _commands;
// the max length of the log
private static readonly int _logHistoryMaxLength = 256;
#if UNITY_EDITOR
private static bool _debugDrawEnabledSet = false;
#endif
private static bool _debugDrawEnabled = false;
private static bool _debugLogEnabled = false;
private static bool _debugLogEnabledSet = false;
/// <summary>
/// Returns a list of all the debug command lines found in the project's assemblies
/// </summary>
public static MethodInfo[] Commands
{
get
{
if (_commands == null)
{
_commands = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(
m => m.GetTypes().SelectMany(
n => n.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
.Where(o => o.GetCustomAttribute<MMDebugLogCommandAttribute>() != null))).ToArray();
}
return _commands;
}
}
/// <summary>
/// Tries to input a command
/// </summary>
/// <param name="command"></param>
public static void DebugLogCommand(string command)
{
// if the command is empty we output an empty line
if (command == string.Empty || command == null)
{
LogCommand("", "#ff2a00");
return;
}
// we split around spaces
string[] splitCommand = command.Split(new char[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries);
if (splitCommand == null || splitCommand.Length == 0)
{
LogCommand("Empty command", "#ff2a00");
return;
}
// we check if the first command exists
string commandFirst = MMString.UppercaseFirst(splitCommand[0]);
MethodInfo[] methods = Commands.Where(m => m.Name == commandFirst).ToArray();
if (methods.Length == 0)
{
LogCommand("Command " + commandFirst + " not found.", "#ff2a00");
return;
}
MethodInfo commandInfo;
object[] parameters = null;
if (splitCommand.Length > 1)
{
// if there are arguments
commandInfo = methods.Where(m => m.GetParameters().Length > 0).FirstOrDefault();
if (commandInfo == null)
{
LogCommand("A version of command " + commandFirst + " with arguments could not be found. Maybe try without arguments.", "#ff2a00");
return;
}
MMDebugLogCommandArgumentCountAttribute argumentAttribute = commandInfo.GetCustomAttributes<MMDebugLogCommandArgumentCountAttribute>(true).FirstOrDefault();
if (argumentAttribute != null && argumentAttribute.ArgumentCount > splitCommand.Length - 1)
{
LogCommand("A version of command " + commandFirst + " needs at least " + argumentAttribute.ArgumentCount + " arguments.", "#ff2a00");
return;
}
parameters = new object[] { splitCommand };
}
else
{
// if there are no arguments
commandInfo = methods.Where(m => m.GetParameters().Length == 0).FirstOrDefault();
if (commandInfo == null)
{
LogCommand("A version of command " + commandFirst + " without arguments could not be found.", "#ff2a00");
return;
}
}
LogCommand(command, "#FFC400");
methods[0].Invoke(null, parameters);
}
/// <summary>
/// Logs the command, adding it to the log history and triggers an event
/// </summary>
/// <param name="command"></param>
/// <param name="color"></param>
private static void LogCommand(string command, string color)
{
DebugLogItem item = new DebugLogItem(command, color, Time.frameCount, Time.time, 3, true);
LogHistory.Add(item);
MMDebugLogEvent.Trigger(new DebugLogItem(null, "", Time.frameCount, Time.time, 0, false));
}
#endregion
#region DebugLog
/// <summary>
/// A struct used to store log items
/// </summary>
public struct DebugLogItem
{
public object Message;
public string Color;
public int Framecount;
public float Time;
public int TimePrecision;
public bool DisplayFrameCount;
public DebugLogItem(object message, string color, int framecount, float time, int timePrecision, bool displayFrameCount)
{
Message = message;
Color = color;
Framecount = framecount;
Time = time;
TimePrecision = timePrecision;
DisplayFrameCount = displayFrameCount;
}
}
/// <summary>
/// A list of all the debug logs (up to DebugLogMaxLength entries)
/// </summary>
public static List<DebugLogItem> LogHistory = new List<DebugLogItem>(_logHistoryMaxLength);
/// <summary>
/// Returns a string with all log history condensed
/// </summary>
public static string LogHistoryText
{
get
{
string colorPrefix = "";
string colorSuffix = "";
StringBuilder log = new StringBuilder();
for (int i = 0; i < LogHistory.Count; i++)
{
// colors
if (!string.IsNullOrEmpty(LogHistory[i].Color))
{
colorPrefix = "<color=" + LogHistory[i].Color + ">";
colorSuffix = "</color>";
}
// build output
if (LogHistory[i].DisplayFrameCount)
{
log.Append("<color=#82d3f9>[" + LogHistory[i].Framecount + "]</color> ");
}
log.Append("<color=#f9a682>[" + MMTime.FloatToTimeString(LogHistory[i].Time, false, true, true, true) + "]</color> ");
log.Append(colorPrefix + LogHistory[i].Message + colorSuffix);
log.Append(System.Environment.NewLine);
}
return log.ToString();
}
}
/// <summary>
/// Clears the debug log
/// </summary>
public static void DebugLogClear()
{
LogHistory.Clear();
MMDebugLogEvent.Trigger(new DebugLogItem(null, "", Time.frameCount, Time.time, 0, false));
}
/// <summary>
/// Outputs the message object to the console, prefixed with the current timestamp
/// </summary>
/// <param name="message">Message.</param>
public static void DebugLogTime(object message, string color = "", int timePrecision = 3, bool displayFrameCount = true)
{
if (!DebugLogsEnabled)
{
return;
}
string callerObjectName = new StackTrace().GetFrame(1).GetMethod().ReflectedType.Name;
color = (color == "") ? "#00FFFF" : color;
// colors
string colorPrefix = "";
string colorSuffix = "";
if (!string.IsNullOrEmpty(color))
{
colorPrefix = "<color=" + color + ">";
colorSuffix = "</color>";
}
// build output
string output = "";
if (displayFrameCount)
{
output += "<color=#82d3f9>[f" + Time.frameCount + "]</color> ";
}
output += "<color=#f9a682>[" + MMTime.FloatToTimeString(Time.time, false, true, true, true) + "]</color> ";
output += callerObjectName + " : ";
output += colorPrefix + message + colorSuffix;
// we output to the console
Debug.Log(output);
// we log to the MM console
DebugLogItem item = LogDebugToConsole(message, color, timePrecision, displayFrameCount);
}
/// <summary>
/// Logs the specified message to the console
/// </summary>
/// <param name="message"></param>
/// <param name="color"></param>
/// <param name="timePrecision"></param>
/// <param name="displayFrameCount"></param>
/// <returns></returns>
public static DebugLogItem LogDebugToConsole(object message, string color, int timePrecision, bool displayFrameCount)
{
DebugLogItem item = new DebugLogItem(message, color, Time.frameCount, Time.time, timePrecision, displayFrameCount);
// we add to our DebugLog
if (LogHistory.Count > _logHistoryMaxLength)
{
LogHistory.RemoveAt(0);
}
LogHistory.Add(item);
// we trigger an event
MMDebugLogEvent.Trigger(item);
return item;
}
/// <summary>
/// An event used to broadcast debug logs
/// </summary>
public struct MMDebugLogEvent
{
static private event Delegate OnEvent;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void RuntimeInitialization() { OnEvent = null; }
static public void Register(Delegate callback) { OnEvent += callback; }
static public void Unregister(Delegate callback) { OnEvent -= callback; }
public delegate void Delegate(DebugLogItem item);
static public void Trigger(DebugLogItem item)
{
OnEvent?.Invoke(item);
}
}
#endregion
#region EnableDisableDebugs
/// <summary>
/// whether or not debug logs (MMDebug.DebugLogTime, MMDebug.DebugOnScreen) should be displayed
/// </summary>
public static bool DebugLogsEnabled
{
get
{
if (_debugLogEnabledSet)
{
return _debugLogEnabled;
}
if (PlayerPrefs.HasKey(_editorPrefsDebugLogs))
{
_debugLogEnabled = (PlayerPrefs.GetInt(_editorPrefsDebugLogs) == 0) ? false : true;
}
else
{
_debugLogEnabled = true;
}
_debugLogEnabledSet = true;
return _debugLogEnabled;
}
private set
{
_debugLogEnabledSet = true;
_debugLogEnabled = value;
}
}
/// <summary>
/// whether or not debug draws should be executed
/// </summary>
public static bool DebugDrawEnabled
{
get
{
#if UNITY_EDITOR
if (_debugDrawEnabledSet)
{
return _debugDrawEnabled;
}
if (PlayerPrefs.HasKey(_editorPrefsDebugDraws))
{
_debugDrawEnabled = (PlayerPrefs.GetInt(_editorPrefsDebugDraws) == 0) ? false : true;
}
else
{
_debugDrawEnabled = true;
}
_debugDrawEnabledSet = true;
return _debugDrawEnabled;
#else
return false;
#endif
}
private set { }
}
private const string _editorPrefsDebugLogs = "DebugLogsEnabled";
private const string _editorPrefsDebugDraws = "DebugDrawsEnabled";
/// <summary>
/// Enables or disables debug logs
/// </summary>
/// <param name="status"></param>
public static void SetDebugLogsEnabled(bool status)
{
DebugLogsEnabled = status;
_debugLogEnabled = status;
#if UNITY_EDITOR
int newStatus = status ? 1 : 0;
PlayerPrefs.SetInt(_editorPrefsDebugLogs, newStatus);
#endif
}
/// <summary>
/// Enables or disables debug draws
/// </summary>
/// <param name="status"></param>
public static void SetDebugDrawEnabled(bool status)
{
DebugDrawEnabled = status;
_debugDrawEnabled = status;
#if UNITY_EDITOR
int newStatus = status ? 1 : 0;
PlayerPrefs.SetInt(_editorPrefsDebugDraws, newStatus);
#endif
}
#endregion
#region Casts
/// <summary>
/// Draws a debug ray in 2D and does the actual raycast
/// </summary>
/// <returns>The raycast hit.</returns>
/// <param name="rayOriginPoint">Ray origin point.</param>
/// <param name="rayDirection">Ray direction.</param>
/// <param name="rayDistance">Ray distance.</param>
/// <param name="mask">Mask.</param>
/// <param name="debug">If set to <c>true</c> debug.</param>
/// <param name="color">Color.</param>
public static RaycastHit2D RayCast(Vector2 rayOriginPoint, Vector2 rayDirection, float rayDistance, LayerMask mask, Color color,bool drawGizmo=false)
{
if (drawGizmo && DebugDrawEnabled)
{
Debug.DrawRay (rayOriginPoint, rayDirection * rayDistance, color);
}
return Physics2D.Raycast(rayOriginPoint,rayDirection,rayDistance,mask);
}
/// <summary>
/// Does a boxcast and draws a box gizmo
/// </summary>
/// <param name="origin"></param>
/// <param name="size"></param>
/// <param name="angle"></param>
/// <param name="direction"></param>
/// <param name="length"></param>
/// <param name="mask"></param>
/// <param name="color"></param>
/// <param name="drawGizmo"></param>
/// <returns></returns>
public static RaycastHit2D BoxCast(Vector2 origin, Vector2 size, float angle, Vector2 direction, float length, LayerMask mask, Color color, bool drawGizmo = false)
{
if (drawGizmo && DebugDrawEnabled)
{
Quaternion rotation = Quaternion.Euler(0f, 0f, angle);
Vector3[] points = new Vector3[8];
float halfSizeX = size.x / 2f;
float halfSizeY = size.y / 2f;
points[0] = rotation * (origin + (Vector2.left * halfSizeX) + (Vector2.up * halfSizeY)); // top left
points[1] = rotation * (origin + (Vector2.right * halfSizeX) + (Vector2.up * halfSizeY)); // top right
points[2] = rotation * (origin + (Vector2.right * halfSizeX) - (Vector2.up * halfSizeY)); // bottom right
points[3] = rotation * (origin + (Vector2.left * halfSizeX) - (Vector2.up * halfSizeY)); // bottom left
points[4] = rotation * ((origin + Vector2.left * halfSizeX + Vector2.up * halfSizeY) + length * direction); // top left
points[5] = rotation * ((origin + Vector2.right * halfSizeX + Vector2.up * halfSizeY) + length * direction); // top right
points[6] = rotation * ((origin + Vector2.right * halfSizeX - Vector2.up * halfSizeY) + length * direction); // bottom right
points[7] = rotation * ((origin + Vector2.left * halfSizeX - Vector2.up * halfSizeY) + length * direction); // bottom left
Debug.DrawLine(points[0], points[1], color);
Debug.DrawLine(points[1], points[2], color);
Debug.DrawLine(points[2], points[3], color);
Debug.DrawLine(points[3], points[0], color);
Debug.DrawLine(points[4], points[5], color);
Debug.DrawLine(points[5], points[6], color);
Debug.DrawLine(points[6], points[7], color);
Debug.DrawLine(points[7], points[4], color);
Debug.DrawLine(points[0], points[4], color);
Debug.DrawLine(points[1], points[5], color);
Debug.DrawLine(points[2], points[6], color);
Debug.DrawLine(points[3], points[7], color);
}
return Physics2D.BoxCast(origin, size, angle, direction, length, mask);
}
/// <summary>
/// Draws a debug ray without allocating memory
/// </summary>
/// <returns>The ray cast non alloc.</returns>
/// <param name="array">Array.</param>
/// <param name="rayOriginPoint">Ray origin point.</param>
/// <param name="rayDirection">Ray direction.</param>
/// <param name="rayDistance">Ray distance.</param>
/// <param name="mask">Mask.</param>
/// <param name="color">Color.</param>
/// <param name="drawGizmo">If set to <c>true</c> draw gizmo.</param>
public static RaycastHit2D MonoRayCastNonAlloc(RaycastHit2D[] array, Vector2 rayOriginPoint, Vector2 rayDirection, float rayDistance, LayerMask mask, Color color,bool drawGizmo=false)
{
if (drawGizmo && DebugDrawEnabled)
{
Debug.DrawRay (rayOriginPoint, rayDirection * rayDistance, color);
}
if (Physics2D.RaycastNonAlloc(rayOriginPoint, rayDirection, array, rayDistance, mask) > 0)
{
return array[0];
}
return new RaycastHit2D();
}
/// <summary>
/// Draws a debug ray in 3D and does the actual raycast
/// </summary>
/// <returns>The raycast hit.</returns>
/// <param name="rayOriginPoint">Ray origin point.</param>
/// <param name="rayDirection">Ray direction.</param>
/// <param name="rayDistance">Ray distance.</param>
/// <param name="mask">Mask.</param>
/// <param name="debug">If set to <c>true</c> debug.</param>
/// <param name="color">Color.</param>
/// <param name="drawGizmo">If set to <c>true</c> draw gizmo.</param>
public static RaycastHit Raycast3D(Vector3 rayOriginPoint, Vector3 rayDirection, float rayDistance, LayerMask mask, Color color,bool drawGizmo=false, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal)
{
if (drawGizmo && DebugDrawEnabled)
{
Debug.DrawRay (rayOriginPoint, rayDirection * rayDistance, color);
}
RaycastHit hit;
Physics.Raycast(rayOriginPoint, rayDirection, out hit, rayDistance, mask, queryTriggerInteraction);
return hit;
}
#endregion
#region DebugOnScreen
//public static MMConsole _console;
public static MMDebugOnScreenConsole _console;
private const string _debugConsolePrefabPath = "MMDebugOnScreenConsole";
/// <summary>
/// Instantiates a MMConsole if there isn't one already, and adds the message in parameter to it.
/// </summary>
/// <param name="message">Message.</param>
public static void DebugOnScreen(string message)
{
if (!DebugLogsEnabled)
{
return;
}
InstantiateOnScreenConsole();
_console.AddMessage(message, "", 30);
}
/// <summary>
/// Instantiates a MMConsole if there isn't one already, and displays the label in bold and its value next to it.
/// </summary>
/// <param name="label">Label.</param>
/// <param name="value">Value.</param>
/// <param name="fontSize">The optional font size.</param>
public static void DebugOnScreen(string label, object value, int fontSize=25)
{
if (!DebugLogsEnabled)
{
return;
}
InstantiateOnScreenConsole(fontSize);
_console.AddMessage(label, value, fontSize);
}
/// <summary>
/// Instantiates the on screen console if there isn't one already
/// </summary>
public static void InstantiateOnScreenConsole(int fontSize=25)
{
if (!DebugLogsEnabled)
{
return;
}
if (_console == null)
{
// we try to find one in the scene
_console = (MMDebugOnScreenConsole) GameObject.FindObjectOfType(typeof(MMDebugOnScreenConsole));
}
if (_console == null)
{
// we instantiate the console
GameObject loaded = UnityEngine.Object.Instantiate(Resources.Load(_debugConsolePrefabPath) as GameObject);
loaded.name = "MMDebugOnScreenConsole";
_console = loaded.GetComponent<MMDebugOnScreenConsole>();
}
}
/// <summary>
/// Use this method to specify what console to use
/// </summary>
/// <param name="newConsole"></param>
public static void SetOnScreenConsole(MMDebugOnScreenConsole newConsole)
{
_console = newConsole;
}
#endregion
#region DebugDraw
/// <summary>
/// Draws a gizmo arrow going from the origin position and along the direction Vector3
/// </summary>
/// <param name="origin">Origin.</param>
/// <param name="direction">Direction.</param>
/// <param name="color">Color.</param>
public static void DrawGizmoArrow(Vector3 origin, Vector3 direction, Color color, float arrowHeadLength = 3f, float arrowHeadAngle = 25f)
{
if (!DebugDrawEnabled)
{
return;
}
Gizmos.color = color;
Gizmos.DrawRay(origin, direction);
DrawArrowEnd(true, origin, direction, color, arrowHeadLength, arrowHeadAngle);
}
/// <summary>
/// Draws a debug arrow going from the origin position and along the direction Vector3
/// </summary>
/// <param name="origin">Origin.</param>
/// <param name="direction">Direction.</param>
/// <param name="color">Color.</param>
public static void DebugDrawArrow(Vector3 origin, Vector3 direction, Color color, float arrowHeadLength = 0.2f, float arrowHeadAngle = 35f)
{
if (!DebugDrawEnabled)
{
return;
}
Debug.DrawRay(origin, direction, color);
DrawArrowEnd(false,origin,direction,color,arrowHeadLength,arrowHeadAngle);
}
/// <summary>
/// Draws a debug arrow going from the origin position and along the direction Vector3
/// </summary>
/// <param name="origin">Origin.</param>
/// <param name="direction">Direction.</param>
/// <param name="color">Color.</param>
/// <param name="arrowLength">Arrow length.</param>
/// <param name="arrowHeadLength">Arrow head length.</param>
/// <param name="arrowHeadAngle">Arrow head angle.</param>
public static void DebugDrawArrow(Vector3 origin, Vector3 direction, Color color, float arrowLength, float arrowHeadLength = 0.20f, float arrowHeadAngle = 35.0f)
{
if (!DebugDrawEnabled)
{
return;
}
Debug.DrawRay(origin, direction * arrowLength, color);
DrawArrowEnd(false,origin,direction * arrowLength,color,arrowHeadLength,arrowHeadAngle);
}
/// <summary>
/// Draws a debug cross of the specified size and color at the specified point
/// </summary>
/// <param name="spot">Spot.</param>
/// <param name="crossSize">Cross size.</param>
/// <param name="color">Color.</param>
public static void DebugDrawCross (Vector3 spot, float crossSize, Color color)
{
if (!DebugDrawEnabled)
{
return;
}
Vector3 tempOrigin = Vector3.zero;
Vector3 tempDirection = Vector3.zero;
tempOrigin.x = spot.x - crossSize / 2;
tempOrigin.y = spot.y - crossSize / 2;
tempOrigin.z = spot.z ;
tempDirection.x = 1;
tempDirection.y = 1;
tempDirection.z = 0;
Debug.DrawRay (tempOrigin, tempDirection * crossSize, color);
tempOrigin.x = spot.x - crossSize / 2;
tempOrigin.y = spot.y + crossSize / 2;
tempOrigin.z = spot.z ;
tempDirection.x = 1;
tempDirection.y = -1;
tempDirection.z = 0;
Debug.DrawRay (tempOrigin, tempDirection * crossSize, color);
}
/// <summary>
/// Draws the arrow end for DebugDrawArrow
/// </summary>
/// <param name="drawGizmos">If set to <c>true</c> draw gizmos.</param>
/// <param name="arrowEndPosition">Arrow end position.</param>
/// <param name="direction">Direction.</param>
/// <param name="color">Color.</param>
/// <param name="arrowHeadLength">Arrow head length.</param>
/// <param name="arrowHeadAngle">Arrow head angle.</param>
private static void DrawArrowEnd (bool drawGizmos, Vector3 arrowEndPosition, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 40.0f)
{
if (!DebugDrawEnabled)
{
return;
}
if (direction == Vector3.zero)
{
return;
}
Vector3 right = Quaternion.LookRotation (direction) * Quaternion.Euler (arrowHeadAngle, 0, 0) * Vector3.back;
Vector3 left = Quaternion.LookRotation (direction) * Quaternion.Euler (-arrowHeadAngle, 0, 0) * Vector3.back;
Vector3 up = Quaternion.LookRotation (direction) * Quaternion.Euler (0, arrowHeadAngle, 0) * Vector3.back;
Vector3 down = Quaternion.LookRotation (direction) * Quaternion.Euler (0, -arrowHeadAngle, 0) * Vector3.back;
if (drawGizmos)
{
Gizmos.color = color;
Gizmos.DrawRay (arrowEndPosition + direction, right * arrowHeadLength);
Gizmos.DrawRay (arrowEndPosition + direction, left * arrowHeadLength);
Gizmos.DrawRay (arrowEndPosition + direction, up * arrowHeadLength);
Gizmos.DrawRay (arrowEndPosition + direction, down * arrowHeadLength);
}
else
{
Debug.DrawRay (arrowEndPosition + direction, right * arrowHeadLength, color);
Debug.DrawRay (arrowEndPosition + direction, left * arrowHeadLength, color);
Debug.DrawRay (arrowEndPosition + direction, up * arrowHeadLength, color);
Debug.DrawRay (arrowEndPosition + direction, down * arrowHeadLength, color);
}
}
/// <summary>
/// Draws handles to materialize the bounds of an object on screen.
/// </summary>
/// <param name="bounds">Bounds.</param>
/// <param name="color">Color.</param>
public static void DrawHandlesBounds(Bounds bounds, Color color)
{
if (!DebugDrawEnabled)
{
return;
}
#if UNITY_EDITOR
Vector3 boundsCenter = bounds.center;
Vector3 boundsExtents = bounds.extents;
Vector3 v3FrontTopLeft = new Vector3(boundsCenter.x - boundsExtents.x, boundsCenter.y + boundsExtents.y, boundsCenter.z - boundsExtents.z); // Front top left corner
Vector3 v3FrontTopRight = new Vector3(boundsCenter.x + boundsExtents.x, boundsCenter.y + boundsExtents.y, boundsCenter.z - boundsExtents.z); // Front top right corner
Vector3 v3FrontBottomLeft = new Vector3(boundsCenter.x - boundsExtents.x, boundsCenter.y - boundsExtents.y, boundsCenter.z - boundsExtents.z); // Front bottom left corner
Vector3 v3FrontBottomRight = new Vector3(boundsCenter.x + boundsExtents.x, boundsCenter.y - boundsExtents.y, boundsCenter.z - boundsExtents.z); // Front bottom right corner
Vector3 v3BackTopLeft = new Vector3(boundsCenter.x - boundsExtents.x, boundsCenter.y + boundsExtents.y, boundsCenter.z + boundsExtents.z); // Back top left corner
Vector3 v3BackTopRight = new Vector3(boundsCenter.x + boundsExtents.x, boundsCenter.y + boundsExtents.y, boundsCenter.z + boundsExtents.z); // Back top right corner
Vector3 v3BackBottomLeft = new Vector3(boundsCenter.x - boundsExtents.x, boundsCenter.y - boundsExtents.y, boundsCenter.z + boundsExtents.z); // Back bottom left corner
Vector3 v3BackBottomRight = new Vector3(boundsCenter.x + boundsExtents.x, boundsCenter.y - boundsExtents.y, boundsCenter.z + boundsExtents.z); // Back bottom right corner
Handles.color = color;
Handles.DrawLine (v3FrontTopLeft, v3FrontTopRight);
Handles.DrawLine (v3FrontTopRight, v3FrontBottomRight);
Handles.DrawLine (v3FrontBottomRight, v3FrontBottomLeft);
Handles.DrawLine (v3FrontBottomLeft, v3FrontTopLeft);
Handles.DrawLine (v3BackTopLeft, v3BackTopRight);
Handles.DrawLine (v3BackTopRight, v3BackBottomRight);
Handles.DrawLine (v3BackBottomRight, v3BackBottomLeft);
Handles.DrawLine (v3BackBottomLeft, v3BackTopLeft);
Handles.DrawLine (v3FrontTopLeft, v3BackTopLeft);
Handles.DrawLine (v3FrontTopRight, v3BackTopRight);
Handles.DrawLine (v3FrontBottomRight, v3BackBottomRight);
Handles.DrawLine (v3FrontBottomLeft, v3BackBottomLeft);
#endif
}
/// <summary>
/// Draws a solid rectangle at the specified position and size, and of the specified colors
/// </summary>
/// <param name="position"></param>
/// <param name="size"></param>
/// <param name="borderColor"></param>
/// <param name="solidColor"></param>
public static void DrawSolidRectangle(Vector3 position, Vector3 size, Color borderColor, Color solidColor)
{
if (!DebugDrawEnabled)
{
return;
}
#if UNITY_EDITOR
Vector3 halfSize = size / 2f;
Vector3[] verts = new Vector3[4];
verts[0] = new Vector3(halfSize.x, halfSize.y, halfSize.z);
verts[1] = new Vector3(-halfSize.x, halfSize.y, halfSize.z);
verts[2] = new Vector3(-halfSize.x, -halfSize.y, halfSize.z);
verts[3] = new Vector3(halfSize.x, -halfSize.y, halfSize.z);
Handles.DrawSolidRectangleWithOutline(verts, solidColor, borderColor);
#endif
}
/// <summary>
/// Draws a gizmo sphere of the specified size and color at a position
/// </summary>
/// <param name="position">Position.</param>
/// <param name="size">Size.</param>
/// <param name="color">Color.</param>
public static void DrawGizmoPoint(Vector3 position, float size, Color color)
{
if (!DebugDrawEnabled)
{
return;
}
Gizmos.color = color;
Gizmos.DrawWireSphere(position,size);
}
/// <summary>
/// Draws a cube at the specified position, and of the specified color and size
/// </summary>
/// <param name="position">Position.</param>
/// <param name="color">Color.</param>
/// <param name="size">Size.</param>
public static void DrawCube (Vector3 position, Color color, Vector3 size)
{
if (!DebugDrawEnabled)
{
return;
}
Vector3 halfSize = size / 2f;
Vector3[] points = new Vector3 []
{
position + new Vector3(halfSize.x,halfSize.y,halfSize.z),
position + new Vector3(-halfSize.x,halfSize.y,halfSize.z),
position + new Vector3(-halfSize.x,-halfSize.y,halfSize.z),
position + new Vector3(halfSize.x,-halfSize.y,halfSize.z),
position + new Vector3(halfSize.x,halfSize.y,-halfSize.z),
position + new Vector3(-halfSize.x,halfSize.y,-halfSize.z),
position + new Vector3(-halfSize.x,-halfSize.y,-halfSize.z),
position + new Vector3(halfSize.x,-halfSize.y,-halfSize.z),
};
Debug.DrawLine (points[0], points[1], color );
Debug.DrawLine (points[1], points[2], color );
Debug.DrawLine (points[2], points[3], color );
Debug.DrawLine (points[3], points[0], color );
}
/// <summary>
/// Draws a cube at the specified position, offset, and of the specified size
/// </summary>
/// <param name="transform"></param>
/// <param name="offset"></param>
/// <param name="cubeSize"></param>
/// <param name="wireOnly"></param>
public static void DrawGizmoCube(Transform transform, Vector3 offset, Vector3 cubeSize, bool wireOnly)
{
if (!DebugDrawEnabled)
{
return;
}
Matrix4x4 rotationMatrix = transform.localToWorldMatrix;
Gizmos.matrix = rotationMatrix;
if (wireOnly)
{
Gizmos.DrawWireCube(offset, cubeSize);
}
else
{
Gizmos.DrawCube(offset, cubeSize);
}
}
/// <summary>
/// Draws a gizmo rectangle
/// </summary>
/// <param name="center">Center.</param>
/// <param name="size">Size.</param>
/// <param name="color">Color.</param>
public static void DrawGizmoRectangle(Vector2 center, Vector2 size, Color color)
{
if (!DebugDrawEnabled)
{
return;
}
Gizmos.color = color;
Vector3 v3TopLeft = new Vector3(center.x - size.x/2, center.y + size.y/2, 0);
Vector3 v3TopRight = new Vector3(center.x + size.x/2, center.y + size.y/2, 0);;
Vector3 v3BottomRight = new Vector3(center.x + size.x/2, center.y - size.y/2, 0);;
Vector3 v3BottomLeft = new Vector3(center.x - size.x/2, center.y - size.y/2, 0);;
Gizmos.DrawLine(v3TopLeft,v3TopRight);
Gizmos.DrawLine(v3TopRight,v3BottomRight);
Gizmos.DrawLine(v3BottomRight,v3BottomLeft);
Gizmos.DrawLine(v3BottomLeft,v3TopLeft);
}
/// <summary>
/// Draws a gizmo rectangle
/// </summary>
/// <param name="center">Center.</param>
/// <param name="size">Size.</param>
/// <param name="color">Color.</param>
public static void DrawGizmoRectangle(Vector2 center, Vector2 size, Matrix4x4 rotationMatrix, Color color)
{
if (!DebugDrawEnabled)
{
return;
}
GL.PushMatrix();
Gizmos.color = color;
Vector3 v3TopLeft = rotationMatrix * new Vector3(center.x - size.x / 2, center.y + size.y / 2, 0);
Vector3 v3TopRight = rotationMatrix * new Vector3(center.x + size.x / 2, center.y + size.y / 2, 0); ;
Vector3 v3BottomRight = rotationMatrix * new Vector3(center.x + size.x / 2, center.y - size.y / 2, 0); ;
Vector3 v3BottomLeft = rotationMatrix * new Vector3(center.x - size.x / 2, center.y - size.y / 2, 0); ;
Gizmos.DrawLine(v3TopLeft, v3TopRight);
Gizmos.DrawLine(v3TopRight, v3BottomRight);
Gizmos.DrawLine(v3BottomRight, v3BottomLeft);
Gizmos.DrawLine(v3BottomLeft, v3TopLeft);
GL.PopMatrix();
}
/// <summary>
/// Draws a rectangle based on a Rect and color
/// </summary>
/// <param name="rectangle">Rectangle.</param>
/// <param name="color">Color.</param>
public static void DrawRectangle (Rect rectangle, Color color)
{
if (!DebugDrawEnabled)
{
return;
}
Vector3 pos = new Vector3( rectangle.x + rectangle.width/2, rectangle.y + rectangle.height/2, 0.0f );
Vector3 scale = new Vector3 (rectangle.width, rectangle.height, 0.0f );
MMDebug.DrawRectangle (pos, color, scale);
}
/// <summary>
/// Draws a rectangle of the specified color and size at the specified position
/// </summary>
/// <param name="position">Position.</param>
/// <param name="color">Color.</param>
/// <param name="size">Size.</param>
public static void DrawRectangle (Vector3 position, Color color, Vector3 size)
{
if (!DebugDrawEnabled)
{
return;
}
Vector3 halfSize = size / 2f;
Vector3[] points = new Vector3 []
{
position + new Vector3(halfSize.x,halfSize.y,halfSize.z),
position + new Vector3(-halfSize.x,halfSize.y,halfSize.z),
position + new Vector3(-halfSize.x,-halfSize.y,halfSize.z),
position + new Vector3(halfSize.x,-halfSize.y,halfSize.z),
};
Debug.DrawLine (points[0], points[1], color );
Debug.DrawLine (points[1], points[2], color );
Debug.DrawLine (points[2], points[3], color );
Debug.DrawLine (points[3], points[0], color );
}
/// <summary>
/// Draws a point of the specified color and size at the specified position
/// </summary>
/// <param name="pos">Position.</param>
/// <param name="col">Col.</param>
/// <param name="scale">Scale.</param>
public static void DrawPoint (Vector3 position, Color color, float size)
{
if (!DebugDrawEnabled)
{
return;
}
Vector3[] points = new Vector3[]
{
position + (Vector3.up * size),
position - (Vector3.up * size),
position + (Vector3.right * size),
position - (Vector3.right * size),
position + (Vector3.forward * size),
position - (Vector3.forward * size)
};
Debug.DrawLine (points[0], points[1], color );
Debug.DrawLine (points[2], points[3], color );
Debug.DrawLine (points[4], points[5], color );
Debug.DrawLine (points[0], points[2], color );
Debug.DrawLine (points[0], points[3], color );
Debug.DrawLine (points[0], points[4], color );
Debug.DrawLine (points[0], points[5], color );
Debug.DrawLine (points[1], points[2], color );
Debug.DrawLine (points[1], points[3], color );
Debug.DrawLine (points[1], points[4], color );
Debug.DrawLine (points[1], points[5], color );
Debug.DrawLine (points[4], points[2], color );
Debug.DrawLine (points[4], points[3], color );
Debug.DrawLine (points[5], points[2], color );
Debug.DrawLine (points[5], points[3], color );
}
/// <summary>
/// Draws a line of the specified color and size using gizmos
/// </summary>
/// <param name="position"></param>
/// <param name="color"></param>
/// <param name="size"></param>
public static void DrawGizmoPoint (Vector3 position, Color color, float size)
{
if (!DebugDrawEnabled)
{
return;
}
Vector3[] points = new Vector3[]
{
position + (Vector3.up * size),
position - (Vector3.up * size),
position + (Vector3.right * size),
position - (Vector3.right * size),
position + (Vector3.forward * size),
position - (Vector3.forward * size)
};
Gizmos.color = color;
Gizmos.DrawLine (points[0], points[1]);
Gizmos.DrawLine (points[2], points[3]);
Gizmos.DrawLine (points[4], points[5]);
Gizmos.DrawLine (points[0], points[2]);
Gizmos.DrawLine (points[0], points[3]);
Gizmos.DrawLine (points[0], points[4]);
Gizmos.DrawLine (points[0], points[5]);
Gizmos.DrawLine (points[1], points[2]);
Gizmos.DrawLine (points[1], points[3]);
Gizmos.DrawLine (points[1], points[4]);
Gizmos.DrawLine (points[1], points[5]);
Gizmos.DrawLine (points[4], points[2]);
Gizmos.DrawLine (points[4], points[3]);
Gizmos.DrawLine (points[5], points[2]);
Gizmos.DrawLine (points[5], points[3]);
}
#endregion
#region Info
public static string GetSystemInfo()
{
string result = "SYSTEM INFO";
#if UNITY_IOS
result += "\n[iPhone generation]iPhone.generation.ToString()";
#endif
#if UNITY_ANDROID
result += "\n[system info]" + SystemInfo.deviceModel;
#endif
result += "\n<color=#FFFFFF>Device Type :</color> " + SystemInfo.deviceType;
result += "\n<color=#FFFFFF>OS Version :</color> " + SystemInfo.operatingSystem;
result += "\n<color=#FFFFFF>System Memory Size :</color> " + SystemInfo.systemMemorySize;
result += "\n<color=#FFFFFF>Graphic Device Name :</color> " + SystemInfo.graphicsDeviceName + " (version " + SystemInfo.graphicsDeviceVersion + ")";
result += "\n<color=#FFFFFF>Graphic Memory Size :</color> " + SystemInfo.graphicsMemorySize;
result += "\n<color=#FFFFFF>Graphic Max Texture Size :</color> " + SystemInfo.maxTextureSize;
result += "\n<color=#FFFFFF>Graphic Shader Level :</color> " + SystemInfo.graphicsShaderLevel;
result += "\n<color=#FFFFFF>Compute Shader Support :</color> " + SystemInfo.supportsComputeShaders;
result += "\n<color=#FFFFFF>Processor Count :</color> " + SystemInfo.processorCount;
result += "\n<color=#FFFFFF>Processor Type :</color> " + SystemInfo.processorType;
result += "\n<color=#FFFFFF>3D Texture Support :</color> " + SystemInfo.supports3DTextures;
result += "\n<color=#FFFFFF>Shadow Support :</color> " + SystemInfo.supportsShadows;
result += "\n<color=#FFFFFF>Platform :</color> " + Application.platform;
result += "\n<color=#FFFFFF>Screen Size :</color> " + Screen.width + " x " + Screen.height;
result += "\n<color=#FFFFFF>DPI :</color> " + Screen.dpi;
return result;
}
#endregion
#region Console
public static void ClearConsole()
{
Type logEntries = System.Type.GetType("UnityEditor.LogEntries, UnityEditor.dll");
if (logEntries != null)
{
MethodInfo clearMethod = logEntries.GetMethod("Clear", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
if (clearMethod != null)
{
clearMethod.Invoke(null, null);
}
}
}
#endregion
}
}