chore(unity): 固定Unity CLI Loop本地包并移除UnitySkills依赖

This commit is contained in:
Liubing\LB
2026-09-28 18:14:59 +08:00
parent 0eb43b2b40
commit c4ae02def9
952 changed files with 70137 additions and 11 deletions

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace io.github.hatayama.uLoopMCP
{
/// <summary>
/// Response structure for GetHierarchy tool
/// Always returns the JSON file path of exported hierarchy data.
/// </summary>
[Serializable]
public class GetHierarchyResponse : BaseToolResponse
{
/// <summary>
/// Human-readable guidance for clients to locate and read the JSON file
/// </summary>
[JsonProperty(Order = -2)]
public string message { get; }
/// <summary>
/// File path where hierarchy data was saved
/// </summary>
[JsonProperty(Order = -1)]
public string hierarchyFilePath { get; }
public GetHierarchyResponse(string filePath, string message = null)
{
this.hierarchyFilePath = filePath ?? string.Empty;
this.message = string.IsNullOrEmpty(message)
? "Hierarchy data saved below. Open the JSON to read 'Context' and 'Hierarchy'."
: message;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f30d6c26df90040cb8d25c68d7e472ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,32 @@
using System.ComponentModel;
namespace io.github.hatayama.uLoopMCP
{
/// <summary>
/// Input parameters for GetHierarchy command
/// </summary>
public class GetHierarchySchema : BaseToolSchema
{
[Description("Whether to include inactive GameObjects in the hierarchy result")]
public bool IncludeInactive { get; set; } = true;
[Description("Maximum depth to traverse the hierarchy (-1 for unlimited depth)")]
public int MaxDepth { get; set; } = -1;
[Description("Root GameObject path to start hierarchy traversal from (empty/null for all root objects)")]
public string RootPath { get; set; }
[Description("Whether to include component information for each GameObject in the hierarchy")]
public bool IncludeComponents { get; set; } = true;
// Advanced output options
[Description("Whether to include path information for nodes (default: false)")]
public bool IncludePaths { get; set; } = false;
[Description("Use LUT for components (auto|true|false)")]
public string UseComponentsLut { get; set; } = "auto";
[Description("Whether to use GameObject(s) currently selected in the Unity Hierarchy as root(s) for hierarchy traversal. When true, RootPath is ignored.")]
public bool UseSelection { get; set; } = false;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 822f8e20f41674bb9bcdb9f21c5c5adf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
using System.Threading.Tasks;
using System.Threading;
namespace io.github.hatayama.uLoopMCP
{
/// <summary>
/// Tool to retrieve Unity Hierarchy information in AI-friendly format
///
///
/// This Tool class delegates to GetHierarchyUseCase for business logic execution,
/// following the UseCase + Tool pattern for separation of concerns.
///
/// Related classes:
/// - GetHierarchyUseCase: Business logic and orchestration
/// - HierarchyService: Core logic for hierarchy traversal
/// - HierarchySerializer: JSON formatting logic
/// - HierarchyNode: Data structure for hierarchy nodes
/// - HierarchyNodeNested: Nested hierarchy structure
/// - HierarchyResultExporter: File export functionality
/// - GetHierarchySchema: Type-safe parameter schema
/// - GetHierarchyResponse: Type-safe response structure
/// </summary>
[McpTool(Description = "Get Unity Hierarchy structure for the whole scene, a root path, or selected GameObject descendants using UseSelection. Use this when the child tree, parent-child structure, or descendants under the selection are needed. Use find-game-objects for selected object details and component properties.")]
public class GetHierarchyTool : AbstractUnityTool<GetHierarchySchema, GetHierarchyResponse>
{
public override string ToolName => "get-hierarchy";
protected override async Task<GetHierarchyResponse> ExecuteAsync(GetHierarchySchema parameters, CancellationToken cancellationToken)
{
// Create and execute GetHierarchyUseCase instance
GetHierarchyUseCase useCase = new(new HierarchyService(), new HierarchySerializer());
return await useCase.ExecuteAsync(parameters, cancellationToken);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5d3cd5ac2d53e4ae9abdb06ebf037a9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using Newtonsoft.Json;
namespace io.github.hatayama.uLoopMCP
{
/// <summary>
/// Tool for exporting hierarchy results to external files
/// Related classes:
/// - HierarchyNodeNested: Data structure for hierarchy nodes
/// - GetHierarchyResponse: Response structure containing hierarchy data
/// - HierarchyContext: Context information for hierarchy
/// </summary>
public static class HierarchyResultExporter
{
private static readonly string EXPORT_DIR = Path.Combine(McpConstants.OUTPUT_ROOT_DIR, McpConstants.HIERARCHY_RESULTS_DIR);
private const string FILE_PREFIX = "hierarchy";
/// <summary>
/// Export hierarchy results to JSON file
/// </summary>
/// <param name="groups">Scene-grouped hierarchy nodes to export</param>
/// <param name="context">Context information about the hierarchy</param>
/// <returns>Relative path to the exported file</returns>
public static string ExportHierarchyResults(List<SceneHierarchyGroup> groups, HierarchyContext context)
{
if (groups == null)
{
groups = new List<SceneHierarchyGroup>();
}
// Create export directory if it doesn't exist
string exportDir = Path.Combine(Application.dataPath, "..", EXPORT_DIR);
Directory.CreateDirectory(exportDir);
// Generate filename with timestamp
string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
string filename = $"{FILE_PREFIX}_{timestamp}.json";
string filePath = Path.Combine(exportDir, filename);
// Create export data structure
// Ensure property order: ExportTimestamp -> Context -> Hierarchy
var exportData = new HierarchyExportData
{
ExportTimestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
Context = context,
Hierarchy = groups
};
// Export to JSON using Newtonsoft.Json for proper serialization
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
MaxDepth = McpServerConfig.DEFAULT_JSON_MAX_DEPTH,
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore
};
string jsonContent = JsonConvert.SerializeObject(exportData, settings);
File.WriteAllText(filePath, jsonContent);
// Return relative path
return Path.Combine(EXPORT_DIR, filename);
}
/// <summary>
/// Data structure for hierarchy export
/// </summary>
[Serializable]
public class HierarchyExportData
{
public string ExportTimestamp;
public HierarchyContext Context;
public List<SceneHierarchyGroup> Hierarchy;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 95572de04cd8f4a3ba4c5d332adb6e44
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4d3ab52184d8e4a3abd3286279e1d765
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,61 @@
---
name: uloop-get-hierarchy
description: "Get the Unity scene hierarchy as a structured tree. Use for parent-child structure, descendants, roots, or subtrees under objects the user currently selected."
---
# uloop get-hierarchy
Get Unity Hierarchy structure from the whole scene, a root path, or selected Hierarchy objects.
Use this for hierarchy structure, especially descendants under the current selection. Use `find-game-objects --search-mode Selected` when you need selected object details or component properties.
## Usage
```bash
uloop get-hierarchy [options]
```
## Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `--root-path` | string | - | Root GameObject path to start from |
| `--max-depth` | integer | `-1` | Maximum depth (-1 for unlimited) |
| `--include-components` | boolean | `true` | Include component information |
| `--include-inactive` | boolean | `true` | Include inactive GameObjects |
| `--include-paths` | boolean | `false` | Include full path information |
| `--use-components-lut` | string | `auto` | Use LUT for components (`auto`, `true`, `false`) |
| `--use-selection` | boolean | `false` | Use selected GameObject(s) as root(s). When true, `--root-path` is ignored. |
## Global Options
| Option | Description |
|--------|-------------|
| `--project-path <path>` | Optional. Use only when the target Unity project is not the current directory. |
## Examples
```bash
# Get entire hierarchy
uloop get-hierarchy
# Get hierarchy from specific root
uloop get-hierarchy --root-path "Canvas/UI"
# Limit depth
uloop get-hierarchy --max-depth 2
# Without components
uloop get-hierarchy --include-components false
# Get hierarchy from currently selected GameObjects
uloop get-hierarchy --use-selection
```
## Output
Returns JSON with:
- `message` (string): Human-readable guidance pointing at the saved file
- `hierarchyFilePath` (string): Filesystem path to the JSON file that contains the actual hierarchy data
The hierarchy itself is **not** in the response — it is written to the file at `hierarchyFilePath`. Open that file to read the `Context` and `Hierarchy` payload (GameObject tree, components, etc.).

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f59aa8bca78e24bd8ad677fec306f481
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: