2025-02-22 17:25:54 +08:00
|
|
|
|
//#undef DEBUG
|
|
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
#define DEV_MODE
|
|
|
|
|
#endif
|
|
|
|
|
using System;
|
|
|
|
|
using DCFApixels.DebugXCore;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.Rendering;
|
|
|
|
|
using UnityEngine.LowLevel;
|
|
|
|
|
using UnityEngine.PlayerLoop;
|
|
|
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
|
|
|
using DCFApixels.DebugXCore.Internal;
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
using UnityEditor;
|
2025-02-28 17:06:43 +08:00
|
|
|
|
using System.Linq;
|
2025-02-22 17:25:54 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace DCFApixels
|
|
|
|
|
{
|
2025-02-24 18:18:49 +08:00
|
|
|
|
using static DebugXConsts;
|
2025-02-26 13:49:52 +08:00
|
|
|
|
using IN = System.Runtime.CompilerServices.MethodImplAttribute;
|
2025-02-28 20:06:09 +08:00
|
|
|
|
|
|
|
|
|
public static class DebugXEvents
|
|
|
|
|
{
|
|
|
|
|
public delegate void OnDrawGizmoHandler(Camera camera);
|
|
|
|
|
private static event OnDrawGizmoHandler _onDrawGizmo = delegate { };
|
|
|
|
|
public static event OnDrawGizmoHandler OnDrawGizmo
|
|
|
|
|
{
|
|
|
|
|
add
|
|
|
|
|
{
|
|
|
|
|
_onDrawGizmo -= value;
|
|
|
|
|
_onDrawGizmo += value;
|
|
|
|
|
}
|
|
|
|
|
remove
|
|
|
|
|
{
|
|
|
|
|
_onDrawGizmo -= value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void CleanupEvent(ref OnDrawGizmoHandler eventToClean)
|
|
|
|
|
{
|
|
|
|
|
var invocationList = eventToClean.GetInvocationList();
|
|
|
|
|
|
|
|
|
|
var validDelegates = invocationList
|
|
|
|
|
.Where(d => d.Target as UnityEngine.Object == null || d.Target as UnityEngine.Object != null)
|
|
|
|
|
.Where(d => !(d.Target is UnityEngine.Object targetObj) || targetObj != null)
|
|
|
|
|
.ToArray();
|
|
|
|
|
|
|
|
|
|
if (validDelegates.Length != invocationList.Length)
|
|
|
|
|
{
|
|
|
|
|
eventToClean = null;
|
|
|
|
|
foreach (var delegateItem in validDelegates)
|
|
|
|
|
{
|
2025-03-05 09:44:27 +08:00
|
|
|
|
eventToClean += (OnDrawGizmoHandler)delegateItem;
|
2025-02-28 20:06:09 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static void CleanupOnDrawGizmo()
|
|
|
|
|
{
|
|
|
|
|
CleanupEvent(ref _onDrawGizmo);
|
|
|
|
|
}
|
|
|
|
|
internal static void InvokeOnDrawGizmo(Camera camera)
|
2025-03-05 09:44:27 +08:00
|
|
|
|
{
|
2025-02-28 20:06:09 +08:00
|
|
|
|
_onDrawGizmo(camera);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-22 17:25:54 +08:00
|
|
|
|
public static unsafe partial class DebugX
|
|
|
|
|
{
|
2025-02-28 10:19:44 +08:00
|
|
|
|
private static DebugXPauseState _pauseState = DebugXPauseState.Unpaused;
|
2025-02-22 17:25:54 +08:00
|
|
|
|
private static bool _isCameraContext = false;
|
|
|
|
|
|
|
|
|
|
private static double _lastUnityTime;
|
|
|
|
|
private static float _deltaTime = 0;
|
|
|
|
|
|
|
|
|
|
private static ulong _editorTicks = 0;
|
2025-02-26 23:39:50 +08:00
|
|
|
|
private static ulong _lastEditorToRenderTicks = 1000;
|
2025-02-22 17:25:54 +08:00
|
|
|
|
private static ulong _renderTicks = 100;
|
|
|
|
|
private static ulong _timeTicks = 0;
|
|
|
|
|
|
2025-02-28 17:06:43 +08:00
|
|
|
|
#if UNITY_EDITOR
|
2025-02-28 20:06:09 +08:00
|
|
|
|
private static readonly Unity.Profiling.ProfilerMarker _onDrawGizmoCalllback = new Unity.Profiling.ProfilerMarker($"{nameof(DebugX)}.{nameof(DebugXEvents.OnDrawGizmo)}");
|
2025-02-28 17:06:43 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2025-02-26 13:49:52 +08:00
|
|
|
|
public static ulong RenderTicks
|
|
|
|
|
{
|
|
|
|
|
get { return _renderTicks; }
|
|
|
|
|
}
|
|
|
|
|
public static ulong TimeTicks
|
|
|
|
|
{
|
|
|
|
|
get { return _timeTicks; }
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-22 17:25:54 +08:00
|
|
|
|
#region Other
|
|
|
|
|
public static void ClearAllGizmos()
|
|
|
|
|
{
|
|
|
|
|
RenderContextController.ClearAllGizmos();
|
|
|
|
|
}
|
|
|
|
|
private static void SetCameraContext()
|
|
|
|
|
{
|
|
|
|
|
_isCameraContext = true;
|
|
|
|
|
}
|
|
|
|
|
private static void SetGameSceneContext()
|
|
|
|
|
{
|
|
|
|
|
_isCameraContext = false;
|
|
|
|
|
}
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
private static void EditorApplication_pauseStateChanged(PauseState obj)
|
|
|
|
|
{
|
2025-02-28 10:19:44 +08:00
|
|
|
|
_pauseState = obj == PauseState.Paused ? DebugXPauseState.Paused : DebugXPauseState.PreUnpaused;
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region ctor
|
|
|
|
|
static DebugX()
|
|
|
|
|
{
|
|
|
|
|
InitGlobals();
|
|
|
|
|
|
|
|
|
|
if (IsSRP)
|
|
|
|
|
{
|
|
|
|
|
RenderPipelineManager.beginCameraRendering -= OnPreRender_SRP;
|
|
|
|
|
RenderPipelineManager.beginCameraRendering += OnPreRender_SRP;
|
|
|
|
|
|
|
|
|
|
RenderPipelineManager.endCameraRendering -= OnPostRender_SRP;
|
|
|
|
|
RenderPipelineManager.endCameraRendering += OnPostRender_SRP;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Camera.onPreRender -= OnPreRender_BRP;
|
|
|
|
|
Camera.onPreRender += OnPreRender_BRP;
|
|
|
|
|
|
|
|
|
|
Camera.onPostRender -= OnPostRender_BRP;
|
|
|
|
|
Camera.onPostRender += OnPostRender_BRP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var curentLoop = PlayerLoop.GetCurrentPlayerLoop();
|
|
|
|
|
var systemsList = curentLoop.subSystemList;
|
|
|
|
|
for (int i = 0; i < systemsList.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
ref var system = ref systemsList[i];
|
|
|
|
|
if (system.type == typeof(EarlyUpdate))
|
|
|
|
|
{
|
|
|
|
|
system.updateDelegate -= PreUpdateCallback;
|
|
|
|
|
system.updateDelegate += PreUpdateCallback;
|
|
|
|
|
}
|
|
|
|
|
if (system.type == typeof(PostLateUpdate))
|
|
|
|
|
{
|
|
|
|
|
system.updateDelegate -= PreRenderCallback;
|
|
|
|
|
system.updateDelegate += PreRenderCallback;
|
|
|
|
|
}
|
2025-02-28 15:11:34 +08:00
|
|
|
|
//if (system.type == typeof(TriggerEndOfFrameCallbacks))
|
|
|
|
|
//{
|
|
|
|
|
// system.updateDelegate -= OnTriggerEndOfFrameCallbacks;
|
|
|
|
|
// system.updateDelegate += OnTriggerEndOfFrameCallbacks;
|
|
|
|
|
//}
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
curentLoop.subSystemList = systemsList;
|
|
|
|
|
PlayerLoop.SetPlayerLoop(curentLoop);
|
|
|
|
|
|
|
|
|
|
//Application.onBeforeRender -= Application_onBeforeRender;
|
|
|
|
|
//Application.onBeforeRender += Application_onBeforeRender;
|
|
|
|
|
|
2025-02-28 17:06:43 +08:00
|
|
|
|
|
2025-02-22 17:25:54 +08:00
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
EditorApplication.pauseStateChanged -= EditorApplication_pauseStateChanged;
|
|
|
|
|
EditorApplication.pauseStateChanged += EditorApplication_pauseStateChanged;
|
|
|
|
|
EditorApplication.update -= EditorApplication_update;
|
|
|
|
|
EditorApplication.update += EditorApplication_update;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Draw/DrawHandler
|
2025-02-23 20:03:13 +08:00
|
|
|
|
private static float GetCurrentDefaultDuration()
|
|
|
|
|
{
|
2025-02-24 10:59:58 +08:00
|
|
|
|
if (GetCurrentContextController().Context.Camera == null)
|
2025-02-23 20:03:13 +08:00
|
|
|
|
{
|
|
|
|
|
return DEFAULT_DURATION;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return IMMEDIATE_DURATION;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-22 17:25:54 +08:00
|
|
|
|
public static DrawHandler Draw()
|
|
|
|
|
{
|
2025-02-23 20:03:13 +08:00
|
|
|
|
return new DrawHandler(GetCurrentDefaultDuration(), DEFAULT_COLOR);
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
public static DrawHandler Draw(float duration)
|
|
|
|
|
{
|
2025-02-23 20:03:13 +08:00
|
|
|
|
return new DrawHandler(duration, DEFAULT_COLOR);
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
public static DrawHandler Draw(Color color)
|
|
|
|
|
{
|
2025-02-23 20:03:13 +08:00
|
|
|
|
return new DrawHandler(GetCurrentDefaultDuration(), color);
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
public static DrawHandler Draw(float duration, Color color)
|
|
|
|
|
{
|
|
|
|
|
return new DrawHandler(duration, color);
|
|
|
|
|
}
|
|
|
|
|
public readonly partial struct DrawHandler
|
|
|
|
|
{
|
|
|
|
|
public readonly Color Color;
|
|
|
|
|
public readonly float Duration;
|
|
|
|
|
//private readonly RenderContextController ContextController;
|
|
|
|
|
//public Camera Camera
|
|
|
|
|
//{
|
|
|
|
|
// get { return ContextController.Context.Camera; }
|
|
|
|
|
//}
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
public DrawHandler(float time, Color color)
|
|
|
|
|
{
|
|
|
|
|
Color = color;
|
|
|
|
|
Duration = time;
|
|
|
|
|
//ContextController = GetCurrenRenderContextController();
|
|
|
|
|
}
|
|
|
|
|
[IN(LINE)] public DrawHandler Setup(float duration, Color color) => new DrawHandler(duration, color);
|
|
|
|
|
[IN(LINE)] public DrawHandler Setup(float duration) => new DrawHandler(duration, Color);
|
|
|
|
|
[IN(LINE)] public DrawHandler Setup(Color color) => new DrawHandler(Duration, color);
|
|
|
|
|
//[IN(LINE)]
|
|
|
|
|
//private DrawHandler(float time, Color color, RenderContextController contextController)
|
|
|
|
|
//{
|
|
|
|
|
// Color = color;
|
|
|
|
|
// Duration = time;
|
|
|
|
|
// ContextController = contextController;
|
|
|
|
|
//}
|
|
|
|
|
//[IN(LINE)] public DrawHandler Setup(float duration, Color color) => new DrawHandler(duration, color, ContextController);
|
|
|
|
|
//[IN(LINE)] public DrawHandler Setup(float duration) => new DrawHandler(duration, Color, ContextController);
|
|
|
|
|
//[IN(LINE)] public DrawHandler Setup(Color color) => new DrawHandler(Duration, color, ContextController);
|
|
|
|
|
//[IN(LINE)] public DrawHandler Setup(Camera camera) => new DrawHandler(Duration, Color, ContextController.Context.Camera != camera ? RenderContextController.GetController(new RenderContext(camera)) : ContextController);
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Gizmo data
|
|
|
|
|
internal struct GizmoInternal<T> where T : IGizmo<T>
|
|
|
|
|
{
|
|
|
|
|
public readonly T Value;
|
|
|
|
|
public readonly Color Color;
|
|
|
|
|
public float Timer;
|
|
|
|
|
//public int IsSwaped;
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
public GizmoInternal(T value, float timer, Color color)
|
|
|
|
|
{
|
|
|
|
|
Value = value;
|
|
|
|
|
Timer = timer;
|
|
|
|
|
Color = color;
|
|
|
|
|
//IsSwaped = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public readonly struct Gizmo<T>
|
|
|
|
|
{
|
|
|
|
|
public readonly T Value;
|
|
|
|
|
public readonly Color Color;
|
|
|
|
|
public readonly float Timer;
|
|
|
|
|
public Gizmo(T value, Color color, float timer)
|
|
|
|
|
{
|
|
|
|
|
Value = value;
|
|
|
|
|
Color = color;
|
|
|
|
|
Timer = timer;
|
|
|
|
|
}
|
|
|
|
|
//public readonly int IsSwaped;
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
|
|
|
|
return $"{Color} {Timer}";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Render Callbacks
|
|
|
|
|
private static void OnPreRender_SRP(ScriptableRenderContext context, Camera camera)
|
|
|
|
|
{
|
|
|
|
|
PreRender_General(camera);
|
|
|
|
|
}
|
|
|
|
|
private static void OnPostRender_SRP(ScriptableRenderContext context, Camera camera)
|
|
|
|
|
{
|
2025-02-26 13:49:52 +08:00
|
|
|
|
PostRender_General(CommandBufferExecutorSRP.GetInstance(context), camera);
|
2025-02-22 17:25:54 +08:00
|
|
|
|
context.Submit();
|
|
|
|
|
}
|
|
|
|
|
private static void OnPreRender_BRP(Camera camera)
|
|
|
|
|
{
|
|
|
|
|
PreRender_General(camera);
|
|
|
|
|
}
|
|
|
|
|
private static void OnPostRender_BRP(Camera camera)
|
|
|
|
|
{
|
2025-02-26 13:49:52 +08:00
|
|
|
|
PostRender_General(CommandBufferExecutorBRP.GetInstance(), camera);
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void PreUpdateCallback()
|
|
|
|
|
{
|
|
|
|
|
_editorTicks++;
|
|
|
|
|
_currentCamera = null;
|
|
|
|
|
|
|
|
|
|
if (_lastUnityTime < Time.unscaledTimeAsDouble)
|
|
|
|
|
{
|
|
|
|
|
_timeTicks++;
|
2025-02-28 10:19:44 +08:00
|
|
|
|
if (_pauseState == DebugXPauseState.Unpaused)
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
|
|
|
|
_deltaTime = Time.unscaledDeltaTime * _timeScaleCache;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const float Min = 1f / 200f;
|
|
|
|
|
const float Max = 1f / 20f;
|
|
|
|
|
if (_deltaTime < Min || _deltaTime > Max)
|
|
|
|
|
{
|
|
|
|
|
_deltaTime = Max;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0, iMax = GizmosBuffer.All.Count; i < iMax; i++)
|
|
|
|
|
{
|
|
|
|
|
GizmosBuffer.All[i].UpdateTimer(_deltaTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_lastUnityTime = Time.unscaledTimeAsDouble;
|
2025-02-28 10:19:44 +08:00
|
|
|
|
if (_pauseState == DebugXPauseState.PreUnpaused)
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
2025-02-28 10:19:44 +08:00
|
|
|
|
_pauseState = DebugXPauseState.Unpaused;
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
SetGameSceneContext();
|
|
|
|
|
}
|
|
|
|
|
private static void PreRenderCallback()
|
2025-02-28 15:04:07 +08:00
|
|
|
|
{
|
2025-02-28 15:06:22 +08:00
|
|
|
|
RenderContextController.ClearCommandBuffers();
|
|
|
|
|
SetCameraContext();
|
|
|
|
|
_currentCamera = null;
|
2025-02-28 15:04:07 +08:00
|
|
|
|
}
|
2025-02-22 17:25:54 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void EditorApplication_update()
|
|
|
|
|
{
|
|
|
|
|
_editorTicks++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void PreRender_General(Camera camera)
|
|
|
|
|
{
|
|
|
|
|
if (camera == null) { return; }
|
|
|
|
|
_currentCamera = camera;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-26 13:49:52 +08:00
|
|
|
|
private static void PostRender_General(ICommandBufferExecutor cbExecutor, Camera camera)
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
2025-02-26 23:39:50 +08:00
|
|
|
|
if (_lastEditorToRenderTicks != _editorTicks)
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
|
|
|
|
_renderTicks++;
|
2025-02-26 23:39:50 +08:00
|
|
|
|
_lastEditorToRenderTicks = _editorTicks;
|
2025-02-28 20:06:09 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DebugXEvents.CleanupOnDrawGizmo();
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-02-24 13:16:30 +08:00
|
|
|
|
if (DebugXUtility.IsGizmosRender())
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
2025-02-28 20:06:09 +08:00
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
using (_onDrawGizmoCalllback.Auto())
|
|
|
|
|
#endif
|
2025-02-28 17:06:43 +08:00
|
|
|
|
{
|
2025-02-28 20:06:09 +08:00
|
|
|
|
DebugXEvents.InvokeOnDrawGizmo(camera);
|
2025-02-28 17:06:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-02-22 17:25:54 +08:00
|
|
|
|
RenderContextController.StaicContextController.Prepare();
|
|
|
|
|
RenderContextController.StaicContextController.Render(cbExecutor);
|
2025-02-28 09:47:18 +08:00
|
|
|
|
cbExecutor.Submit();
|
|
|
|
|
RenderContextController.StaicContextController.PostRender();
|
2025-02-28 15:11:34 +08:00
|
|
|
|
RenderContextController.StaicContextController.RunEnd();
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (camera == null) { return; }
|
|
|
|
|
_currentCamera = camera;
|
|
|
|
|
RenderContextController contextController = RenderContextController.GetController(new RenderContext(camera));
|
|
|
|
|
contextController.Prepare();
|
|
|
|
|
contextController.Render(cbExecutor);
|
2025-02-28 09:47:18 +08:00
|
|
|
|
cbExecutor.Submit();
|
|
|
|
|
contextController.PostRender();
|
2025-02-28 15:11:34 +08:00
|
|
|
|
contextController.RunEnd();
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Gizmo Method
|
|
|
|
|
private static Camera _currentCamera;
|
|
|
|
|
private static Camera GetCurrentCamera()
|
|
|
|
|
{
|
|
|
|
|
return _currentCamera == null ? Camera.current : _currentCamera;
|
|
|
|
|
}
|
2025-02-22 23:02:05 +08:00
|
|
|
|
private static RenderContextController _currenRenderContextControler = RenderContextController.GetController(new RenderContext(null));
|
2025-02-22 17:25:54 +08:00
|
|
|
|
public readonly partial struct DrawHandler
|
|
|
|
|
{
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
public DrawHandler Gizmo<T>(T value) where T : IGizmo<T>
|
|
|
|
|
{
|
2025-02-24 17:59:44 +08:00
|
|
|
|
#if UNITY_EDITOR || !DISABLE_DEBUGX_INBUILD
|
2025-02-22 17:25:54 +08:00
|
|
|
|
GetCurrentContextController().Add(value, Duration, Color);
|
2025-02-24 17:59:44 +08:00
|
|
|
|
#endif
|
2025-02-22 17:25:54 +08:00
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
public DrawHandler Gizmos<T>(ReadOnlySpan<T> values) where T : IGizmo<T>
|
|
|
|
|
{
|
2025-02-24 17:59:44 +08:00
|
|
|
|
#if UNITY_EDITOR || !DISABLE_DEBUGX_INBUILD
|
2025-02-22 17:25:54 +08:00
|
|
|
|
GetCurrentContextController().AddRange(values, Duration, Color);
|
2025-02-24 17:59:44 +08:00
|
|
|
|
#endif
|
2025-02-22 17:25:54 +08:00
|
|
|
|
return this;
|
|
|
|
|
}
|
2025-02-23 20:03:13 +08:00
|
|
|
|
}
|
|
|
|
|
private static RenderContextController GetCurrentContextController()
|
|
|
|
|
{
|
|
|
|
|
//RenderContextController controller;
|
|
|
|
|
//if (ContextController == null)
|
|
|
|
|
//{
|
|
|
|
|
// controller = DrawHandler.GetCurrentContextController();
|
|
|
|
|
//}
|
|
|
|
|
//else
|
|
|
|
|
//{
|
|
|
|
|
// controller = ContextController;
|
|
|
|
|
//}
|
|
|
|
|
//return controller;
|
|
|
|
|
|
2025-02-22 17:25:54 +08:00
|
|
|
|
|
2025-02-23 20:03:13 +08:00
|
|
|
|
if (_isCameraContext)
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
2025-02-23 20:03:13 +08:00
|
|
|
|
if (_currenRenderContextControler.Context.Camera != GetCurrentCamera())
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
2025-02-23 20:03:13 +08:00
|
|
|
|
_currenRenderContextControler = RenderContextController.GetController(new RenderContext(Camera.current));
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-23 20:03:13 +08:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_currenRenderContextControler = RenderContextController.StaicContextController;
|
|
|
|
|
}
|
|
|
|
|
return _currenRenderContextControler;
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
2025-02-26 13:49:52 +08:00
|
|
|
|
#endregion
|
2025-02-22 17:25:54 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region RenderContextControler
|
|
|
|
|
private class RenderContextController
|
|
|
|
|
{
|
|
|
|
|
private static readonly Dictionary<RenderContext, RenderContextController> _allControllers = new Dictionary<RenderContext, RenderContextController>();
|
|
|
|
|
private static readonly RenderContextController _staicContextController;
|
|
|
|
|
private static readonly CommandBuffer _staticContextBuffer;
|
|
|
|
|
static RenderContextController()
|
|
|
|
|
{
|
|
|
|
|
_staticContextBuffer = new CommandBuffer();
|
|
|
|
|
_staticContextBuffer.name = "DebugX_StaticContextRender";
|
|
|
|
|
//_staicContextController = new RenderContextControler(new RenderContext(null), _staticContextBuffer);
|
|
|
|
|
|
|
|
|
|
_staicContextController = GetController(new RenderContext(null));
|
|
|
|
|
}
|
|
|
|
|
public static IEnumerable<RenderContextController> AllConteollers
|
|
|
|
|
{
|
|
|
|
|
get { return _allControllers.Values; }
|
|
|
|
|
}
|
|
|
|
|
public static RenderContextController StaicContextController
|
|
|
|
|
{
|
|
|
|
|
get { return _staicContextController; }
|
|
|
|
|
}
|
|
|
|
|
public static RenderContextController GetController(RenderContext context)
|
|
|
|
|
{
|
|
|
|
|
if (_allControllers.TryGetValue(context, out RenderContextController result) == false)
|
|
|
|
|
{
|
|
|
|
|
CommandBuffer cb;
|
|
|
|
|
if (context.Camera == null)
|
|
|
|
|
{
|
|
|
|
|
cb = _staticContextBuffer;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cb = new CommandBuffer();
|
|
|
|
|
cb.name = "DebugX_CameraContextRender";
|
|
|
|
|
}
|
|
|
|
|
result = new RenderContextController(context, cb);
|
|
|
|
|
//TODO <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
_allControllers.Add(context, result);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
public static void ClearCommandBuffers()
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in _allControllers)
|
|
|
|
|
{
|
|
|
|
|
item.Value.commandBuffer.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public static void UpdateControllersList()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
public static void ClearAllGizmos()
|
|
|
|
|
{
|
|
|
|
|
foreach (var controller in AllConteollers)
|
|
|
|
|
{
|
|
|
|
|
foreach (var buffer in controller._buffers)
|
|
|
|
|
{
|
|
|
|
|
buffer.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public readonly RenderContext Context;
|
|
|
|
|
private readonly CommandBuffer commandBuffer;
|
|
|
|
|
private GizmosBuffer[] _buffersMap = Array.Empty<GizmosBuffer>();
|
|
|
|
|
private readonly List<GizmosBuffer> _buffers = new List<GizmosBuffer>();
|
|
|
|
|
|
|
|
|
|
private readonly Unity.Profiling.ProfilerMarker _cameraMarker;
|
|
|
|
|
|
|
|
|
|
//private long _version;
|
|
|
|
|
//private long _lastVersion;
|
|
|
|
|
//private void IncrementVersion()
|
|
|
|
|
//{
|
|
|
|
|
// System.Threading.Interlocked.Increment(ref _version);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
private RenderContextController(RenderContext context, CommandBuffer cb)
|
|
|
|
|
{
|
|
|
|
|
Context = context;
|
|
|
|
|
commandBuffer = cb;
|
|
|
|
|
|
|
|
|
|
_cameraMarker = new Unity.Profiling.ProfilerMarker($"{Context.Camera}");
|
|
|
|
|
|
|
|
|
|
_buffersMap = new GizmosBuffer[GizmoTypeCode.TypesCount];
|
|
|
|
|
//TODO <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
GizmoTypeCode.OnAddNewID += TypeCode_OnAddNewID;
|
|
|
|
|
}
|
|
|
|
|
private void TypeCode_OnAddNewID(int count)
|
|
|
|
|
{
|
2025-02-24 13:16:30 +08:00
|
|
|
|
Array.Resize(ref _buffersMap, DebugXUtility.NextPow2(count));
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
public void Add<T>(T value, float time, Color color) where T : IGizmo<T>
|
|
|
|
|
{
|
|
|
|
|
GetBuffer<T>().Add(value, time, color);
|
|
|
|
|
}
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
public void AddRange<T>(ReadOnlySpan<T> values, float time, Color color) where T : IGizmo<T>
|
|
|
|
|
{
|
|
|
|
|
GetBuffer<T>().AddRange(values, time, color);
|
|
|
|
|
}
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
private GizmosBuffer<T> GetBuffer<T>() where T : IGizmo<T>
|
|
|
|
|
{
|
|
|
|
|
int id = GizmoTypeCode<T>.ID;
|
|
|
|
|
if (_buffersMap[id] == null)
|
|
|
|
|
{
|
|
|
|
|
var result = new GizmosBuffer<T>(Context, commandBuffer);
|
|
|
|
|
_buffersMap[id] = result;
|
|
|
|
|
_buffers.Add(result);
|
|
|
|
|
_buffers.Sort((a, b) => a.ExecuteOrder - b.ExecuteOrder);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return UnsafeUtility.As<GizmosBuffer, GizmosBuffer<T>>(ref _buffersMap[id]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//[IN(LINE)]
|
|
|
|
|
//public void UpdateTimer(float deltaTime)
|
|
|
|
|
//{
|
|
|
|
|
// int removed = 0;
|
|
|
|
|
// for (int i = 0, iMax = _buffers.Count; i < iMax; i++)
|
|
|
|
|
// {
|
|
|
|
|
// removed |= _buffers[i].UpdateTimer(deltaTime);
|
|
|
|
|
// }
|
|
|
|
|
// //if(removed > 0)
|
|
|
|
|
// //{
|
|
|
|
|
// // IncrementVersion();
|
|
|
|
|
// //}
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
public void Prepare()
|
|
|
|
|
{
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
using (_cameraMarker.Auto())
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0, iMax = _buffers.Count; i < iMax; i++)
|
|
|
|
|
{
|
|
|
|
|
_buffers[i].Prepare();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[IN(LINE)]
|
2025-02-26 13:49:52 +08:00
|
|
|
|
public void Render(ICommandBufferExecutor cbExecutor)
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
using (_cameraMarker.Auto())
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0, iMax = _buffers.Count; i < iMax; i++)
|
|
|
|
|
{
|
|
|
|
|
_buffers[i].Render(cbExecutor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[IN(LINE)]
|
2025-02-28 09:47:18 +08:00
|
|
|
|
public void PostRender()
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
using (_cameraMarker.Auto())
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0, iMax = _buffers.Count; i < iMax; i++)
|
|
|
|
|
{
|
2025-02-28 09:47:18 +08:00
|
|
|
|
_buffers[i].PostRender();
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RunEnd()
|
|
|
|
|
{
|
|
|
|
|
int removed = 0;
|
|
|
|
|
for (int i = 0, iMax = _buffers.Count; i < iMax; i++)
|
|
|
|
|
{
|
|
|
|
|
removed |= _buffers[i].RunEnd();
|
|
|
|
|
}
|
|
|
|
|
//if (removed > 0)
|
|
|
|
|
//{
|
|
|
|
|
// IncrementVersion();
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region GizmosBuffer
|
|
|
|
|
private abstract class GizmosBuffer
|
|
|
|
|
{
|
|
|
|
|
public readonly static List<GizmosBuffer> All = new List<GizmosBuffer>();
|
|
|
|
|
|
|
|
|
|
public abstract int ExecuteOrder { get; }
|
|
|
|
|
public abstract int UpdateTimer(float deltaTime);
|
|
|
|
|
public abstract void Prepare();
|
2025-02-26 13:49:52 +08:00
|
|
|
|
public abstract void Render(ICommandBufferExecutor cbExecutor);
|
2025-02-28 09:47:18 +08:00
|
|
|
|
public abstract void PostRender();
|
2025-02-22 17:25:54 +08:00
|
|
|
|
public abstract int RunEnd();
|
|
|
|
|
public abstract void Clear();
|
|
|
|
|
}
|
|
|
|
|
private class GizmosBuffer<T> : GizmosBuffer where T : IGizmo<T>
|
|
|
|
|
{
|
|
|
|
|
private class DummyRenderer : IGizmoRenderer<T>
|
|
|
|
|
{
|
|
|
|
|
public int ExecuteOrder { get { return 0; } }
|
|
|
|
|
public bool IsStaticRender { get { return true; } }
|
|
|
|
|
public void Prepare(Camera camera, GizmosList<T> list) { }
|
|
|
|
|
public void Render(Camera camera, GizmosList<T> list, CommandBuffer cb) { }
|
|
|
|
|
}
|
2025-02-24 13:16:30 +08:00
|
|
|
|
private static readonly bool _isUnmanaged = UnsafeUtility.IsUnmanaged(typeof(T));
|
2025-02-22 17:25:54 +08:00
|
|
|
|
|
|
|
|
|
private StructList<GizmoInternal<T>> _gizmos = new StructList<GizmoInternal<T>>(32);
|
|
|
|
|
private readonly string _debugName;
|
|
|
|
|
|
|
|
|
|
private readonly RenderContext _context;
|
|
|
|
|
private readonly CommandBuffer _staticCommandBuffer;
|
|
|
|
|
//private readonly CommandBuffer _dynamicCommandBuffer;
|
|
|
|
|
|
|
|
|
|
private readonly IGizmoRenderer<T> _renderer;
|
2025-02-28 09:47:18 +08:00
|
|
|
|
private readonly IGizmoRenderer_PostRender<T> _rendererUnityGizmos;
|
2025-02-22 17:25:54 +08:00
|
|
|
|
private readonly bool _isStatic;
|
|
|
|
|
|
|
|
|
|
#if DEV_MODE
|
2025-02-24 13:16:30 +08:00
|
|
|
|
private static readonly Unity.Profiling.ProfilerMarker _timerMarker = new Unity.Profiling.ProfilerMarker($"{DebugXUtility.GetGenericTypeName(typeof(T), 3, false)}.{nameof(UpdateTimer)}");
|
|
|
|
|
private static readonly Unity.Profiling.ProfilerMarker _prepareMarker = new Unity.Profiling.ProfilerMarker($"{DebugXUtility.GetGenericTypeName(typeof(T), 3, false)}.{nameof(Prepare)}");
|
|
|
|
|
private static readonly Unity.Profiling.ProfilerMarker _renderMarker = new Unity.Profiling.ProfilerMarker($"{DebugXUtility.GetGenericTypeName(typeof(T), 3, false)}.{nameof(Render)}");
|
2025-02-22 17:25:54 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2025-02-24 13:16:30 +08:00
|
|
|
|
public override int ExecuteOrder { get { return _renderer.ExecuteOrder; } }
|
|
|
|
|
|
|
|
|
|
|
2025-02-22 17:25:54 +08:00
|
|
|
|
public GizmosBuffer(RenderContext context, CommandBuffer cb)
|
|
|
|
|
{
|
|
|
|
|
Type type = typeof(T);
|
|
|
|
|
_context = context;
|
|
|
|
|
_staticCommandBuffer = cb;
|
2025-02-24 13:16:30 +08:00
|
|
|
|
_debugName = DebugXUtility.GetGenericTypeName(type, 3, false);
|
2025-02-22 17:25:54 +08:00
|
|
|
|
//_dynamicCommandBuffer = new CommandBuffer();
|
|
|
|
|
//_dynamicCommandBuffer.name = _debugName;
|
|
|
|
|
|
|
|
|
|
_renderer = default(T).RegisterNewRenderer();
|
|
|
|
|
if (_renderer == null)
|
|
|
|
|
{
|
|
|
|
|
_renderer = new DummyRenderer();
|
|
|
|
|
}
|
|
|
|
|
_isStatic = _renderer.IsStaticRender;
|
2025-02-28 09:47:18 +08:00
|
|
|
|
_rendererUnityGizmos = _renderer as IGizmoRenderer_PostRender<T>;
|
2025-02-22 17:25:54 +08:00
|
|
|
|
|
|
|
|
|
All.Add(this);
|
|
|
|
|
All.Sort((a, b) => a.ExecuteOrder - b.ExecuteOrder);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
public void Add(T value, float time, Color color)
|
|
|
|
|
{
|
|
|
|
|
_gizmos.Add(new GizmoInternal<T>(value, time, color));
|
|
|
|
|
}
|
|
|
|
|
[IN(LINE)]
|
|
|
|
|
public void AddRange(ReadOnlySpan<T> values, float time, Color color)
|
|
|
|
|
{
|
|
|
|
|
_gizmos.UpSize(_gizmos._count + values.Length);
|
|
|
|
|
for (int i = 0; i < values.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
_gizmos.Add(new GizmoInternal<T>(values[i], time, color));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public sealed override int UpdateTimer(float deltaTime)
|
|
|
|
|
{
|
|
|
|
|
_staticCommandBuffer.Clear();
|
|
|
|
|
int removeCount = 0;
|
|
|
|
|
#if DEV_MODE
|
|
|
|
|
using (_timerMarker.Auto())
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < _gizmos.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
ref var item = ref _gizmos._items[i];
|
|
|
|
|
if (item.Timer <= 0)
|
|
|
|
|
{
|
|
|
|
|
_gizmos.FastRemoveAt(i);
|
|
|
|
|
i--;
|
|
|
|
|
removeCount++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
item.Timer -= deltaTime;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return removeCount;
|
|
|
|
|
}
|
2025-02-26 23:39:50 +08:00
|
|
|
|
|
2025-02-22 17:25:54 +08:00
|
|
|
|
public sealed override int RunEnd()
|
|
|
|
|
{
|
|
|
|
|
int removeCount = 0;
|
|
|
|
|
#if DEV_MODE
|
|
|
|
|
using (_timerMarker.Auto())
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
int lastCount = _gizmos.Count;
|
|
|
|
|
for (int i = 0; i < _gizmos.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
ref var item = ref _gizmos._items[i];
|
|
|
|
|
if (item.Timer < 0)
|
|
|
|
|
{
|
|
|
|
|
_gizmos.FastRemoveAt(i);
|
|
|
|
|
i--;
|
|
|
|
|
removeCount++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> managed <20><><EFBFBD><EFBFBD>
|
|
|
|
|
if (_isUnmanaged == false)
|
|
|
|
|
{
|
|
|
|
|
for (int i = _gizmos.Count; i < lastCount; i++)
|
|
|
|
|
{
|
|
|
|
|
_gizmos._items[i] = default;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return removeCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ulong _prepareLastRenderTicks = 0;
|
|
|
|
|
public override void Prepare()
|
|
|
|
|
{
|
|
|
|
|
if (_gizmos.Count <= 0) { return; }
|
|
|
|
|
#if DEV_MODE
|
|
|
|
|
using (_prepareMarker.Auto())
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
if (_isStatic == false || _prepareLastRenderTicks != _renderTicks)
|
|
|
|
|
{
|
|
|
|
|
_prepareLastRenderTicks = _renderTicks;
|
|
|
|
|
GizmosList<T> list = GizmosList.From(_gizmos._items, _gizmos._count);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_renderer.Prepare(GetCurrentCamera(), list);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e) { throw new Exception($"[{_debugName}] [Prepare] ", e); }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private ulong _renderLastRenderTicks = 0;
|
2025-02-26 13:49:52 +08:00
|
|
|
|
public override void Render(ICommandBufferExecutor cbExecutor)
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
|
|
|
|
if (_gizmos.Count <= 0) { return; }
|
|
|
|
|
#if DEV_MODE
|
|
|
|
|
using (_renderMarker.Auto())
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
//if (_isStatic == false || _renderLastRenderTicks != _renderTicks)
|
|
|
|
|
{
|
|
|
|
|
_renderLastRenderTicks = _renderTicks;
|
|
|
|
|
GizmosList<T> list = GizmosList.From(_gizmos._items, _gizmos._count);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_staticCommandBuffer.Clear();
|
|
|
|
|
_renderer.Render(GetCurrentCamera(), list, _staticCommandBuffer);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e) { throw new Exception($"[{_debugName}] [Render] ", e); }
|
|
|
|
|
}
|
|
|
|
|
cbExecutor.Execute(_staticCommandBuffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-28 09:47:18 +08:00
|
|
|
|
public override void PostRender()
|
2025-02-22 17:25:54 +08:00
|
|
|
|
{
|
|
|
|
|
if (_rendererUnityGizmos == null) { return; }
|
2025-02-27 16:46:55 +08:00
|
|
|
|
//Debug.Log(_gizmos._count);
|
2025-02-22 17:25:54 +08:00
|
|
|
|
if (_gizmos.Count <= 0) { return; }
|
|
|
|
|
#if DEV_MODE
|
|
|
|
|
using (_renderMarker.Auto())
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
GizmosList<T> list = GizmosList.From(_gizmos._items, _gizmos._count);
|
|
|
|
|
try
|
|
|
|
|
{
|
2025-02-28 09:47:18 +08:00
|
|
|
|
_rendererUnityGizmos.PostRender(GetCurrentCamera(), list);
|
2025-02-22 17:25:54 +08:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e) { throw new Exception($"[{_debugName}] [Render] ", e); }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Clear()
|
|
|
|
|
{
|
|
|
|
|
if (_isUnmanaged)
|
|
|
|
|
{
|
|
|
|
|
_gizmos.FastClear();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_gizmos.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|