chore(unity): 固定Unity CLI Loop本地包并移除UnitySkills依赖
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
namespace io.github.hatayama.uLoopMCP
|
||||
{
|
||||
public class FindGameObjectsResponse : BaseToolResponse
|
||||
{
|
||||
public FindGameObjectResult[] results { get; set; }
|
||||
public int totalFound { get; set; }
|
||||
public string errorMessage { get; set; }
|
||||
|
||||
// For multiple selection file output
|
||||
public string resultsFilePath { get; set; }
|
||||
public string message { get; set; }
|
||||
|
||||
// Processing errors for objects that failed to serialize
|
||||
public ProcessingError[] processingErrors { get; set; }
|
||||
}
|
||||
|
||||
public class FindGameObjectResult
|
||||
{
|
||||
public string name { get; set; }
|
||||
public string path { get; set; }
|
||||
public bool isActive { get; set; }
|
||||
public string tag { get; set; }
|
||||
public int layer { get; set; }
|
||||
public ComponentInfo[] components { get; set; }
|
||||
}
|
||||
|
||||
public class ProcessingError
|
||||
{
|
||||
public string gameObjectName { get; set; }
|
||||
public string gameObjectPath { get; set; }
|
||||
public string error { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cef91629352f241a5a29dc4d7a37baf9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace io.github.hatayama.uLoopMCP
|
||||
{
|
||||
/// <summary>
|
||||
/// Exports FindGameObjects results to external JSON files when multiple objects are selected.
|
||||
/// Related classes:
|
||||
/// - FindGameObjectsUseCase: Uses this exporter for multiple selection results
|
||||
/// - HierarchyResultExporter: Similar pattern for hierarchy export
|
||||
/// </summary>
|
||||
public static class FindGameObjectsResultExporter
|
||||
{
|
||||
private static readonly string EXPORT_DIR = Path.Combine(McpConstants.OUTPUT_ROOT_DIR, McpConstants.FIND_GAMEOBJECTS_RESULTS_DIR);
|
||||
private const string FILE_PREFIX = "find-game-objects";
|
||||
|
||||
/// <summary>
|
||||
/// Export search results to JSON file
|
||||
/// </summary>
|
||||
/// <param name="results">FindGameObjectResult array to export</param>
|
||||
/// <returns>Relative path to the exported file</returns>
|
||||
public static string ExportResults(FindGameObjectResult[] results)
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
results = new FindGameObjectResult[0];
|
||||
}
|
||||
|
||||
// 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
|
||||
FindGameObjectsExportData exportData = new FindGameObjectsExportData
|
||||
{
|
||||
ExportTimestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
TotalCount = results.Length,
|
||||
Results = results
|
||||
};
|
||||
|
||||
// Export to JSON using Newtonsoft.Json for proper serialization
|
||||
JsonSerializerSettings 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 FindGameObjects export
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class FindGameObjectsExportData
|
||||
{
|
||||
public string ExportTimestamp;
|
||||
public int TotalCount;
|
||||
public FindGameObjectResult[] Results;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c62f1377a5d024338ac66d89199f1d2a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace io.github.hatayama.uLoopMCP
|
||||
{
|
||||
public class FindGameObjectsSchema : BaseToolSchema
|
||||
{
|
||||
// Search criteria
|
||||
public string NamePattern { get; set; } = "";
|
||||
[Description("Search mode. Use Selected(4) to inspect the GameObject(s) currently selected in the Unity Hierarchy. Other modes are Exact(0), Path(1), Regex(2), Contains(3).")]
|
||||
public SearchMode SearchMode { get; set; } = SearchMode.Exact;
|
||||
public string[] RequiredComponents { get; set; } = new string[0];
|
||||
public string Tag { get; set; } = "";
|
||||
public int? Layer { get; set; } = null;
|
||||
public bool IncludeInactive { get; set; } = false;
|
||||
|
||||
// Result control
|
||||
public int MaxResults { get; set; } = 20; // Reduced from 100 to prevent performance issues
|
||||
public bool IncludeInheritedProperties { get; set; } = false;
|
||||
}
|
||||
|
||||
public enum SearchMode
|
||||
{
|
||||
Exact = 0, // Exact match (default)
|
||||
Path = 1, // Hierarchy path search (e.g. "Canvas/Button")
|
||||
Regex = 2, // Regular expression
|
||||
Contains = 3, // Partial match
|
||||
Selected = 4 // Get currently selected GameObjects in Unity Editor
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 812d2ec4f53ee4cf7ab19604e1def5ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace io.github.hatayama.uLoopMCP
|
||||
{
|
||||
/// <summary>
|
||||
/// Tool to find multiple GameObjects with advanced search criteria
|
||||
///
|
||||
///
|
||||
/// This Tool class delegates to FindGameObjectsUseCase for business logic execution,
|
||||
/// following the UseCase + Tool pattern for separation of concerns.
|
||||
///
|
||||
/// Related classes:
|
||||
/// - FindGameObjectsUseCase: Business logic and orchestration
|
||||
/// - GameObjectFinderService: Core logic for finding GameObjects
|
||||
/// - FindGameObjectsSchema: Search parameters
|
||||
/// - FindGameObjectsResponse: Type-safe response structure
|
||||
/// </summary>
|
||||
[McpTool(Description = "Use first when the user asks about the currently selected GameObject in the Unity Hierarchy. Inspect selected object details and component properties with SearchMode.Selected before using execute-dynamic-code. Also search by name, path, regex, tag, layer, or required components. Use get-hierarchy when the child tree under the selection is needed.")]
|
||||
public class FindGameObjectsTool : AbstractUnityTool<FindGameObjectsSchema, FindGameObjectsResponse>
|
||||
{
|
||||
public override string ToolName => "find-game-objects";
|
||||
|
||||
protected override async Task<FindGameObjectsResponse> ExecuteAsync(FindGameObjectsSchema parameters, CancellationToken cancellationToken)
|
||||
{
|
||||
// Create and execute FindGameObjectsUseCase instance
|
||||
FindGameObjectsUseCase useCase = new(new GameObjectFinderService(), new ComponentSerializer());
|
||||
return await useCase.ExecuteAsync(parameters, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d5408607c3b648a1bb9f9f431d7b03d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cce14537fd42d4bbaa7f76e5758a5b5d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
name: uloop-find-game-objects
|
||||
description: "Find or inspect Unity GameObjects, especially objects the user currently selected in the Hierarchy. Use for details, components, tags, layers, or name/path searches."
|
||||
---
|
||||
|
||||
# uloop find-game-objects
|
||||
|
||||
Find GameObjects with search criteria or get details for currently selected Hierarchy objects.
|
||||
|
||||
Use this before `execute-dynamic-code` when identifying or inspecting selected GameObjects. Use `get-hierarchy` instead when you need the child tree, parent-child structure, or descendants under the selection.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
uloop find-game-objects [options]
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `--name-pattern` | string | - | Name pattern to search |
|
||||
| `--search-mode` | string | `Exact` | Search mode: `Exact`, `Path`, `Regex`, `Contains`, `Selected` |
|
||||
| `--required-components` | array | - | Required components |
|
||||
| `--tag` | string | - | Tag filter |
|
||||
| `--layer` | integer | - | Layer filter (layer number) |
|
||||
| `--max-results` | integer | `20` | Maximum number of results |
|
||||
| `--include-inactive` | boolean | `false` | Include inactive GameObjects |
|
||||
| `--include-inherited-properties` | boolean | `false` | Include inherited properties in results |
|
||||
|
||||
## Search Modes
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `Exact` | Exact name match (default) |
|
||||
| `Path` | Hierarchy path search (e.g., `Canvas/Button`) |
|
||||
| `Regex` | Regular expression pattern |
|
||||
| `Contains` | Partial name match |
|
||||
| `Selected` | Get currently selected GameObjects in Unity Editor |
|
||||
|
||||
## Global Options
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--project-path <path>` | Optional. Use only when the target Unity project is not the current directory. |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Find by name
|
||||
uloop find-game-objects --name-pattern "Player"
|
||||
|
||||
# Find with component
|
||||
uloop find-game-objects --required-components Rigidbody
|
||||
|
||||
# Find by tag
|
||||
uloop find-game-objects --tag "Enemy"
|
||||
|
||||
# Regex search
|
||||
uloop find-game-objects --name-pattern "UI_.*" --search-mode Regex
|
||||
|
||||
# Get selected GameObjects
|
||||
uloop find-game-objects --search-mode Selected
|
||||
|
||||
# Get selected including inactive
|
||||
uloop find-game-objects --search-mode Selected --include-inactive
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
Returns JSON with:
|
||||
- `results` (array): Matching GameObjects, each containing:
|
||||
- `name` (string): GameObject name
|
||||
- `path` (string): Hierarchy path (e.g., `Canvas/Panel/Button`)
|
||||
- `isActive` (boolean): Active state in hierarchy
|
||||
- `tag` (string): GameObject tag
|
||||
- `layer` (number): Layer index
|
||||
- `components` (array): Each entry has `type` (short name, e.g., `Rigidbody`), `fullTypeName` (e.g., `UnityEngine.Rigidbody`), and `properties` (array of Inspector-visible `{name, type, value}` pairs)
|
||||
- `totalFound` (number): Number of results returned inline, or number exported for multi-selection file output. For search modes, this is after `--max-results` clipping and serialization.
|
||||
- `errorMessage` (string): Top-level failure summary (empty on success)
|
||||
- `processingErrors` (array): Selected-mode per-GameObject serialization failures, each `{gameObjectName, gameObjectPath, error}`. Omitted/null or empty on clean runs.
|
||||
|
||||
### Multi-selection file export
|
||||
|
||||
For `Selected` mode with **multiple** successfully serialized GameObjects, inline `results` is not populated and the data is written to a file instead. Two extra fields appear:
|
||||
- `resultsFilePath` (string): Relative path under `.uloop/outputs/FindGameObjectsResults/`
|
||||
- `message` (string): Human-readable summary (e.g., "5 GameObjects exported")
|
||||
|
||||
Single-selection and search-mode calls (`Exact`, `Path`, `Regex`, `Contains`) always return inline. No selection (`Selected` mode with empty selection) returns empty `results` plus a `message`.
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: acc63be277ef0466f9effdaefa539073
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user