Enum parse support, start work on CSConsole, cleanup

This commit is contained in:
Sinai
2021-05-09 20:18:33 +10:00
parent 7b700cbe55
commit e6b253fed9
30 changed files with 1616 additions and 213 deletions

View File

@ -1,124 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI.CacheObject;
using UnityExplorer.UI.ObjectPool;
using UnityExplorer.UI.Panels;
namespace UnityExplorer.UI.Inspectors
{
public static class InspectorManager
{
public static readonly List<InspectorBase> Inspectors = new List<InspectorBase>();
public static InspectorBase ActiveInspector { get; private set; }
public static float PanelWidth;
public static void Inspect(object obj, CacheObjectBase sourceCache = null)
{
if (obj.IsNullOrDestroyed())
return;
obj = obj.TryCast();
if (TryFocusActiveInspector(obj))
return;
// var type = obj.GetActualType();
//if (type.IsEnumerable())
// CreateInspector<ListInspector>(obj, false, sourceCache);
//// todo dict
if (obj is GameObject)
CreateInspector<GameObjectInspector>(obj);
else
CreateInspector<ReflectionInspector>(obj, false, sourceCache);
}
private static bool TryFocusActiveInspector(object target)
{
foreach (var inspector in Inspectors)
{
if (inspector.Target.ReferenceEqual(target))
{
UIManager.SetPanelActive(UIManager.Panels.Inspector, true);
SetInspectorActive(inspector);
return true;
}
}
return false;
}
public static void Inspect(Type type)
{
CreateInspector<ReflectionInspector>(type, true);
}
public static void SetInspectorActive(InspectorBase inspector)
{
UnsetActiveInspector();
ActiveInspector = inspector;
inspector.OnSetActive();
}
public static void UnsetActiveInspector()
{
if (ActiveInspector != null)
ActiveInspector.OnSetInactive();
}
private static void CreateInspector<T>(object target, bool staticReflection = false, CacheObjectBase sourceCache = null) where T : InspectorBase
{
var inspector = Pool<T>.Borrow();
Inspectors.Add(inspector);
inspector.Target = target;
if (sourceCache != null && sourceCache.CanWrite)
{
// only set parent cache object if we are inspecting a struct, otherwise there is no point.
if (target.GetType().IsValueType && inspector is ReflectionInspector ri)
ri.ParentCacheObject = sourceCache;
}
UIManager.SetPanelActive(UIManager.Panels.Inspector, true);
inspector.UIRoot.transform.SetParent(InspectorPanel.Instance.ContentHolder.transform, false);
if (inspector is ReflectionInspector reflectInspector)
reflectInspector.StaticOnly = staticReflection;
inspector.OnBorrowedFromPool(target);
SetInspectorActive(inspector);
}
internal static void ReleaseInspector<T>(T inspector) where T : InspectorBase
{
inspector.OnReturnToPool();
Pool<T>.Return(inspector);
Inspectors.Remove(inspector);
}
internal static void Update()
{
for (int i = Inspectors.Count - 1; i >= 0; i--)
Inspectors[i].Update();
}
internal static void OnPanelResized(float width)
{
PanelWidth = width;
foreach (var obj in Inspectors)
{
if (obj is ReflectionInspector inspector)
{
inspector.SetLayouts();
}
}
}
}
}

View File

@ -21,22 +21,27 @@ namespace UnityExplorer.UI.Inspectors
public class ReflectionInspector : InspectorBase, IPoolDataSource<CacheMemberCell>, ICacheObjectController
{
public CacheObjectBase ParentCacheObject { get; set; }
public Type TargetType { get; private set; }
public bool CanWrite => true;
// Instance state
public bool StaticOnly { get; internal set; }
public BindingFlags FlagsFilter { get; private set; }
public string NameFilter { get; private set; }
public bool AutoUpdateWanted { get; set; }
public bool CanWrite => true;
private List<CacheMember> members = new List<CacheMember>();
private readonly List<CacheMember> filteredMembers = new List<CacheMember>();
public bool AutoUpdateWanted { get; set; }
private BindingFlags FlagsFilter;
private string NameFilter;
private MemberFlags MemberFilter = MemberFlags.All;
private enum MemberFlags
{
None = 0,
Property = 1,
Field = 2,
Method = 4,
All = 7
}
// UI
@ -44,27 +49,15 @@ namespace UnityExplorer.UI.Inspectors
public Text NameText;
public Text AssemblyText;
// Unity object helpers
private UnityEngine.Object ObjectRef;
private Component ComponentRef;
private Texture2D TextureRef;
private bool TextureViewerWanted;
private GameObject unityObjectRow;
private ButtonRef gameObjectButton;
private InputFieldRef nameInput;
private InputFieldRef instanceIdInput;
private ButtonRef textureButton;
private GameObject textureViewer;
private Toggle autoUpdateToggle;
private readonly Color disabledButtonColor = new Color(0.24f, 0.24f, 0.24f);
private readonly Color enabledButtonColor = new Color(0.2f, 0.27f, 0.2f);
private readonly Dictionary<BindingFlags, ButtonRef> scopeFilterButtons = new Dictionary<BindingFlags, ButtonRef>();
private readonly List<Toggle> memberTypeToggles = new List<Toggle>();
private InputFieldRef filterInputField;
//private LayoutElement memberTitleLayout;
private Toggle autoUpdateToggle;
// Setup / return
public override void OnBorrowedFromPool(object target)
{
@ -144,7 +137,14 @@ namespace UnityExplorer.UI.Inspectors
// Get cache members, and set filter to default
this.members = CacheMember.GetCacheMembers(Target, TargetType, this);
this.filterInputField.Text = "";
SetFilter("", StaticOnly ? BindingFlags.Static : BindingFlags.Instance);
scopeFilterButtons[BindingFlags.Default].Button.gameObject.SetActive(!StaticOnly);
scopeFilterButtons[BindingFlags.Instance].Button.gameObject.SetActive(!StaticOnly);
foreach (var toggle in memberTypeToggles)
toggle.isOn = true;
refreshWanted = true;
}
@ -153,6 +153,7 @@ namespace UnityExplorer.UI.Inspectors
private bool refreshWanted;
private string lastNameFilter;
private BindingFlags lastFlagsFilter;
private MemberFlags lastMemberFilter = MemberFlags.All;
private float timeOfLastAutoUpdate;
public override void Update()
@ -166,10 +167,11 @@ namespace UnityExplorer.UI.Inspectors
return;
}
if (refreshWanted || NameFilter != lastNameFilter || FlagsFilter != lastFlagsFilter)
if (refreshWanted || NameFilter != lastNameFilter || FlagsFilter != lastFlagsFilter || lastMemberFilter != MemberFilter)
{
lastNameFilter = NameFilter;
lastFlagsFilter = FlagsFilter;
lastMemberFilter = MemberFilter;
FilterMembers();
MemberScrollPool.Refresh(true, true);
@ -206,6 +208,14 @@ namespace UnityExplorer.UI.Inspectors
}
}
private void OnMemberTypeToggled(MemberFlags flag, bool val)
{
if (!val)
MemberFilter &= ~flag;
else
MemberFilter |= flag;
}
private void FilterMembers()
{
filteredMembers.Clear();
@ -214,9 +224,6 @@ namespace UnityExplorer.UI.Inspectors
{
var member = members[i];
if (!string.IsNullOrEmpty(NameFilter) && !member.NameForFiltering.ContainsIgnoreCase(NameFilter))
continue;
if (FlagsFilter != BindingFlags.Default)
{
if (FlagsFilter == BindingFlags.Instance && member.IsStatic
@ -224,6 +231,14 @@ namespace UnityExplorer.UI.Inspectors
continue;
}
if ((member is CacheMethod && !MemberFilter.HasFlag(MemberFlags.Method))
|| (member is CacheField && !MemberFilter.HasFlag(MemberFlags.Field))
|| (member is CacheProperty && !MemberFilter.HasFlag(MemberFlags.Property)))
continue;
if (!string.IsNullOrEmpty(NameFilter) && !member.NameForFiltering.ContainsIgnoreCase(NameFilter))
continue;
filteredMembers.Add(member);
}
}
@ -313,9 +328,9 @@ namespace UnityExplorer.UI.Inspectors
new Color(0.12f, 0.12f, 0.12f));
UIFactory.SetLayoutElement(mainContentHolder, flexibleWidth: 9999, flexibleHeight: 9999);
ConstructFilterRow(mainContentHolder);
ConstructFirstRow(mainContentHolder);
ConstructUpdateRow(mainContentHolder);
ConstructSecondRow(mainContentHolder);
// Member scroll pool
@ -335,67 +350,115 @@ namespace UnityExplorer.UI.Inspectors
return UIRoot;
}
// Filter row
// First row
private void ConstructFilterRow(GameObject parent)
private void ConstructFirstRow(GameObject parent)
{
var filterRow = UIFactory.CreateUIObject("FilterRow", parent);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(filterRow, true, true, true, true, 5, 2, 2, 2, 2);
UIFactory.SetLayoutElement(filterRow, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
var rowObj = UIFactory.CreateUIObject("FirstRow", parent);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rowObj, true, true, true, true, 5, 2, 2, 2, 2);
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
var nameLabel = UIFactory.CreateLabel(filterRow, "NameFilterLabel", "Filter names:", TextAnchor.MiddleLeft, Color.grey);
var nameLabel = UIFactory.CreateLabel(rowObj, "NameFilterLabel", "Filter names:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(nameLabel.gameObject, minHeight: 25, minWidth: 90, flexibleWidth: 0);
filterInputField = UIFactory.CreateInputField(filterRow, "NameFilterInput", "...");
filterInputField = UIFactory.CreateInputField(rowObj, "NameFilterInput", "...");
UIFactory.SetLayoutElement(filterInputField.UIRoot, minHeight: 25, flexibleWidth: 300);
filterInputField.OnValueChanged += (string val) => { SetFilter(val); };
var spacer = UIFactory.CreateUIObject("Spacer", filterRow);
var spacer = UIFactory.CreateUIObject("Spacer", rowObj);
UIFactory.SetLayoutElement(spacer, minWidth: 25);
var scopeLabel = UIFactory.CreateLabel(filterRow, "ScopeLabel", "Scope:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(scopeLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0);
AddFilterButton(filterRow, BindingFlags.Default, true);
AddFilterButton(filterRow, BindingFlags.Instance);
AddFilterButton(filterRow, BindingFlags.Static);
// Update button and toggle
var updateButton = UIFactory.CreateButton(rowObj, "UpdateButton", "Update displayed values", new Color(0.22f, 0.28f, 0.22f));
UIFactory.SetLayoutElement(updateButton.Button.gameObject, minHeight: 25, minWidth: 175, flexibleWidth: 0);
updateButton.OnClick += UpdateDisplayedMembers;
var toggleObj = UIFactory.CreateToggle(rowObj, "AutoUpdateToggle", out autoUpdateToggle, out Text toggleText);
//GameObject.DestroyImmediate(toggleText);
UIFactory.SetLayoutElement(toggleObj, minWidth: 125, minHeight: 25);
autoUpdateToggle.isOn = false;
autoUpdateToggle.onValueChanged.AddListener((bool val) => { AutoUpdateWanted = val; });
toggleText.text = "Auto-update";
}
private void AddFilterButton(GameObject parent, BindingFlags flags, bool setAsActive = false)
// Second row
private void ConstructSecondRow(GameObject parent)
{
var rowObj = UIFactory.CreateUIObject("SecondRow", parent);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rowObj, false, false, true, true, 5, 2, 2, 2, 2);
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
// Scope buttons
var scopeLabel = UIFactory.CreateLabel(rowObj, "ScopeLabel", "Scope:", TextAnchor.MiddleLeft, Color.grey);
UIFactory.SetLayoutElement(scopeLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0);
AddScopeFilterButton(rowObj, BindingFlags.Default, true);
AddScopeFilterButton(rowObj, BindingFlags.Instance);
AddScopeFilterButton(rowObj, BindingFlags.Static);
var spacer = UIFactory.CreateUIObject("Spacer", rowObj);
UIFactory.SetLayoutElement(spacer, minWidth: 15);
// Member type toggles
//var typeLabel = UIFactory.CreateLabel(rowObj, "MemberTypeLabel", "Show:", TextAnchor.MiddleLeft, Color.grey);
//UIFactory.SetLayoutElement(typeLabel.gameObject, minHeight: 25, minWidth: 40);
AddMemberTypeToggle(rowObj, MemberTypes.Property, 90);
AddMemberTypeToggle(rowObj, MemberTypes.Field, 70);
AddMemberTypeToggle(rowObj, MemberTypes.Method, 90);
}
private void AddScopeFilterButton(GameObject parent, BindingFlags flags, bool setAsActive = false)
{
string lbl = flags == BindingFlags.Default ? "All" : flags.ToString();
var color = setAsActive ? enabledButtonColor : disabledButtonColor;
var button = UIFactory.CreateButton(parent, "Filter_" + flags, lbl, color);
UIFactory.SetLayoutElement(button.Button.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 100, flexibleWidth: 0);
UIFactory.SetLayoutElement(button.Button.gameObject, minHeight: 25, flexibleHeight: 0, minWidth: 70, flexibleWidth: 0);
scopeFilterButtons.Add(flags, button);
button.OnClick += () => { SetFilter(flags); };
}
// Update row
private void ConstructUpdateRow(GameObject parent)
private void AddMemberTypeToggle(GameObject parent, MemberTypes type, int width)
{
var updateRow = UIFactory.CreateUIObject("UpdateRow", parent);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(updateRow, false, false, true, true, 4);
UIFactory.SetLayoutElement(updateRow, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
var toggleObj = UIFactory.CreateToggle(parent, "Toggle_" + type, out Toggle toggle, out Text toggleText);
UIFactory.SetLayoutElement(toggleObj, minHeight: 25, minWidth: width);
toggleText.text = $"<color={SignatureHighlighter.GetMemberInfoColor(type)}>{type}</color>";
var updateButton = UIFactory.CreateButton(updateRow, "UpdateButton", "Update displayed values", new Color(0.22f, 0.28f, 0.22f));
UIFactory.SetLayoutElement(updateButton.Button.gameObject, minHeight: 25, minWidth: 175, flexibleWidth: 0);
updateButton.OnClick += UpdateDisplayedMembers;
toggle.graphic.TryCast<Image>().color = new Color(0.25f, 0.25f, 0.25f);
var toggleObj = UIFactory.CreateToggle(updateRow, "AutoUpdateToggle", out autoUpdateToggle, out Text toggleText);
//GameObject.DestroyImmediate(toggleText);
UIFactory.SetLayoutElement(toggleObj, minWidth: 185, minHeight: 25);
autoUpdateToggle.isOn = false;
autoUpdateToggle.onValueChanged.AddListener((bool val) => { AutoUpdateWanted = val; });
toggleText.text = "Auto-update displayed";
MemberFlags flag;
switch (type)
{
case MemberTypes.Method: flag = MemberFlags.Method; break;
case MemberTypes.Property: flag = MemberFlags.Property; break;
case MemberTypes.Field: flag = MemberFlags.Field; break;
default: return;
}
toggle.onValueChanged.AddListener((bool val) => { OnMemberTypeToggled(flag, val); });
memberTypeToggles.Add(toggle);
}
#region UNITY OBJECT SPECIFIC
// Unity object helpers
private UnityEngine.Object ObjectRef;
private Component ComponentRef;
private Texture2D TextureRef;
private bool TextureViewerWanted;
private GameObject unityObjectRow;
private ButtonRef gameObjectButton;
private InputFieldRef nameInput;
private InputFieldRef instanceIdInput;
private ButtonRef textureButton;
private GameObject textureViewer;
private void SetUnityTargets()
{
if (!typeof(UnityEngine.Object).IsAssignableFrom(TargetType))

View File

@ -0,0 +1,327 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using UnityEngine;
//using UnityEngine.EventSystems;
//using UnityEngine.UI;
//using UnityExplorer.Core;
//using UnityExplorer.Core.Input;
//using UnityExplorer.Core.Runtime;
//using UnityExplorer.UI;
//using UnityExplorer.UI.Main;
//using UnityExplorer.Inspectors;
//namespace UnityExplorer.UI.Main.Home
//{
// public class InspectUnderMouse
// {
// public enum MouseInspectMode
// {
// World,
// UI
// }
// public static bool Inspecting { get; set; }
// public static MouseInspectMode Mode { get; set; }
// private static GameObject s_lastHit;
// private static Vector3 s_lastMousePos;
// private static readonly List<Graphic> _wasDisabledGraphics = new List<Graphic>();
// private static readonly List<CanvasGroup> _wasDisabledCanvasGroups = new List<CanvasGroup>();
// private static readonly List<GameObject> _objectsAddedCastersTo = new List<GameObject>();
// internal static Camera MainCamera;
// internal static GraphicRaycaster[] graphicRaycasters;
// public static void Init()
// {
// ConstructUI();
// }
// public static void StartInspect(MouseInspectMode mode)
// {
// MainCamera = Camera.main;
// if (!MainCamera)
// return;
// Mode = mode;
// Inspecting = true;
// MainMenu.Instance.MainPanel.SetActive(false);
// s_UIContent.SetActive(true);
// if (mode == MouseInspectMode.UI)
// SetupUIRaycast();
// }
// internal static void ClearHitData()
// {
// s_lastHit = null;
// s_objNameLabel.text = "No hits...";
// s_objPathLabel.text = "";
// }
// public static void StopInspect()
// {
// Inspecting = false;
// MainMenu.Instance.MainPanel.SetActive(true);
// s_UIContent.SetActive(false);
// if (Mode == MouseInspectMode.UI)
// StopUIInspect();
// ClearHitData();
// }
// public static void UpdateInspect()
// {
// if (InputManager.GetKeyDown(KeyCode.Escape))
// {
// StopInspect();
// return;
// }
// var mousePos = InputManager.MousePosition;
// if (mousePos != s_lastMousePos)
// UpdatePosition(mousePos);
// // actual inspect raycast
// switch (Mode)
// {
// case MouseInspectMode.UI:
// RaycastUI(mousePos); break;
// case MouseInspectMode.World:
// RaycastWorld(mousePos); break;
// }
// }
// internal static void UpdatePosition(Vector2 mousePos)
// {
// s_lastMousePos = mousePos;
// var inversePos = UIManager.CanvasRoot.transform.InverseTransformPoint(mousePos);
// s_mousePosLabel.text = $"<color=grey>Mouse Position:</color> {mousePos.ToString()}";
// float yFix = mousePos.y < 120 ? 80 : -80;
// s_UIContent.transform.localPosition = new Vector3(inversePos.x, inversePos.y + yFix, 0);
// }
// internal static void OnHitGameObject(GameObject obj)
// {
// if (obj != s_lastHit)
// {
// s_lastHit = obj;
// s_objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>";
// s_objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}";
// }
// if (InputManager.GetMouseButtonDown(0))
// {
// StopInspect();
// InspectorManager.Instance.Inspect(obj);
// }
// }
// // Collider raycasting
// internal static void RaycastWorld(Vector2 mousePos)
// {
// var ray = MainCamera.ScreenPointToRay(mousePos);
// Physics.Raycast(ray, out RaycastHit hit, 1000f);
// if (hit.transform)
// {
// var obj = hit.transform.gameObject;
// OnHitGameObject(obj);
// }
// else
// {
// if (s_lastHit)
// ClearHitData();
// }
// }
// // UI Graphic raycasting
// private static void SetupUIRaycast()
// {
// foreach (var obj in RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(Canvas)))
// {
// var canvas = obj.Cast(typeof(Canvas)) as Canvas;
// if (!canvas || !canvas.enabled || !canvas.gameObject.activeInHierarchy)
// continue;
// if (!canvas.GetComponent<GraphicRaycaster>())
// {
// canvas.gameObject.AddComponent<GraphicRaycaster>();
// //ExplorerCore.Log("Added raycaster to " + canvas.name);
// _objectsAddedCastersTo.Add(canvas.gameObject);
// }
// }
// // recache Graphic Raycasters each time we start
// var casters = RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(GraphicRaycaster));
// graphicRaycasters = new GraphicRaycaster[casters.Length];
// for (int i = 0; i < casters.Length; i++)
// {
// graphicRaycasters[i] = casters[i].Cast(typeof(GraphicRaycaster)) as GraphicRaycaster;
// }
// // enable raycastTarget on Graphics
// foreach (var obj in RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(Graphic)))
// {
// var graphic = obj.Cast(typeof(Graphic)) as Graphic;
// if (!graphic || !graphic.enabled || graphic.raycastTarget || !graphic.gameObject.activeInHierarchy)
// continue;
// graphic.raycastTarget = true;
// //ExplorerCore.Log("Enabled raycastTarget on " + graphic.name);
// _wasDisabledGraphics.Add(graphic);
// }
// // enable blocksRaycasts on CanvasGroups
// foreach (var obj in RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(CanvasGroup)))
// {
// var canvas = obj.Cast(typeof(CanvasGroup)) as CanvasGroup;
// if (!canvas || !canvas.gameObject.activeInHierarchy || canvas.blocksRaycasts)
// continue;
// canvas.blocksRaycasts = true;
// //ExplorerCore.Log("Enabled raycasts on " + canvas.name);
// _wasDisabledCanvasGroups.Add(canvas);
// }
// }
// internal static void RaycastUI(Vector2 mousePos)
// {
// var ped = new PointerEventData(null)
// {
// position = mousePos
// };
// //ExplorerCore.Log("~~~~~~~~~ begin raycast ~~~~~~~~");
// GameObject hitObject = null;
// int highestLayer = int.MinValue;
// int highestOrder = int.MinValue;
// int highestDepth = int.MinValue;
// foreach (var gr in graphicRaycasters)
// {
// var list = new List<RaycastResult>();
// RuntimeProvider.Instance.GraphicRaycast(gr, ped, list);
// //gr.Raycast(ped, list);
// if (list.Count > 0)
// {
// foreach (var hit in list)
// {
// // Manual trying to determine which object is "on top".
// // Not perfect, but not terrible.
// if (!hit.gameObject)
// continue;
// if (hit.gameObject.GetComponent<CanvasGroup>() is CanvasGroup group && group.alpha == 0)
// continue;
// if (hit.gameObject.GetComponent<Graphic>() is Graphic graphic && graphic.color.a == 0f)
// continue;
// if (hit.sortingLayer < highestLayer)
// continue;
// if (hit.sortingLayer > highestLayer)
// {
// highestLayer = hit.sortingLayer;
// highestDepth = int.MinValue;
// }
// if (hit.depth < highestDepth)
// continue;
// if (hit.depth > highestDepth)
// {
// highestDepth = hit.depth;
// highestOrder = int.MinValue;
// }
// if (hit.sortingOrder <= highestOrder)
// continue;
// highestOrder = hit.sortingOrder;
// hitObject = hit.gameObject;
// }
// }
// else
// {
// if (s_lastHit)
// ClearHitData();
// }
// }
// if (hitObject)
// OnHitGameObject(hitObject);
// //ExplorerCore.Log("~~~~~~~~~ end raycast ~~~~~~~~");
// }
// private static void StopUIInspect()
// {
// foreach (var obj in _objectsAddedCastersTo)
// {
// if (obj.GetComponent<GraphicRaycaster>() is GraphicRaycaster raycaster)
// GameObject.Destroy(raycaster);
// }
// foreach (var graphic in _wasDisabledGraphics)
// graphic.raycastTarget = false;
// foreach (var canvas in _wasDisabledCanvasGroups)
// canvas.blocksRaycasts = false;
// _objectsAddedCastersTo.Clear();
// _wasDisabledCanvasGroups.Clear();
// _wasDisabledGraphics.Clear();
// }
// internal static Text s_objNameLabel;
// internal static Text s_objPathLabel;
// internal static Text s_mousePosLabel;
// internal static GameObject s_UIContent;
// internal static void ConstructUI()
// {
// s_UIContent = UIFactory.CreatePanel("InspectUnderMouse_UI", out GameObject content);
// var baseRect = s_UIContent.GetComponent<RectTransform>();
// var half = new Vector2(0.5f, 0.5f);
// baseRect.anchorMin = half;
// baseRect.anchorMax = half;
// baseRect.pivot = half;
// baseRect.sizeDelta = new Vector2(700, 150);
// var group = content.GetComponent<VerticalLayoutGroup>();
// group.childForceExpandHeight = true;
// // Title text
// UIFactory.CreateLabel(content, "InspectLabel", "<b>Mouse Inspector</b> (press <b>ESC</b> to cancel)", TextAnchor.MiddleCenter);
// s_mousePosLabel = UIFactory.CreateLabel(content, "MousePosLabel", "Mouse Position:", TextAnchor.MiddleCenter);
// s_objNameLabel = UIFactory.CreateLabel(content, "HitLabelObj", "No hits...", TextAnchor.MiddleLeft);
// s_objNameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
// s_objPathLabel = UIFactory.CreateLabel(content, "PathLabel", "", TextAnchor.MiddleLeft);
// s_objPathLabel.fontStyle = FontStyle.Italic;
// s_objPathLabel.horizontalOverflow = HorizontalWrapMode.Wrap;
// UIFactory.SetLayoutElement(s_objPathLabel.gameObject, minHeight: 75);
// s_UIContent.SetActive(false);
// }
// }
//}