171 lines
7.4 KiB
C#
171 lines
7.4 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using UnityEngine;
|
|||
|
using UnityEngine.SceneManagement;
|
|||
|
|
|||
|
namespace QFSW.QC.Extras
|
|||
|
{
|
|||
|
public static class UtilCommands
|
|||
|
{
|
|||
|
private static readonly Pool<StringBuilder> _builderPool = new Pool<StringBuilder>();
|
|||
|
|
|||
|
[Command("get-object-info", "Finds the specified GameObject and displays its transform and component data")]
|
|||
|
private static string ExtractObjectInfo(GameObject target)
|
|||
|
{
|
|||
|
StringBuilder builder = _builderPool.GetObject();
|
|||
|
builder.Clear();
|
|||
|
|
|||
|
builder.AppendLine($"Extracted info for object '{target.name}'");
|
|||
|
builder.AppendLine("Transform data:");
|
|||
|
builder.AppendLine($" - position: {target.transform.position}");
|
|||
|
builder.AppendLine($" - rotation: {target.transform.localRotation}");
|
|||
|
builder.AppendLine($" - scale: {target.transform.localScale}");
|
|||
|
if (target.transform.childCount > 0) { builder.AppendLine($" - child count: {target.transform.childCount}"); }
|
|||
|
if (target.transform.parent) { builder.AppendLine($" - parent: {target.transform.parent.name}"); }
|
|||
|
|
|||
|
Component[] components = target.GetComponents<Component>().OrderBy(x => x.GetType().Name).ToArray();
|
|||
|
|
|||
|
if (components.Length > 0)
|
|||
|
{
|
|||
|
builder.AppendLine("Component data:");
|
|||
|
for (int i = 0; i < components.Length; i++)
|
|||
|
{
|
|||
|
int componentCount = 1;
|
|||
|
Type componentType = components[i].GetType();
|
|||
|
builder.AppendLine($" - {componentType.Name}");
|
|||
|
while (i + 1 < components.Length && components[i + 1].GetType() == componentType)
|
|||
|
{
|
|||
|
componentCount++;
|
|||
|
i++;
|
|||
|
}
|
|||
|
|
|||
|
if (componentCount > 1) { builder.Append($" ({componentCount})"); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (target.transform.childCount > 0)
|
|||
|
{
|
|||
|
builder.AppendLine("Children:");
|
|||
|
|
|||
|
int childCount = target.transform.childCount;
|
|||
|
for (int i = 0; i < childCount; i++)
|
|||
|
{
|
|||
|
builder.AppendLine($" - {target.transform.GetChild(i).name}");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
string info = builder.ToString();
|
|||
|
_builderPool.Release(builder);
|
|||
|
return info;
|
|||
|
}
|
|||
|
|
|||
|
[Command("get-scene-hierarchy", "Renders the GameObject hierarchy of the currently open scenes")]
|
|||
|
private static string GetSceneHierarchy()
|
|||
|
{
|
|||
|
List<GameObject> objects = new List<GameObject>();
|
|||
|
StringBuilder buffer = _builderPool.GetObject();
|
|||
|
buffer.Clear();
|
|||
|
|
|||
|
int sceneCount = SceneManager.sceneCountInBuildSettings;
|
|||
|
for (int i = 0; i < sceneCount; i++)
|
|||
|
{
|
|||
|
Scene scene = SceneManager.GetSceneByBuildIndex(i);
|
|||
|
if (scene.isLoaded)
|
|||
|
{
|
|||
|
objects.Clear();
|
|||
|
scene.GetRootGameObjects(objects);
|
|||
|
|
|||
|
buffer.AppendLine(scene.name);
|
|||
|
GetSceneHierarchy(objects.Select(x => x.transform).ToArray(), 0, buffer, new List<bool>());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
string result = buffer.ToString();
|
|||
|
_builderPool.Release(buffer);
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private static IEnumerable<Transform> GetChildren(this Transform transform)
|
|||
|
{
|
|||
|
for (int i = 0; i < transform.childCount; i++)
|
|||
|
{
|
|||
|
yield return transform.GetChild(i);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private static void GetSceneHierarchy(IList<Transform> roots, int depth, StringBuilder buffer, IList<bool> drawVertical)
|
|||
|
{
|
|||
|
const char terminalSymbol = '|';
|
|||
|
const char verticalSplitSymbol = '|';
|
|||
|
const char verticalSymbol = '|';
|
|||
|
const char horizontalSymbol = '-';
|
|||
|
const int indentation = 3;
|
|||
|
|
|||
|
for (int i = 0; i < roots.Count; i++)
|
|||
|
{
|
|||
|
Transform root = roots[i];
|
|||
|
|
|||
|
for (int j = 0; j < depth; j++)
|
|||
|
{
|
|||
|
buffer.Append(drawVertical[j] ? verticalSymbol : ' ');
|
|||
|
buffer.Append(' ', indentation - 1);
|
|||
|
}
|
|||
|
|
|||
|
bool terminal = i == roots.Count - 1;
|
|||
|
drawVertical.Add(!terminal);
|
|||
|
|
|||
|
buffer.Append(terminal ? terminalSymbol : verticalSplitSymbol);
|
|||
|
buffer.Append(horizontalSymbol, indentation - 1);
|
|||
|
buffer.AppendLine(root.name);
|
|||
|
|
|||
|
GetSceneHierarchy(root.GetChildren().ToList(), depth + 1, buffer, drawVertical);
|
|||
|
drawVertical.RemoveAt(drawVertical.Count - 1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Command("add-component", "Adds a component of type T to the specified GameObject")]
|
|||
|
private static void AddComponent<T>(GameObject target) where T : Component { target.AddComponent<T>(); }
|
|||
|
|
|||
|
[Command("destroy-component", "Destroys the component of type T on the specified GameObject")]
|
|||
|
private static void DestroyComponent<T>(T target) where T : Component { GameObject.Destroy(target); }
|
|||
|
|
|||
|
[Command("destroy", "Destroys a GameObject")]
|
|||
|
private static void DestroyGO(GameObject target) { GameObject.Destroy(target); }
|
|||
|
|
|||
|
[Command("instantiate", "Instantiates a GameObject")]
|
|||
|
private static void InstantiateGO(
|
|||
|
[CommandParameterDescription("The original GameObject to instantiate a copy of.")] GameObject original,
|
|||
|
[CommandParameterDescription("The position of the instantiated GameObject.")] Vector3 position,
|
|||
|
[CommandParameterDescription("The rotation of the instantiated GameObject.")] Quaternion rotation)
|
|||
|
{
|
|||
|
GameObject.Instantiate(original, position, rotation);
|
|||
|
}
|
|||
|
|
|||
|
[Command("instantiate", "Instantiates a GameObject")]
|
|||
|
private static void InstantiateGO(GameObject original, Vector3 position) { GameObject.Instantiate(original).transform.position = position; }
|
|||
|
|
|||
|
[Command("instantiate", "Instantiates a GameObject")]
|
|||
|
private static void InstantiateGO(GameObject original) { GameObject.Instantiate(original); }
|
|||
|
|
|||
|
[Command("teleport", "Teleports a GameObject")]
|
|||
|
private static void TeleportGO(GameObject target, Vector3 position) { target.transform.position = position; }
|
|||
|
|
|||
|
[Command("teleport-relative", "Teleports a GameObject by a relative offset to its current position")]
|
|||
|
private static void TeleportRelativeGO(GameObject target, Vector3 offset) { target.transform.Translate(offset); }
|
|||
|
|
|||
|
[Command("rotate", "Rotates a GameObject")]
|
|||
|
private static void RotateGO(GameObject target, Quaternion rotation) { target.transform.Rotate(rotation.eulerAngles); }
|
|||
|
|
|||
|
[Command("set-active", "Activates/deactivates a GameObject")]
|
|||
|
private static void SetGOActive(GameObject target, bool active) { target.SetActive(active); }
|
|||
|
|
|||
|
[Command("set-parent", "Sets the parent of the targert transform.")]
|
|||
|
private static void SetGOParent(Transform target, Transform parentTarget) { target.SetParent(parentTarget); }
|
|||
|
|
|||
|
[Command("send-message", "Calls the method named 'methodName' on every MonoBehaviour in the target GameObject")]
|
|||
|
private static void SendGOMessage(GameObject target, string methodName) { target.SendMessage(methodName); }
|
|||
|
}
|
|||
|
}
|