mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-16 14:17:51 +08:00
Update to UniverseLib 1.3.4
This commit is contained in:
parent
a5e6b65dee
commit
a5023d03f4
@ -74,7 +74,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
InspectorManager.ReleaseInspector(this);
|
InspectorManager.ReleaseInspector(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeTarget(GameObject newTarget)
|
public void OnTransformCellClicked(GameObject newTarget)
|
||||||
{
|
{
|
||||||
this.Target = newTarget;
|
this.Target = newTarget;
|
||||||
GOControls.UpdateGameObjectInfo(true, true);
|
GOControls.UpdateGameObjectInfo(true, true);
|
||||||
@ -293,12 +293,8 @@ namespace UnityExplorer.Inspectors
|
|||||||
|
|
||||||
transformScroll = UIFactory.CreateScrollPool<TransformCell>(leftGroup, "TransformTree", out GameObject transformObj,
|
transformScroll = UIFactory.CreateScrollPool<TransformCell>(leftGroup, "TransformTree", out GameObject transformObj,
|
||||||
out GameObject transformContent, new Color(0.11f, 0.11f, 0.11f));
|
out GameObject transformContent, new Color(0.11f, 0.11f, 0.11f));
|
||||||
UIFactory.SetLayoutElement(transformObj, flexibleHeight: 9999);
|
|
||||||
UIFactory.SetLayoutElement(transformContent, flexibleHeight: 9999);
|
|
||||||
|
|
||||||
TransformTree = new TransformTree(transformScroll, GetTransformEntries);
|
TransformTree = new TransformTree(transformScroll, GetTransformEntries, OnTransformCellClicked);
|
||||||
TransformTree.Init();
|
|
||||||
TransformTree.OnClickOverrideHandler = ChangeTarget;
|
|
||||||
|
|
||||||
// Right group (Components)
|
// Right group (Components)
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ namespace UnityExplorer.Inspectors
|
|||||||
{
|
{
|
||||||
if (this.GOTarget && this.GOTarget.transform.parent)
|
if (this.GOTarget && this.GOTarget.transform.parent)
|
||||||
{
|
{
|
||||||
Parent.ChangeTarget(this.GOTarget.transform.parent.gameObject);
|
Parent.OnTransformCellClicked(this.GOTarget.transform.parent.gameObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ using UniverseLib;
|
|||||||
using UniverseLib.UI;
|
using UniverseLib.UI;
|
||||||
using UniverseLib.UI.Models;
|
using UniverseLib.UI.Models;
|
||||||
using UniverseLib.Utility;
|
using UniverseLib.Utility;
|
||||||
|
using UniverseLib.UI.Widgets;
|
||||||
|
|
||||||
namespace UnityExplorer.ObjectExplorer
|
namespace UnityExplorer.ObjectExplorer
|
||||||
{
|
{
|
||||||
@ -156,7 +157,7 @@ namespace UnityExplorer.ObjectExplorer
|
|||||||
{
|
{
|
||||||
if ((!string.IsNullOrEmpty(input) && !Tree.Filtering) || (string.IsNullOrEmpty(input) && Tree.Filtering))
|
if ((!string.IsNullOrEmpty(input) && !Tree.Filtering) || (string.IsNullOrEmpty(input) && Tree.Filtering))
|
||||||
{
|
{
|
||||||
Tree.cachedTransforms.Clear();
|
Tree.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree.CurrentFilter = input;
|
Tree.CurrentFilter = input;
|
||||||
@ -259,8 +260,7 @@ namespace UnityExplorer.ObjectExplorer
|
|||||||
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
|
||||||
UIFactory.SetLayoutElement(scrollContent, flexibleHeight: 9999);
|
UIFactory.SetLayoutElement(scrollContent, flexibleHeight: 9999);
|
||||||
|
|
||||||
Tree = new TransformTree(scrollPool, GetRootEntries);
|
Tree = new TransformTree(scrollPool, GetRootEntries, OnCellClicked);
|
||||||
Tree.Init();
|
|
||||||
Tree.RefreshData(true, true, true, false);
|
Tree.RefreshData(true, true, true, false);
|
||||||
//scrollPool.Viewport.GetComponent<Mask>().enabled = false;
|
//scrollPool.Viewport.GetComponent<Mask>().enabled = false;
|
||||||
//UIRoot.GetComponent<Mask>().enabled = false;
|
//UIRoot.GetComponent<Mask>().enabled = false;
|
||||||
@ -272,6 +272,8 @@ namespace UnityExplorer.ObjectExplorer
|
|||||||
RuntimeHelper.StartCoroutine(TempFixCoro());
|
RuntimeHelper.StartCoroutine(TempFixCoro());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnCellClicked(GameObject obj) => InspectorManager.Inspect(obj);
|
||||||
|
|
||||||
// To "fix" a strange FPS drop issue with MelonLoader.
|
// To "fix" a strange FPS drop issue with MelonLoader.
|
||||||
private IEnumerator TempFixCoro()
|
private IEnumerator TempFixCoro()
|
||||||
{
|
{
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Widgets
|
|
||||||
{
|
|
||||||
public class CachedTransform
|
|
||||||
{
|
|
||||||
public TransformTree Tree { get; }
|
|
||||||
public Transform Value { get; private set; }
|
|
||||||
public int InstanceID { get; }
|
|
||||||
public CachedTransform Parent { get; internal set; }
|
|
||||||
|
|
||||||
public int Depth { get; internal set; }
|
|
||||||
public int ChildCount { get; internal set; }
|
|
||||||
public string Name { get; internal set; }
|
|
||||||
public bool Enabled { get; internal set; }
|
|
||||||
public int SiblingIndex { get; internal set; }
|
|
||||||
|
|
||||||
public bool Expanded => Tree.IsTransformExpanded(InstanceID);
|
|
||||||
|
|
||||||
public CachedTransform(TransformTree tree, Transform transform, int depth, CachedTransform parent = null)
|
|
||||||
{
|
|
||||||
InstanceID = transform.GetInstanceID();
|
|
||||||
|
|
||||||
Tree = tree;
|
|
||||||
Value = transform;
|
|
||||||
Parent = parent;
|
|
||||||
SiblingIndex = transform.GetSiblingIndex();
|
|
||||||
Update(transform, depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Update(Transform transform, int depth)
|
|
||||||
{
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
if (Value != transform
|
|
||||||
|| depth != Depth
|
|
||||||
|| ChildCount != transform.childCount
|
|
||||||
|| Name != transform.name
|
|
||||||
|| Enabled != transform.gameObject.activeSelf
|
|
||||||
|| SiblingIndex != transform.GetSiblingIndex())
|
|
||||||
{
|
|
||||||
changed = true;
|
|
||||||
|
|
||||||
Value = transform;
|
|
||||||
Depth = depth;
|
|
||||||
ChildCount = transform.childCount;
|
|
||||||
Name = transform.name;
|
|
||||||
Enabled = transform.gameObject.activeSelf;
|
|
||||||
SiblingIndex = transform.GetSiblingIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,201 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using UniverseLib;
|
|
||||||
using UniverseLib.UI;
|
|
||||||
using UniverseLib.UI.Models;
|
|
||||||
using UniverseLib.UI.Widgets.ScrollView;
|
|
||||||
using UniverseLib.Utility;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Widgets
|
|
||||||
{
|
|
||||||
public class TransformCell : ICell
|
|
||||||
{
|
|
||||||
public float DefaultHeight => 25f;
|
|
||||||
|
|
||||||
public bool Enabled => enabled;
|
|
||||||
private bool enabled;
|
|
||||||
|
|
||||||
public Action<CachedTransform> OnExpandToggled;
|
|
||||||
public Action<CachedTransform> OnEnableToggled;
|
|
||||||
public Action<GameObject> OnGameObjectClicked;
|
|
||||||
|
|
||||||
public CachedTransform cachedTransform;
|
|
||||||
|
|
||||||
public GameObject UIRoot { get; set; }
|
|
||||||
public RectTransform Rect { get; set; }
|
|
||||||
|
|
||||||
public ButtonRef ExpandButton;
|
|
||||||
public ButtonRef NameButton;
|
|
||||||
public Toggle EnabledToggle;
|
|
||||||
public InputFieldRef SiblingIndex;
|
|
||||||
|
|
||||||
public LayoutElement spacer;
|
|
||||||
|
|
||||||
public void Enable()
|
|
||||||
{
|
|
||||||
enabled = true;
|
|
||||||
UIRoot.SetActive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Disable()
|
|
||||||
{
|
|
||||||
enabled = false;
|
|
||||||
UIRoot.SetActive(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ConfigureCell(CachedTransform cached)
|
|
||||||
{
|
|
||||||
if (cached == null)
|
|
||||||
{
|
|
||||||
ExplorerCore.LogWarning("Setting TransformTree cell but the CachedTransform is null!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Enabled)
|
|
||||||
Enable();
|
|
||||||
|
|
||||||
cachedTransform = cached;
|
|
||||||
|
|
||||||
spacer.minWidth = cached.Depth * 15;
|
|
||||||
|
|
||||||
if (cached.Value)
|
|
||||||
{
|
|
||||||
string name = cached.Value.name?.Trim();
|
|
||||||
if (string.IsNullOrEmpty(name))
|
|
||||||
name = "<i><color=grey>untitled</color></i>";
|
|
||||||
NameButton.ButtonText.text = name;
|
|
||||||
NameButton.ButtonText.color = cached.Value.gameObject.activeSelf ? Color.white : Color.grey;
|
|
||||||
|
|
||||||
EnabledToggle.Set(cached.Value.gameObject.activeSelf, false);
|
|
||||||
|
|
||||||
if (!cached.Value.parent)
|
|
||||||
SiblingIndex.GameObject.SetActive(false);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SiblingIndex.GameObject.SetActive(true);
|
|
||||||
if (!SiblingIndex.Component.isFocused)
|
|
||||||
SiblingIndex.Text = cached.Value.GetSiblingIndex().ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
int childCount = cached.Value.childCount;
|
|
||||||
if (childCount > 0)
|
|
||||||
{
|
|
||||||
NameButton.ButtonText.text = $"<color=grey>[{childCount}]</color> {NameButton.ButtonText.text}";
|
|
||||||
|
|
||||||
ExpandButton.Component.interactable = true;
|
|
||||||
ExpandButton.ButtonText.text = cached.Expanded ? "▼" : "►";
|
|
||||||
ExpandButton.ButtonText.color = cached.Expanded ? new Color(0.5f, 0.5f, 0.5f) : new Color(0.3f, 0.3f, 0.3f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ExpandButton.Component.interactable = false;
|
|
||||||
ExpandButton.ButtonText.text = "▪";
|
|
||||||
ExpandButton.ButtonText.color = new Color(0.3f, 0.3f, 0.3f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NameButton.ButtonText.text = $"[Destroyed]";
|
|
||||||
NameButton.ButtonText.color = Color.red;
|
|
||||||
|
|
||||||
SiblingIndex.GameObject.SetActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMainButtonClicked()
|
|
||||||
{
|
|
||||||
if (cachedTransform.Value)
|
|
||||||
OnGameObjectClicked?.Invoke(cachedTransform.Value.gameObject);
|
|
||||||
else
|
|
||||||
ExplorerCore.LogWarning("The object was destroyed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnExpandClicked()
|
|
||||||
{
|
|
||||||
OnExpandToggled?.Invoke(cachedTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEnableClicked(bool value)
|
|
||||||
{
|
|
||||||
OnEnableToggled?.Invoke(cachedTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnSiblingIndexEndEdit(string input)
|
|
||||||
{
|
|
||||||
if (this.cachedTransform == null || !this.cachedTransform.Value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (int.TryParse(input.Trim(), out int index))
|
|
||||||
this.cachedTransform.Value.SetSiblingIndex(index);
|
|
||||||
|
|
||||||
this.SiblingIndex.Text = this.cachedTransform.Value.GetSiblingIndex().ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameObject CreateContent(GameObject parent)
|
|
||||||
{
|
|
||||||
UIRoot = UIFactory.CreateUIObject("TransformCell", parent);
|
|
||||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(UIRoot, false, false, true, true, 2, childAlignment: TextAnchor.MiddleCenter);
|
|
||||||
Rect = UIRoot.GetComponent<RectTransform>();
|
|
||||||
Rect.anchorMin = new Vector2(0, 1);
|
|
||||||
Rect.anchorMax = new Vector2(0, 1);
|
|
||||||
Rect.pivot = new Vector2(0.5f, 1);
|
|
||||||
Rect.sizeDelta = new Vector2(25, 25);
|
|
||||||
UIFactory.SetLayoutElement(UIRoot, minWidth: 100, flexibleWidth: 9999, minHeight: 25, flexibleHeight: 0);
|
|
||||||
|
|
||||||
GameObject spacerObj = UIFactory.CreateUIObject("Spacer", UIRoot, new Vector2(0, 0));
|
|
||||||
UIFactory.SetLayoutElement(spacerObj, minWidth: 0, flexibleWidth: 0, minHeight: 0, flexibleHeight: 0);
|
|
||||||
this.spacer = spacerObj.GetComponent<LayoutElement>();
|
|
||||||
|
|
||||||
// Expand arrow
|
|
||||||
|
|
||||||
ExpandButton = UIFactory.CreateButton(this.UIRoot, "ExpandButton", "►");
|
|
||||||
UIFactory.SetLayoutElement(ExpandButton.Component.gameObject, minWidth: 15, flexibleWidth: 0, minHeight: 25, flexibleHeight: 0);
|
|
||||||
|
|
||||||
// Enabled toggle
|
|
||||||
|
|
||||||
GameObject toggleObj = UIFactory.CreateToggle(UIRoot, "BehaviourToggle", out EnabledToggle, out Text behavText, default, 17, 17);
|
|
||||||
UIFactory.SetLayoutElement(toggleObj, minHeight: 17, flexibleHeight: 0, minWidth: 17);
|
|
||||||
EnabledToggle.onValueChanged.AddListener(OnEnableClicked);
|
|
||||||
|
|
||||||
// Name button
|
|
||||||
|
|
||||||
GameObject nameBtnHolder = UIFactory.CreateHorizontalGroup(this.UIRoot, "NameButtonHolder",
|
|
||||||
false, false, true, true, childAlignment: TextAnchor.MiddleLeft);
|
|
||||||
UIFactory.SetLayoutElement(nameBtnHolder, flexibleWidth: 9999, minHeight: 25, flexibleHeight: 0);
|
|
||||||
nameBtnHolder.AddComponent<Mask>().showMaskGraphic = false;
|
|
||||||
|
|
||||||
NameButton = UIFactory.CreateButton(nameBtnHolder, "NameButton", "Name", null);
|
|
||||||
UIFactory.SetLayoutElement(NameButton.Component.gameObject, flexibleWidth: 9999, minHeight: 25, flexibleHeight: 0);
|
|
||||||
Text nameLabel = NameButton.Component.GetComponentInChildren<Text>();
|
|
||||||
nameLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
|
|
||||||
nameLabel.alignment = TextAnchor.MiddleLeft;
|
|
||||||
|
|
||||||
// Sibling index input
|
|
||||||
|
|
||||||
SiblingIndex = UIFactory.CreateInputField(this.UIRoot, "SiblingIndexInput", string.Empty);
|
|
||||||
SiblingIndex.Component.textComponent.fontSize = 11;
|
|
||||||
SiblingIndex.Component.textComponent.alignment = TextAnchor.MiddleRight;
|
|
||||||
Image siblingImage = SiblingIndex.GameObject.GetComponent<Image>();
|
|
||||||
siblingImage.color = new(0f, 0f, 0f, 0.25f);
|
|
||||||
UIFactory.SetLayoutElement(SiblingIndex.GameObject, 35, 20, 0, 0);
|
|
||||||
SiblingIndex.Component.GetOnEndEdit().AddListener(OnSiblingIndexEndEdit);
|
|
||||||
|
|
||||||
// Setup selectables
|
|
||||||
|
|
||||||
Color normal = new(0.11f, 0.11f, 0.11f);
|
|
||||||
Color highlight = new(0.25f, 0.25f, 0.25f);
|
|
||||||
Color pressed = new(0.05f, 0.05f, 0.05f);
|
|
||||||
Color disabled = new(1, 1, 1, 0);
|
|
||||||
RuntimeHelper.SetColorBlock(ExpandButton.Component, normal, highlight, pressed, disabled);
|
|
||||||
RuntimeHelper.SetColorBlock(NameButton.Component, normal, highlight, pressed, disabled);
|
|
||||||
|
|
||||||
NameButton.OnClick += OnMainButtonClicked;
|
|
||||||
ExpandButton.OnClick += OnExpandClicked;
|
|
||||||
|
|
||||||
UIRoot.SetActive(false);
|
|
||||||
|
|
||||||
return this.UIRoot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,369 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using UnityEngine;
|
|
||||||
using UniverseLib;
|
|
||||||
using UniverseLib.UI.Widgets.ScrollView;
|
|
||||||
using UniverseLib.Utility;
|
|
||||||
|
|
||||||
namespace UnityExplorer.UI.Widgets
|
|
||||||
{
|
|
||||||
public class TransformTree : ICellPoolDataSource<TransformCell>
|
|
||||||
{
|
|
||||||
public Func<IEnumerable<GameObject>> GetRootEntriesMethod;
|
|
||||||
public Action<GameObject> OnClickOverrideHandler;
|
|
||||||
|
|
||||||
public ScrollPool<TransformCell> ScrollPool;
|
|
||||||
|
|
||||||
// IMPORTANT CAVEAT WITH OrderedDictionary:
|
|
||||||
// While the performance is mostly good, there are two methods we should NEVER use:
|
|
||||||
// - Remove(object)
|
|
||||||
// - set_Item[object]
|
|
||||||
// These two methods have extremely bad performance due to using IndexOfKey(), which iterates the whole dictionary.
|
|
||||||
// Currently we do not use either of these methods, so everything should be constant time lookups.
|
|
||||||
// We DO make use of get_Item[object], get_Item[index], Add, Insert, Contains and RemoveAt, which OrderedDictionary meets our needs for.
|
|
||||||
/// <summary>
|
|
||||||
/// Key: UnityEngine.Transform instance ID<br/>
|
|
||||||
/// Value: CachedTransform
|
|
||||||
/// </summary>
|
|
||||||
internal readonly OrderedDictionary cachedTransforms = new();
|
|
||||||
|
|
||||||
// for keeping track of which actual transforms are expanded or not, outside of the cache data.
|
|
||||||
private readonly HashSet<int> expandedInstanceIDs = new();
|
|
||||||
private readonly HashSet<int> autoExpandedIDs = new();
|
|
||||||
|
|
||||||
// state for Traverse parse
|
|
||||||
private readonly HashSet<int> visited = new();
|
|
||||||
private bool needRefreshUI;
|
|
||||||
private int displayIndex;
|
|
||||||
int prevDisplayIndex;
|
|
||||||
|
|
||||||
private Coroutine refreshCoroutine;
|
|
||||||
private readonly Stopwatch traversedThisFrame = new();
|
|
||||||
|
|
||||||
// ScrollPool item count. PrevDisplayIndex is the highest index + 1 from our last traverse.
|
|
||||||
public int ItemCount => prevDisplayIndex;
|
|
||||||
|
|
||||||
// Search filter
|
|
||||||
public bool Filtering => !string.IsNullOrEmpty(currentFilter);
|
|
||||||
private bool wasFiltering;
|
|
||||||
|
|
||||||
public string CurrentFilter
|
|
||||||
{
|
|
||||||
get => currentFilter;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
currentFilter = value ?? "";
|
|
||||||
if (!wasFiltering && Filtering)
|
|
||||||
wasFiltering = true;
|
|
||||||
else if (wasFiltering && !Filtering)
|
|
||||||
{
|
|
||||||
wasFiltering = false;
|
|
||||||
autoExpandedIDs.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private string currentFilter;
|
|
||||||
|
|
||||||
public TransformTree(ScrollPool<TransformCell> scrollPool, Func<IEnumerable<GameObject>> getRootEntriesMethod)
|
|
||||||
{
|
|
||||||
ScrollPool = scrollPool;
|
|
||||||
GetRootEntriesMethod = getRootEntriesMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize and reset
|
|
||||||
|
|
||||||
// Must be called externally from owner of this TransformTree
|
|
||||||
public void Init()
|
|
||||||
{
|
|
||||||
ScrollPool.Initialize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called to completely reset the tree, ie. switching inspected GameObject
|
|
||||||
public void Rebuild()
|
|
||||||
{
|
|
||||||
autoExpandedIDs.Clear();
|
|
||||||
expandedInstanceIDs.Clear();
|
|
||||||
|
|
||||||
RefreshData(true, true, true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called to completely wipe our data (ie, GameObject inspector returning to pool)
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
this.cachedTransforms.Clear();
|
|
||||||
displayIndex = 0;
|
|
||||||
autoExpandedIDs.Clear();
|
|
||||||
expandedInstanceIDs.Clear();
|
|
||||||
this.ScrollPool.Refresh(true, true);
|
|
||||||
if (refreshCoroutine != null)
|
|
||||||
{
|
|
||||||
RuntimeHelper.StopCoroutine(refreshCoroutine);
|
|
||||||
refreshCoroutine = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks if the given Instance ID is expanded or not
|
|
||||||
public bool IsTransformExpanded(int instanceID)
|
|
||||||
{
|
|
||||||
return Filtering ? autoExpandedIDs.Contains(instanceID)
|
|
||||||
: expandedInstanceIDs.Contains(instanceID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Jumps to a specific Transform in the tree and highlights it.
|
|
||||||
public void JumpAndExpandToTransform(Transform transform)
|
|
||||||
{
|
|
||||||
// make sure all parents of the object are expanded
|
|
||||||
Transform parent = transform.parent;
|
|
||||||
while (parent)
|
|
||||||
{
|
|
||||||
int pid = parent.GetInstanceID();
|
|
||||||
if (!expandedInstanceIDs.Contains(pid))
|
|
||||||
expandedInstanceIDs.Add(pid);
|
|
||||||
|
|
||||||
parent = parent.parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh cached transforms (no UI rebuild yet).
|
|
||||||
// Stop existing coroutine and do it oneshot.
|
|
||||||
RefreshData(false, false, true, true);
|
|
||||||
|
|
||||||
int transformID = transform.GetInstanceID();
|
|
||||||
|
|
||||||
// find the index of our transform in the list and jump to it
|
|
||||||
int idx;
|
|
||||||
for (idx = 0; idx < cachedTransforms.Count; idx++)
|
|
||||||
{
|
|
||||||
CachedTransform cache = (CachedTransform)cachedTransforms[idx];
|
|
||||||
if (cache.InstanceID == transformID)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollPool.JumpToIndex(idx, OnCellJumpedTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnCellJumpedTo(TransformCell cell)
|
|
||||||
{
|
|
||||||
RuntimeHelper.StartCoroutine(HighlightCellCoroutine(cell));
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator HighlightCellCoroutine(TransformCell cell)
|
|
||||||
{
|
|
||||||
UnityEngine.UI.Button button = cell.NameButton.Component;
|
|
||||||
button.StartColorTween(new Color(0.2f, 0.3f, 0.2f), false);
|
|
||||||
|
|
||||||
float start = Time.realtimeSinceStartup;
|
|
||||||
while (Time.realtimeSinceStartup - start < 1.5f)
|
|
||||||
yield return null;
|
|
||||||
|
|
||||||
button.OnDeselect(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform a Traverse and optionally refresh the ScrollPool as well.
|
|
||||||
// If oneShot, then this happens instantly with no yield.
|
|
||||||
public void RefreshData(bool andRefreshUI, bool jumpToTop, bool stopExistingCoroutine, bool oneShot)
|
|
||||||
{
|
|
||||||
if (refreshCoroutine != null)
|
|
||||||
{
|
|
||||||
if (stopExistingCoroutine)
|
|
||||||
{
|
|
||||||
RuntimeHelper.StopCoroutine(refreshCoroutine);
|
|
||||||
refreshCoroutine = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
visited.Clear();
|
|
||||||
displayIndex = 0;
|
|
||||||
needRefreshUI = false;
|
|
||||||
traversedThisFrame.Reset();
|
|
||||||
traversedThisFrame.Start();
|
|
||||||
|
|
||||||
refreshCoroutine = RuntimeHelper.StartCoroutine(RefreshCoroutine(andRefreshUI, jumpToTop, oneShot));
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator RefreshCoroutine(bool andRefreshUI, bool jumpToTop, bool oneShot)
|
|
||||||
{
|
|
||||||
// Instead of doing string.IsNullOrEmpty(CurrentFilter) many times, let's just do it once per update.
|
|
||||||
bool filtering = Filtering;
|
|
||||||
|
|
||||||
IEnumerable<GameObject> rootObjects = GetRootEntriesMethod();
|
|
||||||
foreach (GameObject gameObj in rootObjects)
|
|
||||||
{
|
|
||||||
if (!gameObj)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
IEnumerator enumerator = Traverse(gameObj.transform, null, 0, oneShot, filtering);
|
|
||||||
while (enumerator.MoveNext())
|
|
||||||
{
|
|
||||||
if (!oneShot)
|
|
||||||
yield return enumerator.Current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prune displayed transforms that we didnt visit in that traverse
|
|
||||||
for (int i = cachedTransforms.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (traversedThisFrame.ElapsedMilliseconds > 2)
|
|
||||||
{
|
|
||||||
yield return null;
|
|
||||||
traversedThisFrame.Reset();
|
|
||||||
traversedThisFrame.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
CachedTransform cached = (CachedTransform)cachedTransforms[i];
|
|
||||||
if (!visited.Contains(cached.InstanceID))
|
|
||||||
{
|
|
||||||
cachedTransforms.RemoveAt(i);
|
|
||||||
needRefreshUI = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (andRefreshUI && needRefreshUI)
|
|
||||||
ScrollPool.Refresh(true, jumpToTop);
|
|
||||||
|
|
||||||
prevDisplayIndex = displayIndex;
|
|
||||||
refreshCoroutine = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recursive method to check a Transform and its children (if expanded).
|
|
||||||
// Parent and depth can be null/default.
|
|
||||||
private IEnumerator Traverse(Transform transform, CachedTransform parent, int depth, bool oneShot, bool filtering)
|
|
||||||
{
|
|
||||||
if (traversedThisFrame.ElapsedMilliseconds > 2)
|
|
||||||
{
|
|
||||||
yield return null;
|
|
||||||
traversedThisFrame.Reset();
|
|
||||||
traversedThisFrame.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
int instanceID = transform.GetInstanceID();
|
|
||||||
|
|
||||||
// Unlikely, but since this method is async it could theoretically happen in extremely rare circumstances
|
|
||||||
if (visited.Contains(instanceID))
|
|
||||||
yield break;
|
|
||||||
|
|
||||||
if (filtering)
|
|
||||||
{
|
|
||||||
if (!FilterHierarchy(transform))
|
|
||||||
yield break;
|
|
||||||
|
|
||||||
if (!autoExpandedIDs.Contains(instanceID))
|
|
||||||
autoExpandedIDs.Add(instanceID);
|
|
||||||
}
|
|
||||||
|
|
||||||
visited.Add(instanceID);
|
|
||||||
|
|
||||||
CachedTransform cached;
|
|
||||||
if (cachedTransforms.Contains(instanceID))
|
|
||||||
{
|
|
||||||
cached = (CachedTransform)cachedTransforms[(object)instanceID];
|
|
||||||
int prevSiblingIdx = cached.SiblingIndex;
|
|
||||||
if (cached.Update(transform, depth))
|
|
||||||
{
|
|
||||||
needRefreshUI = true;
|
|
||||||
|
|
||||||
// If the sibling index changed, we need to shuffle it in our cached transforms list.
|
|
||||||
if (prevSiblingIdx != cached.SiblingIndex)
|
|
||||||
{
|
|
||||||
cachedTransforms.Remove(instanceID);
|
|
||||||
if (cachedTransforms.Count <= displayIndex)
|
|
||||||
cachedTransforms.Add(instanceID, cached);
|
|
||||||
else
|
|
||||||
cachedTransforms.Insert(displayIndex, instanceID, cached);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
needRefreshUI = true;
|
|
||||||
cached = new CachedTransform(this, transform, depth, parent);
|
|
||||||
if (cachedTransforms.Count <= displayIndex)
|
|
||||||
cachedTransforms.Add(instanceID, cached);
|
|
||||||
else
|
|
||||||
cachedTransforms.Insert(displayIndex, instanceID, cached);
|
|
||||||
}
|
|
||||||
|
|
||||||
displayIndex++;
|
|
||||||
|
|
||||||
if (IsTransformExpanded(instanceID) && cached.Value.childCount > 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < transform.childCount; i++)
|
|
||||||
{
|
|
||||||
IEnumerator enumerator = Traverse(transform.GetChild(i), cached, depth + 1, oneShot, filtering);
|
|
||||||
while (enumerator.MoveNext())
|
|
||||||
{
|
|
||||||
if (!oneShot)
|
|
||||||
yield return enumerator.Current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool FilterHierarchy(Transform obj)
|
|
||||||
{
|
|
||||||
if (obj.name.ContainsIgnoreCase(currentFilter))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (obj.childCount <= 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int i = 0; i < obj.childCount; i++)
|
|
||||||
if (FilterHierarchy(obj.GetChild(i)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetCell(TransformCell cell, int index)
|
|
||||||
{
|
|
||||||
if (index < cachedTransforms.Count)
|
|
||||||
{
|
|
||||||
cell.ConfigureCell((CachedTransform)cachedTransforms[index]);
|
|
||||||
if (Filtering)
|
|
||||||
{
|
|
||||||
if (cell.cachedTransform.Name.ContainsIgnoreCase(currentFilter))
|
|
||||||
cell.NameButton.ButtonText.color = Color.green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cell.Disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCellBorrowed(TransformCell cell)
|
|
||||||
{
|
|
||||||
cell.OnExpandToggled += OnCellExpandToggled;
|
|
||||||
cell.OnGameObjectClicked += OnGameObjectClicked;
|
|
||||||
cell.OnEnableToggled += OnCellEnableToggled;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnGameObjectClicked(GameObject obj)
|
|
||||||
{
|
|
||||||
if (OnClickOverrideHandler != null)
|
|
||||||
OnClickOverrideHandler.Invoke(obj);
|
|
||||||
else
|
|
||||||
InspectorManager.Inspect(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCellExpandToggled(CachedTransform cache)
|
|
||||||
{
|
|
||||||
int instanceID = cache.InstanceID;
|
|
||||||
if (expandedInstanceIDs.Contains(instanceID))
|
|
||||||
expandedInstanceIDs.Remove(instanceID);
|
|
||||||
else
|
|
||||||
expandedInstanceIDs.Add(instanceID);
|
|
||||||
|
|
||||||
RefreshData(true, false, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCellEnableToggled(CachedTransform cache)
|
|
||||||
{
|
|
||||||
cache.Value.gameObject.SetActive(!cache.Value.gameObject.activeSelf);
|
|
||||||
|
|
||||||
RefreshData(true, false, true, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -79,11 +79,11 @@
|
|||||||
<!-- il2cpp nuget -->
|
<!-- il2cpp nuget -->
|
||||||
<ItemGroup Condition="'$(Configuration)'=='ML_Cpp_net6' or '$(Configuration)'=='ML_Cpp_net472' or '$(Configuration)'=='STANDALONE_Cpp' or '$(Configuration)'=='BIE_Cpp'">
|
<ItemGroup Condition="'$(Configuration)'=='ML_Cpp_net6' or '$(Configuration)'=='ML_Cpp_net472' or '$(Configuration)'=='STANDALONE_Cpp' or '$(Configuration)'=='BIE_Cpp'">
|
||||||
<PackageReference Include="Il2CppAssemblyUnhollower.BaseLib" Version="0.4.22" IncludeAssets="compile" />
|
<PackageReference Include="Il2CppAssemblyUnhollower.BaseLib" Version="0.4.22" IncludeAssets="compile" />
|
||||||
<PackageReference Include="UniverseLib.IL2CPP" Version="1.3.3" />
|
<PackageReference Include="UniverseLib.IL2CPP" Version="1.3.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- mono nuget -->
|
<!-- mono nuget -->
|
||||||
<ItemGroup Condition="'$(Configuration)'=='BIE6_Mono' or '$(Configuration)'=='BIE5_Mono' or '$(Configuration)'=='ML_Mono' or '$(Configuration)'=='STANDALONE_Mono'">
|
<ItemGroup Condition="'$(Configuration)'=='BIE6_Mono' or '$(Configuration)'=='BIE5_Mono' or '$(Configuration)'=='ML_Mono' or '$(Configuration)'=='STANDALONE_Mono'">
|
||||||
<PackageReference Include="UniverseLib.Mono" Version="1.3.3" />
|
<PackageReference Include="UniverseLib.Mono" Version="1.3.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- ~~~~~ ASSEMBLY REFERENCES ~~~~~ -->
|
<!-- ~~~~~ ASSEMBLY REFERENCES ~~~~~ -->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user