Files
GameDevTVObstacleDodge/Library/PackageCache/com.unity.cinemachine@5342685532bb/Runtime/Debug/CinemachineDebug.cs

153 lines
6.5 KiB
C#

using UnityEngine;
using System.Collections.Generic;
using System.Text;
using System;
#if UNITY_EDITOR && CINEMACHINE_UIELEMENTS
using UnityEditor;
using UnityEngine.UIElements;
#endif
namespace Unity.Cinemachine
{
/// <summary>Manages onscreen positions for Cinemachine debugging output</summary>
static class CinemachineDebug
{
static List<StringBuilder> s_AvailableStringBuilders;
#if UNITY_EDITOR && CINEMACHINE_UIELEMENTS
const string k_DebugUIName = "Cinemachine__internal__DebugUI";
static Dictionary<Camera, VisualElement> s_CameraViewRectContainers = new();
static GameObject s_UIDocumentHolder;
static UIDocument s_UIDocument;
public static VisualElement GetOrCreateUIContainer(Camera outputCamera)
{
var uiDocumentHolder = GetUIDocumentHolder();
if (!uiDocumentHolder.TryGetComponent(out s_UIDocument))
{
s_UIDocument = uiDocumentHolder.AddComponent<UIDocument>();
const string path = CinemachineCore.kPackageRoot + "/Runtime/Debug/";
s_UIDocument.panelSettings = AssetDatabase.LoadAssetAtPath<PanelSettings>(path + "CinemachinePanelSettings.asset");
}
if (s_CameraViewRectContainers.ContainsKey(outputCamera))
{
if (s_CameraViewRectContainers[outputCamera].childCount != 0)
return s_CameraViewRectContainers[outputCamera];
s_CameraViewRectContainers[outputCamera].RemoveFromHierarchy();
s_CameraViewRectContainers.Remove(outputCamera);
}
var viewportContainer = new VisualElement
{
name = "CinemachineDebugUI_ViewportContainer",
pickingMode = PickingMode.Ignore,
style =
{
position = new StyleEnum<Position>(Position.Absolute),
flexWrap = new StyleEnum<Wrap>(Wrap.Wrap),
}
};
SetRoot(viewportContainer);
viewportContainer.schedule.Execute(() => PositionWithinCameraView(viewportContainer, outputCamera)).Every(0);
s_CameraViewRectContainers.Add(outputCamera, viewportContainer);
return viewportContainer;
// local functions
static GameObject GetUIDocumentHolder()
{
if (s_UIDocumentHolder == null)
{
// if the holder exists in the scene without any view containers, then it is better to delete it,
// and create a new one, because UITK may have failed to create a rootVisualElement.
s_UIDocumentHolder = GameObject.Find(k_DebugUIName);
if (s_UIDocumentHolder != null && s_CameraViewRectContainers.Count == 0)
{
RuntimeUtility.DestroyObject(s_UIDocumentHolder);
s_UIDocumentHolder = null;
}
if (s_UIDocumentHolder == null)
{
s_UIDocumentHolder = new GameObject(k_DebugUIName)
{
hideFlags = HideFlags.HideAndDontSave
};
}
}
return s_UIDocumentHolder;
}
static void SetRoot(VisualElement viewportContainer)
{
// Need to wait until rootVisualElement is created.
if (s_UIDocument.rootVisualElement == null)
{
EditorApplication.delayCall += () => SetRoot(viewportContainer);
return;
}
s_UIDocument.rootVisualElement.Add(viewportContainer);
}
static void PositionWithinCameraView(VisualElement viewportContainer, Camera camera)
{
if (viewportContainer.childCount == 0 || camera == null)
{
viewportContainer.RemoveFromHierarchy();
s_CameraViewRectContainers.Remove(camera);
}
if (s_UIDocument == null || s_UIDocument.rootVisualElement == null || camera == null)
return;
var panel = s_UIDocument.rootVisualElement.panel;
var screenPanelSpace = RuntimePanelUtils.ScreenToPanel(panel, new Vector2(Screen.width, Screen.height));
var viewport = camera.pixelRect;
var viewPortMaxPanelSpace = RuntimePanelUtils.ScreenToPanel(panel, viewport.max);
var viewPortMinPanelSpace = RuntimePanelUtils.ScreenToPanel(panel, viewport.min);
viewportContainer.style.top = new Length(screenPanelSpace.y - viewPortMaxPanelSpace.y, LengthUnit.Pixel);
viewportContainer.style.bottom = new Length(viewPortMinPanelSpace.y, LengthUnit.Pixel);
viewportContainer.style.left = new Length(viewPortMinPanelSpace.x, LengthUnit.Pixel);
viewportContainer.style.right = new Length(screenPanelSpace.x - viewPortMaxPanelSpace.x, LengthUnit.Pixel);
}
}
#endif
/// <summary>
/// Delegate for OnGUI debugging.
/// This will be called by the CinemachineDebugBrain in its OnGUI (editor only)
/// </summary>
public static Action<CinemachineBrain> OnGUIHandlers;
/// <summary>
/// Tracks CinemachineCorePrefs.ShowInGameGuides.Value, so it can be accessed at runtime
/// </summary>
public static bool GameViewGuidesEnabled;
/// <summary>Get a pre-allocated StringBuilder from the pool</summary>
/// <returns>The pre-allocated StringBuilder from the pool.
/// Client must call ReturnToPool when done</returns>
public static StringBuilder SBFromPool()
{
if (s_AvailableStringBuilders == null || s_AvailableStringBuilders.Count == 0)
return new StringBuilder();
var sb = s_AvailableStringBuilders[^1];
s_AvailableStringBuilders.RemoveAt(s_AvailableStringBuilders.Count - 1);
sb.Length = 0;
return sb;
}
/// <summary>Return a StringBuilder to the pre-allocated pool</summary>
/// <param name="sb">The string builder object to return to the pool</param>
public static void ReturnToPool(StringBuilder sb)
{
s_AvailableStringBuilders ??= new List<StringBuilder>();
s_AvailableStringBuilders.Add(sb);
}
}
}