namespace Fusion.Addons.KCC { using UnityEngine; using System.Runtime.CompilerServices; // This file contains utilities for debugging. public partial class KCC { // PRIVATE MEMBERS private static readonly Vector3[] _spherePoints = MakeUnitSphere(24); private static readonly Vector3[] _lowerHemiSpherePoints = MakeLowerUnitHemiSphere(24); private static readonly Vector3[] _upperHemiSpherePoints = MakeUpperUnitHemiSphere(24); // PUBLIC METHODS /// /// Logs current KCC and KCCData state. /// [HideInCallstack] public void Dump() { _debug.Dump(this); } /// /// Enable logs for a given duration. This outputs same logs as Dump(). /// Duration of logs. Use negative value for infinite logging. /// public void EnableLogs(float duration = -1.0f) { _debug.EnableLogs(this, duration); } /// /// Logs info message into console with frame/tick metadata. /// /// Custom message objects. [HideInCallstack] public void Log(params object[] messages) { KCCUtility.Log(this, default, EKCCLogType.Info, messages); } /// /// Logs warning message into console with frame/tick metadata. /// /// Custom message objects. [HideInCallstack] public void LogWarning(params object[] messages) { KCCUtility.Log(this, default, EKCCLogType.Warning, messages); } /// /// Logs error message into console with frame/tick metadata. /// /// Custom message objects. [HideInCallstack] public void LogError(params object[] messages) { KCCUtility.Log(this, default, EKCCLogType.Error, messages); } /// /// Draws debug line in editor scene view. /// The color is yellow (forward tick), red (resimulation tick) or green (render). /// /// Duration of the drawing. public void DrawLine(float duration = 0.0f) { Color color; Vector3 position; NetworkRunner runner = Runner; if (runner != null) { bool isInFixedUpdate = runner.Stage != default; bool isInForwardTick = runner.IsForward == true; if (isInFixedUpdate == true) { position = _fixedData.TargetPosition; if (isInForwardTick == true) { color = new Color(1.0f, 1.0f, 0.0f, 1.0f); } else { color = new Color(1.0f, 0.0f, 0.0f, 1.0f); } } else { position = _renderData.TargetPosition; color = new Color(0.0f, 1.0f, 0.0f, 1.0f); } } else { position = _transform.position; color = new Color(0.0f, 0.0f, 1.0f, 1.0f); } UnityEngine.Debug.DrawLine(position, position + Vector3.up, color, duration); } /// /// Draws debug line in editor scene view. /// /// Color of the line. /// Duration of the drawing. public void DrawLine(Color color, float duration = 0.0f) { Vector3 position = Data.TargetPosition; UnityEngine.Debug.DrawLine(position, position + Vector3.up, color, duration); } /// /// Draws debug sphere in editor scene view, using radius defined in KCC Settings. /// /// Base position of the sphere. /// Color of the sphere. /// Duration of the drawing. public void DrawSphere(Vector3 position, Color color, float duration = 0.0f) { DrawSphere(position, _settings.Radius, color, duration); } /// /// Draws debug sphere in editor scene view. /// /// Base position of the sphere. /// Radius of the sphere. /// Color of the sphere. /// Duration of the drawing. public void DrawSphere(Vector3 position, float radius, Color color, float duration = 0.0f) { if (radius <= 0.0f) return; DrawWireSphere(position, radius, color, duration); } /// /// Draws debug capsule in editor scene view, using radius and height defined in KCC Settings. /// /// Base position of the capsule. /// Color of the capsule. /// Duration of the drawing. public void DrawCapsule(Vector3 position, Color color, float duration = 0.0f) { DrawCapsule(position, _settings.Radius, _settings.Height, color, duration); } /// /// Draws debug capsule in editor scene view. /// /// Base position of the capsule. /// Radius of the capsule. /// Height of the capsule. /// Color of the capsule. /// Duration of the drawing. public void DrawCapsule(Vector3 position, float radius, float height, Color color, float duration = 0.0f) { if (radius <= 0.0f) return; height = Mathf.Max(radius * 2.0f, height); Vector3 baseLow = position + Vector3.up * radius; Vector3 baseHigh = position + Vector3.up * (height - radius); Vector3 offsetFront = Vector3.forward * radius; Vector3 offsetBack = Vector3.back * radius; Vector3 offsetLeft = Vector3.left * radius; Vector3 offsetRight = Vector3.right * radius; DrawWireHemiSphere(_lowerHemiSpherePoints, baseLow, radius, color, duration); DrawWireHemiSphere(_upperHemiSpherePoints, baseHigh, radius, color, duration); UnityEngine.Debug.DrawLine(baseLow + offsetFront, baseHigh + offsetFront, color, duration); UnityEngine.Debug.DrawLine(baseLow + offsetBack, baseHigh + offsetBack, color, duration); UnityEngine.Debug.DrawLine(baseLow + offsetLeft, baseHigh + offsetLeft, color, duration); UnityEngine.Debug.DrawLine(baseLow + offsetRight, baseHigh + offsetRight, color, duration); } // PRIVATE METHODS [HideInCallstack] [System.Diagnostics.Conditional(TRACING_SCRIPT_DEFINE)] private void Trace(params object[] messages) { KCCUtility.Trace(this, messages); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool CheckSpawned() { if (_isSpawned == false) { LogError($"{nameof(KCC)}.{nameof(Spawned)}() has not been called yet! Use {nameof(KCC)}.{nameof(InvokeOnSpawn)}() to register a callback.", this); return false; } return true; } private static void DrawWireSphere(Vector3 position, float radius, Color color, float duration = 0.0f) { Vector3[] points = _spherePoints; int length = points.Length / 3; for (int i = 0; i < length; i++) { int j = (i + 1) % length; Vector3 startX = position + radius * points[length * 0 + i]; Vector3 endX = position + radius * points[length * 0 + j]; Vector3 startY = position + radius * points[length * 1 + i]; Vector3 endY = position + radius * points[length * 1 + j]; Vector3 startZ = position + radius * points[length * 2 + i]; Vector3 endZ = position + radius * points[length * 2 + j]; UnityEngine.Debug.DrawLine(startX, endX, color, duration); UnityEngine.Debug.DrawLine(startY, endY, color, duration); UnityEngine.Debug.DrawLine(startZ, endZ, color, duration); } } private static void DrawWireHemiSphere(Vector3[] points, Vector3 position, float radius, Color color, float duration = 0.0f) { int length = points.Length / 3; for (int i = 0; i < length - 1; i++) { int j = (i + 1) % length; Vector3 startX = position + radius * points[length * 0 + i]; Vector3 endX = position + radius * points[length * 0 + j]; Vector3 startY = position + radius * points[length * 1 + i]; Vector3 endY = position + radius * points[length * 1 + j]; Vector3 startZ = position + radius * points[length * 2 + i]; Vector3 endZ = position + radius * points[length * 2 + j]; UnityEngine.Debug.DrawLine(startX, endX, color, duration); UnityEngine.Debug.DrawLine(startY, endY, color, duration); UnityEngine.Debug.DrawLine(startZ, endZ, color, duration); } } private static Vector3[] MakeUnitSphere(int length) { Vector3[] points = new Vector3[length * 3]; for (int i = 0; i < length; i++) { float f = i / (float)length; float c = Mathf.Cos(f * (float)(System.Math.PI * 2.0f)); float s = Mathf.Sin(f * (float)(System.Math.PI * 2.0f)); points[length * 0 + i] = new Vector3(c, s, 0); points[length * 1 + i] = new Vector3(0, c, s); points[length * 2 + i] = new Vector3(s, 0, c); } return points; } private static Vector3[] MakeLowerUnitHemiSphere(int length) { int count = length + 1; Vector3[] points = new Vector3[count * 3]; for (int i = 0; i < count; i++) { float f = i / (float)length; float c1 = Mathf.Cos(Mathf.PI * f * 2.0f); float s1 = Mathf.Sin(Mathf.PI * f * 2.0f); float c2 = Mathf.Cos(Mathf.PI * (f + 0.5f)); float s2 = Mathf.Sin(Mathf.PI * (f + 0.5f)); float c3 = Mathf.Cos(Mathf.PI * (f + 1.0f)); float s3 = Mathf.Sin(Mathf.PI * (f + 1.0f)); points[count * 0 + i] = new Vector3(c3, s3, 0); points[count * 1 + i] = new Vector3(0, c2, s2); points[count * 2 + i] = new Vector3(s1, 0, c1); } return points; } private static Vector3[] MakeUpperUnitHemiSphere(int length) { int count = length + 1; Vector3[] points = new Vector3[count * 3]; for (int i = 0; i < count; i++) { float f = i / (float)length; float c1 = Mathf.Cos(Mathf.PI * f * 2.0f); float s1 = Mathf.Sin(Mathf.PI * f * 2.0f); float c2 = Mathf.Cos(Mathf.PI * (f - 0.5f)); float s2 = Mathf.Sin(Mathf.PI * (f - 0.5f)); float c3 = Mathf.Cos(Mathf.PI * f); float s3 = Mathf.Sin(Mathf.PI * f); points[count * 0 + i] = new Vector3(c3, s3, 0); points[count * 1 + i] = new Vector3(0, c2, s2); points[count * 2 + i] = new Vector3(s1, 0, c1); } return points; } } }