diff --git a/README.md b/README.md index 1d8614e8..32622016 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

Unity - Skills + Skills License 中文

@@ -30,7 +30,7 @@ This project is a deep refactoring and feature extension based on the excellent ## 🚀 Core Features -- 🛠️ **733 REST Skills Comprehensive Toolkit**: Includes 51 functional source modules plus 20 advisory design modules, with Batch operations for multi-object control. +- 🛠️ **771 REST Skills Comprehensive Toolkit**: Includes 52 functional source modules plus 23 advisory design modules, with Batch operations for multi-object control. - ⚡ **Revolutionary Efficiency Boost (v2.0.1+)**: Schema caching + exponential backoff polling + BATCH-FIRST guidance → **Token consumption ↓ 96%**, **simple tasks 4-6 calls → 1 call (↓ 75-83%)**. Current: v2.1.3. - 🔐 **Three-Tier Permission Modes (v1.9.0+)**: Approval / Auto / Bypass with dual approval channels (Dialog / Panel), aligned with Claude Code permission modes; zero-impact upgrade for existing users. - 🤖 **4 Major IDEs Native Support**: Claude Code / Antigravity / Codex / Cursor — one-click install and use. @@ -63,7 +63,7 @@ UnitySkills ships with a true server-side permission system aligned with Claude > > 🗑 The Skill Installer card shows a **per-scope uninstall** button that auto-adapts: disabled when nothing's installed, a single button labeled with its scope when only one is installed, and a dropdown (`Uninstall ▾`) listing Project / Global when both are installed. > -> 20 advisory design modules (architecture, performance, design patterns, testability, package-specific source rules, etc.) are available in all modes and loaded on demand. +> 23 advisory design modules (architecture, performance, design patterns, testability, package-specific source rules, etc.) are available in all modes and loaded on demand. --- @@ -173,7 +173,7 @@ If you're using other tools that support Skills, install according to the Skills ---
-

📦 Skills Category Overview (733)

+

📦 Skills Category Overview (771)

| Category | Count | Core Functions | | :--- | :---: | :--- | @@ -195,6 +195,7 @@ If you're using other tools that support Skills, install according to the Skills | **URP** | 7 | URP asset/renderer/renderer feature inspection and edits | | **Decal** | 7 | URP Decal Projector create/inspect/configure/delete workflows | | **DOTween** | 21 | DOTweenAnimation editor-time setup and tuning | +| **PrimeTween** | 5 | PrimeTween Free inspection, factory discovery, and runtime tween/sequence script generation | | **Editor** | 14 | Play mode runtime capture/Selection/Undo-Redo/Context retrieval/Change journal/Menu execution | | **Physics** | 12 | Raycast/SphereCast/BoxCast/Physics materials/Layer collision matrix | | **Script** | 12 | C# script create/Read/Replace/List/Info/Rename/Move/Analyze | @@ -230,7 +231,7 @@ If you're using other tools that support Skills, install according to the Skills > ⚠️ Most modules support `*_batch` batch operations. When operating on multiple objects, prioritize batch Skills for better performance. > -> 🧠 `unity-skills/skills/` also includes **20 advisory design modules** for architecture, script design, performance, maintainability, Inspector guidance, and package-specific source rules. +> 🧠 `unity-skills/skills/` also includes **23 advisory design modules** for architecture, script design, performance, maintainability, Inspector guidance, and package-specific source rules.
@@ -246,9 +247,9 @@ If you're using other tools that support Skills, install according to the Skills │ │ ├── SKILL.md # Main Skill Definitions (AI-readable) │ │ ├── scripts/ │ │ │ └── unity_skills.py # Python Client Library -│ │ ├── skills/ # 69 module docs (49 REST/module docs + 20 advisory docs) +│ │ ├── skills/ # 71 module docs (48 REST/module docs + 23 advisory docs) │ │ └── references/ # Unity Development References -│ └── Editor/Skills/ # Core Skill Logic (51 *Skills.cs files, 733 Skills) +│ └── Editor/Skills/ # Core Skill Logic (52 *Skills.cs files, 771 Skills) │ ├── SkillsHttpServer.cs # HTTP Server Core (Producer-Consumer) │ ├── SkillRouter.cs # Request Routing & Reflection-based Skill Discovery │ ├── WorkflowManager.cs # Persistent Workflow (Task/Session/Snapshot) @@ -260,7 +261,7 @@ If you're using other tools that support Skills, install according to the Skills │ ├── CinemachineSkills.cs # Cinemachine 2.x/3.x (34 skills) │ ├── WorkflowSkills.cs # Workflow Undo/Rollback (23 skills) │ ├── PerceptionSkills.cs # Scene Understanding (18 skills) -│ └── ... # 733 Skills source code +│ └── ... # 771 Skills source code ├── docs/ │ └── SETUP_GUIDE.md # Complete Setup & Usage Guide ├── CHANGELOG.md # Version Update Log diff --git a/README_CN.md b/README_CN.md index 4d9f9890..4569f250 100644 --- a/README_CN.md +++ b/README_CN.md @@ -6,7 +6,7 @@

Unity - Skills + Skills License English

@@ -30,7 +30,7 @@ ## 🚀 核心特性 -- 🛠️ **733 REST Skills 全能库**:包含 51 个功能源码模块和 20 个 advisory 设计模块,支持 Batch 批处理,一次操控多个对象。 +- 🛠️ **771 REST Skills 全能库**:包含 52 个功能源码模块和 23 个 advisory 设计模块,支持 Batch 批处理,一次操控多个对象。 - ⚡ **调用效率革命性提升 (v2.0.1+)**:Schema 缓存 + 指数退避轮询 + BATCH-FIRST 引导 → **Token 消耗 ↓ 96%**,**简单任务 4-6 次调用 → 1 次(↓ 75-83%)**。当前:v2.1.3。 - 🔐 **三档权限模式 (v1.9.0+)**:Approval / Auto / Bypass,配合双轨审批渠道(Dialog / Panel),对齐 Claude Code permission modes;老用户升级零感知。 - 🤖 **4 大 IDE 原生支持**:Claude Code / Antigravity / Codex / Cursor,一键安装即用。 @@ -63,7 +63,7 @@ UnitySkills 引入真正的服务端权限系统,对齐 Claude Code permission > > 🗑 Skill Installer 卡片的"卸载"按钮按 scope 智能形变:未装为灰态;仅一处装则按钮自带 scope 标签直接卸载;两处都装则显示 `Uninstall ▾` 下拉,分别选择 Project / Global。 > -> 20 个 advisory 设计模块(架构、性能、设计模式、可测试性、包级源码规则等)在所有模式下均可用,按需自动加载。 +> 23 个 advisory 设计模块(架构、性能、设计模式、可测试性、包级源码规则等)在所有模式下均可用,按需自动加载。 --- @@ -173,7 +173,7 @@ https://github.com/Besty0728/Unity-Skills.git?path=/SkillsForUnity#v1.6.0 ---
-

📦 Skills 分类概要 (733)

+

📦 Skills 分类概要 (771)

| 分类 | 数量 | 核心功能 | | :--- | :---: | :--- | @@ -195,6 +195,7 @@ https://github.com/Besty0728/Unity-Skills.git?path=/SkillsForUnity#v1.6.0 | **URP** | 7 | URP 资产/Renderer/Renderer Feature 检查与编辑 | | **Decal** | 7 | URP Decal Projector 创建/检查/配置/删除工作流 | | **DOTween** | 21 | DOTweenAnimation 编辑器期配置与调参 | +| **PrimeTween** | 5 | PrimeTween Free 检查、工厂方法发现与运行时补间/序列脚本生成 | | **Editor** | 14 | Play 模式运行捕获/选择/撤销重做/上下文获取/变更日志/菜单执行 | | **Physics** | 12 | 射线检测/球形投射/盒形投射/物理材质/层碰撞矩阵 | | **Script** | 12 | C#脚本创建/读取/替换/列表/信息/重命名/移动/分析 | @@ -230,7 +231,7 @@ https://github.com/Besty0728/Unity-Skills.git?path=/SkillsForUnity#v1.6.0 > ⚠️ 大部分模块支持 `*_batch` 批量操作,操作多个物体时应优先使用批量 Skills 以提升性能。 > -> 🧠 `unity-skills/skills/` 目录下额外提供 **20 个 advisory 设计模块**,用于在脚本编写前辅助 AI 进行架构、性能、可维护性、Inspector 设计与包级源码规则决策。 +> 🧠 `unity-skills/skills/` 目录下额外提供 **23 个 advisory 设计模块**,用于在脚本编写前辅助 AI 进行架构、性能、可维护性、Inspector 设计与包级源码规则决策。
@@ -246,9 +247,9 @@ https://github.com/Besty0728/Unity-Skills.git?path=/SkillsForUnity#v1.6.0 │ │ ├── SKILL.md # 主 Skill 定义 (AI 读取) │ │ ├── scripts/ │ │ │ └── unity_skills.py # Python 客户端库 -│ │ ├── skills/ # 69 个模块文档(49 个 REST/模块文档 + 20 个 advisory 文档) +│ │ ├── skills/ # 71 个模块文档(48 个 REST/模块文档 + 23 个 advisory 文档) │ │ └── references/ # Unity 开发参考文档 -│ └── Editor/Skills/ # 核心 Skill 逻辑 (51 个 *Skills.cs, 共 733 Skills) +│ └── Editor/Skills/ # 核心 Skill 逻辑 (52 个 *Skills.cs, 共 771 Skills) │ ├── SkillsHttpServer.cs # HTTP 服务器核心 (Producer-Consumer) │ ├── SkillRouter.cs # 请求路由 & 反射发现 Skills │ ├── WorkflowManager.cs # 持久化工作流 (Task/Session/Snapshot) @@ -260,7 +261,7 @@ https://github.com/Besty0728/Unity-Skills.git?path=/SkillsForUnity#v1.6.0 │ ├── CinemachineSkills.cs # Cinemachine 2.x/3.x (34 skills) │ ├── WorkflowSkills.cs # Workflow 撤销/回滚 (23 skills) │ ├── PerceptionSkills.cs # 场景理解 (18 skills) -│ └── ... # 733 Skills 源码 +│ └── ... # 771 Skills 源码 ├── docs/ │ └── SETUP_GUIDE.md # 完整安装使用指南 ├── CHANGELOG.md # 版本更新记录 diff --git a/SkillsForUnity/Editor/Skills/Localization.cs b/SkillsForUnity/Editor/Skills/Localization.cs index abb47feb..06e59d6f 100644 --- a/SkillsForUnity/Editor/Skills/Localization.cs +++ b/SkillsForUnity/Editor/Skills/Localization.cs @@ -514,6 +514,11 @@ public static string Get(string key) {"decal_delete", "Delete a Decal Projector GameObject"}, {"decal_set_properties_batch", "Modify multiple Decal Projectors in one request"}, {"decal_ensure_renderer_feature", "Ensure the current URP renderer has a DecalRendererFeature"}, + {"primetween_get_status", "Get PrimeTween Free installation status and package version"}, + {"primetween_get_config", "Read PrimeTween global runtime configuration"}, + {"primetween_list_factories", "List PrimeTween public factory methods"}, + {"primetween_generate_tween_script", "Generate a PrimeTween Transform tween MonoBehaviour script"}, + {"primetween_generate_sequence_script", "Generate a PrimeTween Sequence MonoBehaviour script"}, {"dotween_get_status", "Get DOTween installation status, Pro availability, settings, and visible modules"}, {"dotween_settings_get", "Read common fields from Resources/DOTweenSettings.asset"}, {"dotween_settings_find", "Find DOTweenSettings assets in the project"}, @@ -1796,6 +1801,13 @@ public static string Get(string key) {"decal_set_properties_batch", "批量修改 Decal Projector 属性"}, {"decal_ensure_renderer_feature", "确保当前 URP 渲染器已启用 DecalRendererFeature"}, + // PrimeTween Skills + {"primetween_get_status", "获取 PrimeTween Free 安装状态与包版本"}, + {"primetween_get_config", "读取 PrimeTween 全局运行时配置"}, + {"primetween_list_factories", "列出 PrimeTween 公开工厂方法"}, + {"primetween_generate_tween_script", "生成 PrimeTween Transform 补间 MonoBehaviour 脚本"}, + {"primetween_generate_sequence_script", "生成 PrimeTween Sequence MonoBehaviour 脚本"}, + // DOTween Skills {"dotween_get_status", "获取 DOTween 安装状态、Pro 可用性、设置与已加载模块"}, {"dotween_settings_get", "读取 Resources/DOTweenSettings.asset 的常用字段"}, diff --git a/SkillsForUnity/Editor/Skills/PrimeTweenSkills.cs b/SkillsForUnity/Editor/Skills/PrimeTweenSkills.cs new file mode 100644 index 00000000..4e6c4b39 --- /dev/null +++ b/SkillsForUnity/Editor/Skills/PrimeTweenSkills.cs @@ -0,0 +1,737 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using Newtonsoft.Json; +using UnityEditor; +using UnityEditor.PackageManager; +using UnityEngine; +using UnitySkills.Internal; + +namespace UnitySkills +{ + /// + /// PrimeTween Free diagnostics, API discovery, and runtime-script generation. + /// All PrimeTween access is reflective so UnitySkills continues to compile + /// when the optional package is not installed. + /// + public static class PrimeTweenSkills + { + private const string PackageName = "com.kyrylokuzyk.primetween"; + private const string TweenTypeName = "PrimeTween.Tween"; + private const string SequenceTypeName = "PrimeTween.Sequence"; + private const string ConfigTypeName = "PrimeTween.PrimeTweenConfig"; + private const string ShakeTypeName = "PrimeTween.Shake"; + + [UnitySkill("primetween_get_status", + "Get PrimeTween Free installation status, package version, and the available core API types.", + Category = SkillCategory.PrimeTween, Operation = SkillOperation.Query, + Tags = new[] { "primetween", "free", "status", "installed", "package" }, + Outputs = new[] { "isInstalled", "packageVersion", "types" }, + RequiresPackages = new[] { PackageName }, + Mode = SkillMode.SemiAuto)] + public static object PrimeTweenGetStatus() + { + var tweenType = FindType(TweenTypeName); + if (tweenType == null) + { + return new + { + isInstalled = false, + error = $"PrimeTween Free is not installed. Install the '{PackageName}' package before using PrimeTween skills." + }; + } + + var packageInfo = PackageInfo.FindForAssembly(tweenType.Assembly); + var typeNames = new[] + { + TweenTypeName, + SequenceTypeName, + ConfigTypeName, + ShakeTypeName + }; + + return new + { + isInstalled = true, + packageName = packageInfo?.name, + packageVersion = packageInfo?.version, + assembly = tweenType.Assembly.GetName().Name, + types = typeNames + .Select(FindType) + .Where(type => type != null) + .Select(type => type.FullName) + .OrderBy(name => name) + .ToArray() + }; + } + + [UnitySkill("primetween_get_config", + "Read PrimeTween's current global runtime configuration. These values are static runtime settings, not a project asset.", + Category = SkillCategory.PrimeTween, Operation = SkillOperation.Query, + Tags = new[] { "primetween", "free", "config", "runtime", "query" }, + Outputs = new[] { "success", "properties" }, + RequiresPackages = new[] { PackageName }, + Mode = SkillMode.SemiAuto)] + public static object PrimeTweenGetConfig() + { + var configType = FindType(ConfigTypeName); + if (configType == null) + { + return NoPrimeTween(); + } + + var propertyNames = new[] + { + "defaultEase", + "defaultUpdateType" + }; + var properties = new Dictionary(); + var unavailable = new List(); + + foreach (var propertyName in propertyNames) + { + var property = configType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Static); + if (property == null || !property.CanRead || property.GetMethod == null || !property.GetMethod.IsPublic) + { + unavailable.Add(propertyName); + continue; + } + + try + { + properties[propertyName] = Stringify(property.GetValue(null)); + } + catch (Exception exception) + { + unavailable.Add($"{propertyName}: {exception.Message}"); + } + } + + return new + { + success = true, + properties, + unavailable, + note = "PrimeTweenConfig is process-wide runtime state. This skill intentionally does not modify it." + }; + } + + [UnitySkill("primetween_list_factories", + "List PrimeTween Free public factory methods on Tween, Sequence, Shake, or PrimeTweenConfig.", + Category = SkillCategory.PrimeTween, Operation = SkillOperation.Query, + Tags = new[] { "primetween", "free", "api", "factory", "reflection" }, + Outputs = new[] { "count", "methods" }, + RequiresPackages = new[] { PackageName }, + Mode = SkillMode.SemiAuto)] + public static object PrimeTweenListFactories(string typeName = "Tween", string methodPrefix = null, int limit = 100) + { + var type = ResolveApiType(typeName); + if (type == null) + { + return new + { + error = "PrimeTween is not installed, or typeName must be Tween, Sequence, Shake, or PrimeTweenConfig." + }; + } + + var methods = type + .GetMethods(BindingFlags.Public | BindingFlags.Static) + .Where(method => !method.IsSpecialName) + .Where(method => string.IsNullOrEmpty(methodPrefix) || + method.Name.StartsWith(methodPrefix, StringComparison.OrdinalIgnoreCase)) + .OrderBy(method => method.Name) + .ThenBy(method => method.GetParameters().Length) + .Take(Mathf.Max(limit, 1)) + .Select(ToMethodInfo) + .ToArray(); + + return new + { + type = type.FullName, + count = methods.Length, + methods + }; + } + + [UnitySkill("primetween_generate_tween_script", + "Generate a PrimeTween Free MonoBehaviour for a supported Transform animation. The generated script owns and stops its tween; it does not create DOTween-style links.", + Category = SkillCategory.PrimeTween, Operation = SkillOperation.Create, + Tags = new[] { "primetween", "free", "generate", "script", "runtime", "tween" }, + Outputs = new[] { "success", "path", "className" }, + RequiresInput = new[] { "className" }, + RequiresPackages = new[] { PackageName }, + TracksWorkflow = true, MutatesAssets = true, MayTriggerReload = true, RiskLevel = "high")] + public static object PrimeTweenGenerateTweenScript( + string className, + string folder = "Assets/Scripts/PrimeTween", + string namespaceName = null, + string tweenKind = "LocalPosition", + float duration = 1f, + string ease = "OutQuad", + int cycles = 1, + string cycleMode = "Restart", + bool autoPlay = true) + { + if (FindType(TweenTypeName) == null) + { + return NoPrimeTween(); + } + + var spec = ResolveTransformTween(tweenKind); + if (spec == null) + { + return UnsupportedTween(tweenKind); + } + + if (TryValidateGeneratorInputs(ease, cycleMode, cycles) is object error) + { + return error; + } + + return WriteGeneratedScript( + className, + folder, + BuildTweenScript(className, namespaceName, spec, duration, ease, cycles, cycleMode, autoPlay)); + } + + [UnitySkill("primetween_generate_sequence_script", + "Generate a PrimeTween Free MonoBehaviour that composes supported Transform tweens with Sequence.Chain and Sequence.Group.", + Category = SkillCategory.PrimeTween, Operation = SkillOperation.Create, + Tags = new[] { "primetween", "free", "generate", "script", "runtime", "sequence" }, + Outputs = new[] { "success", "path", "className" }, + RequiresInput = new[] { "className" }, + RequiresPackages = new[] { PackageName }, + TracksWorkflow = true, MutatesAssets = true, MayTriggerReload = true, RiskLevel = "high")] + public static object PrimeTweenGenerateSequenceScript( + string className, + string folder = "Assets/Scripts/PrimeTween", + string namespaceName = null, + string tweenKind = "Scale", + float duration = 0.2f, + string ease = "OutBack", + int cycles = 1, + string sequenceCycleMode = "Restart", + bool autoPlay = true, + string stepsJson = null) + { + if (FindType(SequenceTypeName) == null) + { + return NoPrimeTween(); + } + + var steps = ParseSequenceSteps(stepsJson, tweenKind, duration); + if (steps == null || steps.Count == 0) + { + return new + { + error = "stepsJson must be a JSON array of { op: Chain|Group, tweenKind, duration }." + }; + } + + var specs = new List(); + foreach (var step in steps) + { + var spec = ResolveTransformTween(step.tweenKind ?? tweenKind); + if (spec == null) + { + return UnsupportedTween(step.tweenKind ?? tweenKind); + } + + if (!string.Equals(step.op, "Chain", StringComparison.OrdinalIgnoreCase) && + !string.Equals(step.op, "Group", StringComparison.OrdinalIgnoreCase)) + { + return new { error = $"Unsupported sequence operation '{step.op}'. Use Chain or Group." }; + } + + specs.Add(new SequenceStep + { + Operation = string.Equals(step.op, "Group", StringComparison.OrdinalIgnoreCase) ? "Group" : "Chain", + Tween = spec, + Duration = step.duration > 0f ? step.duration : duration + }); + } + + if (TryValidateGeneratorInputs(ease, sequenceCycleMode, cycles, SequenceTypeName + "+SequenceCycleMode") is object error) + { + return error; + } + + return WriteGeneratedScript( + className, + folder, + BuildSequenceScript(className, namespaceName, specs, ease, cycles, sequenceCycleMode, autoPlay)); + } + + private sealed class TransformTweenSpec + { + public string Method; + public string FieldName; + public string DefaultValue; + public string StartValueExpression; + } + + private sealed class SequenceStepInput + { + public string op { get; set; } + public string tweenKind { get; set; } + public float duration { get; set; } + } + + private sealed class SequenceStep + { + public string Operation; + public TransformTweenSpec Tween; + public float Duration; + } + + private static object NoPrimeTween() + { + return new + { + error = $"PrimeTween Free is not installed. Install the '{PackageName}' package before using PrimeTween skills." + }; + } + + private static Type ResolveApiType(string typeName) + { + if (string.Equals(typeName, "Tween", StringComparison.OrdinalIgnoreCase)) + { + return FindType(TweenTypeName); + } + + if (string.Equals(typeName, "Sequence", StringComparison.OrdinalIgnoreCase)) + { + return FindType(SequenceTypeName); + } + + if (string.Equals(typeName, "Shake", StringComparison.OrdinalIgnoreCase)) + { + return FindType(ShakeTypeName); + } + + if (string.Equals(typeName, "PrimeTweenConfig", StringComparison.OrdinalIgnoreCase)) + { + return FindType(ConfigTypeName); + } + + return null; + } + + private static Type FindType(string typeName) + { + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + var type = assembly.GetType(typeName, throwOnError: false); + if (type != null) + { + return type; + } + } + + return null; + } + + private static object ToMethodInfo(MethodInfo method) + { + var parameters = method + .GetParameters() + .Select(parameter => new + { + name = parameter.Name, + type = FriendlyTypeName(parameter.ParameterType), + optional = parameter.IsOptional, + defaultValue = parameter.IsOptional ? parameter.DefaultValue?.ToString() : null + }) + .ToArray(); + + return new + { + name = method.Name, + returnType = FriendlyTypeName(method.ReturnType), + parameters, + signature = $"{FriendlyTypeName(method.ReturnType)} {method.Name}({string.Join(", ", parameters.Select(parameter => $"{parameter.type} {parameter.name}"))})" + }; + } + + private static string FriendlyTypeName(Type type) + { + if (type == null) + { + return null; + } + + if (!type.IsGenericType) + { + return type.FullName ?? type.Name; + } + + var name = type.Name; + var genericMarker = name.IndexOf('`'); + if (genericMarker >= 0) + { + name = name.Substring(0, genericMarker); + } + + return $"{type.Namespace}.{name}<{string.Join(",", type.GetGenericArguments().Select(FriendlyTypeName))}>"; + } + + private static object Stringify(object value) + { + if (value == null) + { + return null; + } + + if (value is Enum enumValue) + { + return enumValue.ToString(); + } + + return value; + } + + private static TransformTweenSpec ResolveTransformTween(string tweenKind) + { + switch ((tweenKind ?? string.Empty).Trim().ToLowerInvariant()) + { + case "position": + return new TransformTweenSpec { Method = "Position", FieldName = "endPosition", DefaultValue = "new Vector3(0f, 1f, 0f)" }; + case "localposition": + return new TransformTweenSpec { Method = "LocalPosition", FieldName = "endLocalPosition", DefaultValue = "new Vector3(0f, 1f, 0f)" }; + case "eulerangles": + return new TransformTweenSpec { Method = "EulerAngles", FieldName = "endEulerAngles", DefaultValue = "new Vector3(0f, 180f, 0f)", StartValueExpression = "_target.eulerAngles" }; + case "localeulerangles": + return new TransformTweenSpec { Method = "LocalEulerAngles", FieldName = "endLocalEulerAngles", DefaultValue = "new Vector3(0f, 180f, 0f)", StartValueExpression = "_target.localEulerAngles" }; + case "scale": + return new TransformTweenSpec { Method = "Scale", FieldName = "endScale", DefaultValue = "Vector3.one * 1.2f" }; + default: + return null; + } + } + + private static object UnsupportedTween(string tweenKind) + { + return new + { + error = $"Unsupported PrimeTween generator tweenKind '{tweenKind}'. Supported values: Position, LocalPosition, EulerAngles, LocalEulerAngles, Scale. Use primetween_list_factories to inspect other PrimeTween APIs." + }; + } + + private static object TryValidateGeneratorInputs( + string ease, + string cycleMode, + int cycles, + string cycleModeTypeName = "PrimeTween.CycleMode") + { + if (cycles < -1) + { + return new { error = "cycles must be -1 (infinite) or a positive integer." }; + } + + if (!IsEnumValue("PrimeTween.Ease", ease)) + { + return new { error = $"Invalid PrimeTween Ease value '{ease}'. Use primetween_list_factories typeName=Tween to inspect available APIs." }; + } + + if (!IsEnumValue(cycleModeTypeName, cycleMode)) + { + return new { error = $"Invalid PrimeTween cycle mode '{cycleMode}'." }; + } + + return null; + } + + private static bool IsEnumValue(string typeName, string value) + { + var enumType = FindType(typeName); + return enumType != null && + enumType.IsEnum && + !string.IsNullOrWhiteSpace(value) && + Enum.GetNames(enumType).Any(name => string.Equals(name, value, StringComparison.OrdinalIgnoreCase)); + } + + private static List ParseSequenceSteps(string stepsJson, string tweenKind, float duration) + { + if (string.IsNullOrWhiteSpace(stepsJson)) + { + return new List + { + new SequenceStepInput { op = "Chain", tweenKind = tweenKind, duration = duration }, + new SequenceStepInput { op = "Group", tweenKind = "Scale", duration = duration }, + new SequenceStepInput { op = "Chain", tweenKind = tweenKind, duration = duration } + }; + } + + try + { + return JsonConvert.DeserializeObject>(stepsJson); + } + catch (JsonException) + { + return null; + } + } + + private static object WriteGeneratedScript(string className, string folder, string content) + { + if (string.IsNullOrWhiteSpace(className)) + { + return new { error = "className is required" }; + } + + if (!IsValidClassName(className)) + { + return new { error = "className must be a valid C# identifier and must not contain path separators." }; + } + + if (Validate.SafePath(folder, "folder") is object folderError) + { + return folderError; + } + + if (!Directory.Exists(folder)) + { + Directory.CreateDirectory(folder); + } + + var path = Path.Combine(folder, className + ".cs").Replace("\\", "/"); + if (File.Exists(path)) + { + return new { error = $"Script already exists: {path}" }; + } + + File.WriteAllText(path, content, SkillsCommon.Utf8NoBom); + AssetDatabase.ImportAsset(path); + var asset = AssetDatabase.LoadAssetAtPath(path); + if (asset != null) + { + WorkflowManager.SnapshotCreatedAsset(asset); + } + + return new + { + success = true, + path, + className, + nextAction = "Unity may start compiling. After compilation finishes, call script_get_compile_feedback if needed." + }; + } + + private static bool IsValidClassName(string className) + { + if (string.IsNullOrWhiteSpace(className) || + className.Contains("/") || + className.Contains("\\") || + className.Contains("..")) + { + return false; + } + + if (!char.IsLetter(className[0]) && className[0] != '_') + { + return false; + } + + return className.All(character => char.IsLetterOrDigit(character) || character == '_'); + } + + private static string BuildTweenScript( + string className, + string namespaceName, + TransformTweenSpec spec, + float duration, + string ease, + int cycles, + string cycleMode, + bool autoPlay) + { + var builder = CreateScriptHeader(className, namespaceName); + builder.AppendLine(" [SerializeField] private Transform _target;"); + builder.AppendLine($" [SerializeField] private Vector3 _{spec.FieldName} = {spec.DefaultValue};"); + builder.AppendLine($" [SerializeField] private float _duration = {FloatLiteral(duration)};"); + builder.AppendLine($" [SerializeField] private Ease _ease = Ease.{SanitizeEnumName(ease, "OutQuad")};"); + builder.AppendLine($" [SerializeField] private int _cycles = {NormalizeCycles(cycles)};"); + builder.AppendLine($" [SerializeField] private CycleMode _cycleMode = CycleMode.{SanitizeEnumName(cycleMode, "Restart")};"); + builder.AppendLine($" [SerializeField] private bool _autoPlay = {BoolLiteral(autoPlay)};"); + builder.AppendLine(); + builder.AppendLine(" private Tween _tween;"); + builder.AppendLine(); + builder.AppendLine(" private void Awake()"); + builder.AppendLine(" {"); + builder.AppendLine(" if (_target == null)"); + builder.AppendLine(" {"); + builder.AppendLine(" _target = transform;"); + builder.AppendLine(" }"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" private void OnEnable()"); + builder.AppendLine(" {"); + builder.AppendLine(" if (_autoPlay)"); + builder.AppendLine(" {"); + builder.AppendLine(" Play();"); + builder.AppendLine(" }"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" private void OnDisable()"); + builder.AppendLine(" {"); + builder.AppendLine(" Stop();"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" public void Play()"); + builder.AppendLine(" {"); + builder.AppendLine(" Stop();"); + builder.AppendLine(" if (_target == null)"); + builder.AppendLine(" {"); + builder.AppendLine(" return;"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine($" _tween = {BuildTweenCall(spec, "_duration", "_ease, _cycles, _cycleMode")};"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" public void Stop()"); + builder.AppendLine(" {"); + builder.AppendLine(" if (_tween.isAlive)"); + builder.AppendLine(" {"); + builder.AppendLine(" _tween.Stop();"); + builder.AppendLine(" }"); + builder.AppendLine(" }"); + CloseScript(builder, namespaceName); + return builder.ToString(); + } + + private static string BuildSequenceScript( + string className, + string namespaceName, + List steps, + string ease, + int cycles, + string sequenceCycleMode, + bool autoPlay) + { + var uniqueSpecs = steps + .Select(step => step.Tween) + .GroupBy(spec => spec.FieldName) + .Select(group => group.First()) + .ToArray(); + var builder = CreateScriptHeader(className, namespaceName); + builder.AppendLine(" [SerializeField] private Transform _target;"); + foreach (var spec in uniqueSpecs) + { + builder.AppendLine($" [SerializeField] private Vector3 _{spec.FieldName} = {spec.DefaultValue};"); + } + builder.AppendLine($" [SerializeField] private Ease _ease = Ease.{SanitizeEnumName(ease, "OutBack")};"); + builder.AppendLine($" [SerializeField] private int _cycles = {NormalizeCycles(cycles)};"); + builder.AppendLine($" [SerializeField] private Sequence.SequenceCycleMode _cycleMode = Sequence.SequenceCycleMode.{SanitizeEnumName(sequenceCycleMode, "Restart")};"); + builder.AppendLine($" [SerializeField] private bool _autoPlay = {BoolLiteral(autoPlay)};"); + builder.AppendLine(); + builder.AppendLine(" private Sequence _sequence;"); + builder.AppendLine(); + builder.AppendLine(" private void Awake()"); + builder.AppendLine(" {"); + builder.AppendLine(" if (_target == null)"); + builder.AppendLine(" {"); + builder.AppendLine(" _target = transform;"); + builder.AppendLine(" }"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" private void OnEnable()"); + builder.AppendLine(" {"); + builder.AppendLine(" if (_autoPlay)"); + builder.AppendLine(" {"); + builder.AppendLine(" Play();"); + builder.AppendLine(" }"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" private void OnDisable()"); + builder.AppendLine(" {"); + builder.AppendLine(" Stop();"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" public void Play()"); + builder.AppendLine(" {"); + builder.AppendLine(" Stop();"); + builder.AppendLine(" if (_target == null)"); + builder.AppendLine(" {"); + builder.AppendLine(" return;"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" _sequence = Sequence.Create(_cycles, _cycleMode, _ease);"); + foreach (var step in steps) + { + builder.AppendLine($" _sequence.{step.Operation}({BuildTweenCall(step.Tween, FloatLiteral(step.Duration), "_ease")});"); + } + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" public void Stop()"); + builder.AppendLine(" {"); + builder.AppendLine(" if (_sequence.isAlive)"); + builder.AppendLine(" {"); + builder.AppendLine(" _sequence.Stop();"); + builder.AppendLine(" }"); + builder.AppendLine(" }"); + CloseScript(builder, namespaceName); + return builder.ToString(); + } + + private static StringBuilder CreateScriptHeader(string className, string namespaceName) + { + var builder = new StringBuilder(); + builder.AppendLine("using PrimeTween;"); + builder.AppendLine("using UnityEngine;"); + builder.AppendLine(); + if (!string.IsNullOrWhiteSpace(namespaceName)) + { + builder.AppendLine($"namespace {namespaceName}"); + builder.AppendLine("{"); + } + builder.AppendLine($"public sealed class {className} : MonoBehaviour"); + builder.AppendLine("{"); + return builder; + } + + private static void CloseScript(StringBuilder builder, string namespaceName) + { + builder.AppendLine("}"); + if (!string.IsNullOrWhiteSpace(namespaceName)) + { + builder.AppendLine("}"); + } + } + + private static string FloatLiteral(float value) + { + return value.ToString("0.0#####", System.Globalization.CultureInfo.InvariantCulture) + "f"; + } + + private static string BoolLiteral(bool value) + { + return value ? "true" : "false"; + } + + private static string BuildTweenCall(TransformTweenSpec spec, string duration, string settings) + { + var arguments = spec.StartValueExpression == null + ? $"_target, _{spec.FieldName}, {duration}, {settings}" + : $"_target, {spec.StartValueExpression}, _{spec.FieldName}, {duration}, {settings}"; + return $"Tween.{spec.Method}({arguments})"; + } + + private static int NormalizeCycles(int cycles) + { + return cycles == -1 ? -1 : Mathf.Max(cycles, 1); + } + + private static string SanitizeEnumName(string value, string fallback) + { + if (string.IsNullOrWhiteSpace(value) || !value.All(character => char.IsLetterOrDigit(character) || character == '_')) + { + return fallback; + } + + return value; + } + } +} diff --git a/SkillsForUnity/Editor/Skills/UnitySkillAttribute.cs b/SkillsForUnity/Editor/Skills/UnitySkillAttribute.cs index 6e5876ec..119bdcb9 100644 --- a/SkillsForUnity/Editor/Skills/UnitySkillAttribute.cs +++ b/SkillsForUnity/Editor/Skills/UnitySkillAttribute.cs @@ -51,6 +51,7 @@ public enum SkillCategory Netcode, YooAsset, DOTween, + PrimeTween, Graphics, Volume, URP, diff --git a/SkillsForUnity/Tests/Editor/Core/SkillDocumentationConsistencyTests.cs b/SkillsForUnity/Tests/Editor/Core/SkillDocumentationConsistencyTests.cs index fc4b339d..422d1fc3 100644 --- a/SkillsForUnity/Tests/Editor/Core/SkillDocumentationConsistencyTests.cs +++ b/SkillsForUnity/Tests/Editor/Core/SkillDocumentationConsistencyTests.cs @@ -39,6 +39,7 @@ public class SkillDocumentationConsistencyTests // 统一豁免 schema-first(Exact Signatures)校验,避免误报。 "addressables-design", "dotween-design", + "primetween-design", "netcode-design", "unitask-design", "yooasset-design", diff --git a/SkillsForUnity/unity-skills~/SKILL.md b/SkillsForUnity/unity-skills~/SKILL.md index ef025a2d..83b083f7 100644 --- a/SkillsForUnity/unity-skills~/SKILL.md +++ b/SkillsForUnity/unity-skills~/SKILL.md @@ -12,7 +12,7 @@ Use this skill when the user wants to automate the Unity Editor through the loca The schema is the canonical source for exact skill names, parameters, defaults, and returns — **but you rarely need the expensive layers**. Route by task shape (all layers are server-cached with ETag/304 and served off the main thread): - **Intent is specific** ("create a cube", "set this SO field") → `GET /skills/recommend?intent=&topN=10&includeSchema=true` (~2-5 KB) returns scored candidates **with parameter schemas** — often the only lookup you need. If you already know the skill name, skip lookups entirely and go straight to the dryRun gate below. -- **Task touches one or two areas** → directory first: `GET /skills?brief=1` (~19 KB ≈ 3.4K tokens — all 733 skill names grouped by module, names are self-describing `module_verb`) to lock the module(s), then `GET /skills/schema?category=` (~13–44 KB) for exact signatures. Typical session cost ≈ 10K tokens instead of 35K. +- **Task touches one or two areas** → directory first: `GET /skills?brief=1` (~19 KB ≈ 3.4K tokens — all 771 skill names grouped by module, names are self-describing `module_verb`) to lock the module(s), then `GET /skills/schema?category=` (~13–44 KB) for exact signatures. Typical session cost ≈ 10K tokens instead of 35K. - **Exploratory / cross-module / unsure what exists** → full awareness: `GET /skills?summary=1` (~143 KB ≈ 35K tokens — every skill's full description). The only layer with all descriptions at once; reach for it when the cheaper layers left you unsure, **not by default**. - **Full detail (rare)**: `GET /skills/schema` — full schema with exact parameter schemas (~`618 KB` ≈ 150K tokens, client-cached 300s + disk-cached under `~/.unity_skills/cache/` with ETag/304 revalidation, so short-lived CLI processes reuse it too). Only when you need many modules' exact signatures at once. @@ -31,7 +31,7 @@ Python helper shortcuts: `unity_skills.search_skills("keyword")` greps the cache Use module `SKILL.md` files for routing guidance, guardrails, and minimal examples, not as the canonical source of exact signatures. -Current snapshot: `733` REST skills, `51` functional source modules, `69` module documentation directories (`49` REST/module docs + `20` advisory docs), Unity `2022.3+`, default timeout `15 minutes`. +Current snapshot: `771` REST skills, `52` functional source modules, `71` module documentation directories (`48` REST/module docs + `23` advisory docs), Unity `2022.3+`, default timeout `15 minutes`. Python helper: `unity-skills/scripts/unity_skills.py` @@ -115,7 +115,7 @@ Mode authorization (persistent, per-skill) and `ConfirmationToken` (single-shot, ### Skill Mode Annotation -The REST surface (`733` skills) is partitioned by `[UnitySkill]` `Mode` and runtime metadata. Use schema endpoints for the canonical list: +The REST surface (`771` skills) is partitioned by `[UnitySkill]` `Mode` and runtime metadata. Use schema endpoints for the canonical list: | Annotation | Count | Source | |---|---|---| diff --git a/SkillsForUnity/unity-skills~/skills/SKILL.md b/SkillsForUnity/unity-skills~/skills/SKILL.md index 3af03942..e383bbf9 100644 --- a/SkillsForUnity/unity-skills~/skills/SKILL.md +++ b/SkillsForUnity/unity-skills~/skills/SKILL.md @@ -71,6 +71,7 @@ Module docs. Start with [../SKILL.md](../SKILL.md) for mode switching and schema | [netcode](./netcode/SKILL.md) | Mixed* | Netcode for GameObjects setup, prefabs, lifecycle, host/server/client | Yes | | [yooasset](./yooasset/SKILL.md) | Mixed* | YooAsset hot-update: build bundles, Collector CRUD, BuildReport asset/dependency analysis, PlayMode runtime validation, Reporter/Debugger/AssetArtScanner tools | Yes | | [dotween](./dotween/SKILL.md) | Mixed* | DOTween Pro DOTweenAnimation editor-time configuration (add/batch/stagger/tune) | Yes | +| [primetween](./primetween/SKILL.md) | Mixed* | PrimeTween Free inspection, factory discovery, and runtime tween/sequence script generation | No | ## Advisory Design Modules @@ -96,6 +97,7 @@ These modules provide design guidance only. | [addressables-design](./addressables-design/SKILL.md) | Addressables dual-version (1.22.3 Unity 2022 / 2.9.1 Unity 6) source-anchored rules (init/handles/loading/scene/update/download/assetref/pitfalls) with migration table | | [unitask-design](./unitask-design/SKILL.md) | UniTask 2.5.10 source-anchored rules (basics/playerloop/cancellation/composition/conversion/asyncenumerable/triggers/pitfalls) | | [dotween-design](./dotween-design/SKILL.md) | DOTween 1.3.015 source-anchored rules (basics/tween/sequence/shortcuts/ease/lifetime/integration/pitfalls) | +| [primetween-design](./primetween-design/SKILL.md) | PrimeTween 1.4.6 source-anchored rules (factories/handles/sequences/cycles/callbacks/lifetime/integration) | | [shadergraph-design](./shadergraph-design/SKILL.md) | ShaderGraph dual-version source-anchored rules (versions/node subset/recipes/pitfalls/review) | | [yaml-editing](./yaml-editing/SKILL.md) | Safe hand-edit rules for serialized YAML (.unity/.prefab/.asset/.meta/ProjectSettings) when REST cannot reach — reference/fileID repair, .meta/GUID safety, ProjectSettings patch, merge conflict | diff --git a/SkillsForUnity/unity-skills~/skills/primetween-design/SKILL.md b/SkillsForUnity/unity-skills~/skills/primetween-design/SKILL.md new file mode 100644 index 00000000..583eee4a --- /dev/null +++ b/SkillsForUnity/unity-skills~/skills/primetween-design/SKILL.md @@ -0,0 +1,44 @@ +--- +name: unity-primetween-design +description: Source-anchored design rules for PrimeTween 1.4.6 — factory tweens, non-reusable handles, sequences, cycles, callbacks, cancellation, async/coroutine waiting, and configuration. Use when writing or reviewing PrimeTween animation code or diagnosing its lifecycle behavior. +--- + +# PrimeTween - Design Rules + +Advisory module. Rules are grounded in the PrimeTween **1.4.6** package installed through `com.kyrylokuzyk.primetween`. + +> **Mode**: Documentation only — no REST skills to gate; load freely under any operating mode. + +## When to Load This Module + +Load before writing or reviewing: + +- `Tween.Position`, `LocalPosition`, `EulerAngles`, `LocalEulerAngles`, `Scale`, `Alpha`, `Color`, `Custom`, delay, or shake calls. +- `Sequence.Create`, `Chain`, `Group`, `Insert`, callbacks, or sequence cycles. +- `Tween.Stop`, `Complete`, `StopAll`, `CompleteAll`, `PausedAll`, progress, time scale, or manual update control. +- `OnComplete`, `OnUpdate`, zero-allocation callback overloads, or target-destruction handling. +- `await tween`, `ToYieldInstruction`, serialized `TweenSettings`, `PrimeTweenConfig`, or capacity tuning. + +## Critical Rule Summary + +| # | Rule | Source anchor | +|---|------|---------------| +| 1 | PrimeTween uses static `Tween` factories. Its `Tween` handle is a struct, and a completed or stopped handle is dead and non-reusable; create a new tween to replay or reverse an animation. | `Runtime/Tween.cs:53,256-264`; `readme.md` “Controlling tweens” | +| 2 | Use `Sequence.Chain` for sequential work, `Group` for parallel work against the previous item, and `Insert` for absolute-time overlap. This naming differs from DOTween’s Append/Join vocabulary. | `Runtime/Sequence.cs:154,193,202` | +| 3 | A `Sequence` has its own cycles, cycle mode, easing, update type, and unscaled-time settings at creation. Configure those on `Sequence.Create`, not through DOTween-style fluent setters. | `Runtime/Sequence.cs:108` | +| 4 | Callbacks can bind a target explicitly with `OnComplete` or sequence callback overloads. That avoids a capturing closure and lets PrimeTween suppress the callback if its target is destroyed. | `Runtime/Tween.cs:365-382`; `Runtime/Sequence.cs:228-281` | +| 5 | PrimeTween detects destroyed Unity targets and exposes targeted warnings through `PrimeTweenConfig`. Do not assume a DOTween `SetLink` API exists; own a handle and stop it when your component is disabled when that is the intended lifecycle. | `Runtime/Internal/PrimeTweenManager.cs:870-880`; `Runtime/PrimeTweenConfig.cs:56-87` | +| 6 | `await tween` and `ToYieldInstruction()` are supported, but both async state machines and coroutines allocate. For allocation-sensitive animation flows, prefer `Sequence`. | `Runtime/Internal/AsyncAwaitSupport.cs`; `Runtime/Internal/CoroutinesSupport.cs`; `readme.md` “Async/await” | +| 7 | `TweenSettings` and `TweenSettings` are serializable configuration carriers for Inspector-authored tween values; use them instead of inventing a separate animation settings component. | `Runtime/TweenSettings.cs:25-54`; `readme.md` “Inspector integration” | +| 8 | `PrimeTweenConfig` is static runtime configuration. It has capacity, default ease/update type, warning controls, and manual-update APIs, but it is not a `Resources` settings asset. | `Runtime/PrimeTweenConfig.cs:25-101` | + +## Routing to Other Modules + +- Async control flow or cancellation policy → load [async](../async/SKILL.md) and [unitask-design](../unitask-design/SKILL.md). +- Inspector-authored `TweenSettings` fields → load [inspector](../inspector/SKILL.md). +- Tween-heavy performance analysis → load [performance](../performance/SKILL.md). +- Addressables-loaded targets or scene lifetime → load [addressables-design](../addressables-design/SKILL.md). + +## Version Scope + +This module targets PrimeTween **1.4.6**. Its UPM package supports Unity 2018.4+, but Unity Skills itself maintains a Unity 2022.3+ baseline. Check the installed package version before relying on a newer factory overload or PrimeTween Pro feature. diff --git a/SkillsForUnity/unity-skills~/skills/primetween/SKILL.md b/SkillsForUnity/unity-skills~/skills/primetween/SKILL.md new file mode 100644 index 00000000..fbe449a7 --- /dev/null +++ b/SkillsForUnity/unity-skills~/skills/primetween/SKILL.md @@ -0,0 +1,49 @@ +--- +name: unity-primetween +description: Inspect PrimeTween Free, discover its public animation factories, and generate lifecycle-aware PrimeTween runtime scripts. Use when checking a PrimeTween installation, exploring supported animation APIs, or generating Transform/Sequence animation code. +--- + +# PrimeTween Skills + +PrimeTween Free support is intentionally tailored to its API rather than mirroring DOTween: it discovers static factories, reads process-wide configuration, and generates runtime scripts that own and stop their `Tween` or `Sequence` handles. It does not configure a DOTween-style settings asset or create PrimeTween Pro components. + +## Guardrails + +- PrimeTween must be installed as `com.kyrylokuzyk.primetween`. +- Query skills run directly in all operating modes. Script generators create a C# asset and can trigger compilation, so they are high-risk and require Bypass or an Allowlist entry in Auto/Approval modes. +- `primetween_get_config` is read-only. `PrimeTweenConfig` is runtime state, not a serialized project configuration asset. +- Generated scripts support Transform `Position`, `LocalPosition`, `EulerAngles`, `LocalEulerAngles`, and `Scale`. Use `primetween_list_factories` before requesting an API outside that supported generator set. +- PrimeTween handles are non-reusable. Generated scripts stop their owned live handle on disable instead of using a DOTween `SetLink` equivalent. + +## Free Skills + +### `primetween_get_status` +Report whether PrimeTween is installed, its package version, assembly, and visible core types. + +**Parameters:** None. + +### `primetween_get_config` +Read the current global runtime values exposed by `PrimeTweenConfig`. + +**Parameters:** None. + +### `primetween_list_factories` +List public static methods from one PrimeTween API type. + +**Parameters:** `typeName="Tween"` (`Tween`, `Sequence`, `Shake`, or `PrimeTweenConfig`), `methodPrefix?`, `limit=100`. + +### `primetween_generate_tween_script` +Create a Transform-focused PrimeTween MonoBehaviour that owns its `Tween` and stops it on disable. + +**Parameters:** `className`, `folder="Assets/Scripts/PrimeTween"`, `namespaceName?`, `tweenKind="LocalPosition"`, `duration=1`, `ease="OutQuad"`, `cycles=1`, `cycleMode="Restart"`, `autoPlay=true`. + +### `primetween_generate_sequence_script` +Create a PrimeTween MonoBehaviour that uses `Sequence.Chain` and `Sequence.Group` with supported Transform tween factories. + +**Parameters:** `className`, `folder="Assets/Scripts/PrimeTween"`, `namespaceName?`, `tweenKind="Scale"`, `duration=0.2`, `ease="OutBack"`, `cycles=1`, `sequenceCycleMode="Restart"`, `autoPlay=true`, `stepsJson?`. + +`stepsJson` is a JSON array of `{ "op": "Chain|Group", "tweenKind": "Scale", "duration": 0.2 }`. + +## Exact Signatures + +Exact names, parameters, defaults, and return values are defined by `GET /skills/schema` or `unity_skills.get_skill_schema()`, not by this file. diff --git a/agent.md b/agent.md index 729a6387..c3f070aa 100644 --- a/agent.md +++ b/agent.md @@ -3,7 +3,7 @@ > **本文件面向"开发这个项目的 AI"**,非"调用该项目 REST API 的 AI"。 > 后者请读 `SkillsForUnity/unity-skills~/SKILL.md`。 -通过 REST API 让 AI 直接控制 Unity 编辑器。733 个 REST Skills + 20 个 Advisory 模块。 +通过 REST API 让 AI 直接控制 Unity 编辑器。771 个 REST Skills + 23 个 Advisory 模块。 | 项目 | 值 | |------|----| @@ -24,7 +24,7 @@ AI Agent ──HTTP──▶ unity_skills.py ──POST localhost:8090-8100─ │ SkillRouter (反射发现 [UnitySkill]) │ - 51 个 *Skills.cs (733 Skills) + 52 个 *Skills.cs (771 Skills) │ WorkflowManager (持久化撤销/回滚) RegistryService (多实例发现) @@ -57,7 +57,7 @@ Unity-Skills/ │ │ │ ├── GameObjectFinder.cs # 统一查找器 (name/instanceId/path) │ │ │ ├── BatchExecutor.cs # 批量操作框架 │ │ │ ├── SkillInstaller.cs # AI 工具一键安装 -│ │ │ └── *Skills.cs × 51 # 功能模块 (共 733 Skills) +│ │ │ └── *Skills.cs × 52 # 功能模块 (共 771 Skills) │ │ └── UI/ # Editor UI (USS + UXML + EditorWindow) │ │ ├── UnitySkillsWindow.{cs,uxml,uss} # 主窗口 │ │ ├── AuditLogWindow.{uxml,uss} # 审计窗口 @@ -66,7 +66,7 @@ Unity-Skills/ │ └── unity-skills~/ # AI Skill 模板(波浪线隐藏,随包分发) │ ├── SKILL.md # 调用方文档("用"项目) │ ├── scripts/unity_skills.py -│ ├── skills/ # 69 个模块文档 (49 REST + 20 advisory) +│ ├── skills/ # 71 个模块文档 (48 REST + 23 advisory) │ └── references/ ├── .claude/commands/ # 自定义命令 ├── docs/SETUP_GUIDE.md @@ -168,7 +168,7 @@ public static object SkillName(string name, float x = 0f) { ... } --- -## Skills 模块 (51 个功能模块, 733 Skills) +## Skills 模块 (52 个功能模块, 771 Skills) | 模块 | 数量 | 模块 | 数量 | 模块 | 数量 | |------|:----:|------|:----:|------|:----:| @@ -176,24 +176,25 @@ public static object SkillName(string name, float x = 0f) { ... } | UI | 29 | UIToolkit | 25 | ShaderGraph | 23 | | Workflow | 23 | ProBuilder* | 22 | XR* | 22 | | Batch | 22 | DOTween* | 21 | Material | 21 | -| PostProcess† | 10 | GameObject | 19 | Perception | 18 | -| Volume† | 9 | URP† | 7 | Decal† | 7 | -| Test | 13 | Editor | 14 | Script | 12 | -| Timeline | 12 | Physics | 12 | Asset | 11 | -| AssetImport | 11 | Camera | 12 | Package | 11 | -| Prefab | 11 | Shader | 11 | Graphics | 11 | -| Animator | 10 | Audio | 10 | Cleaner | 10 | -| Component | 14 | Console | 10 | Debug | 10 | -| Event | 11 | Light | 10 | Model | 10 | -| NavMesh | 10 | Optimization | 10 | Profiler | 10 | -| Scene | 10 | ScriptableObject | 13 | Smart | 10 | -| Terrain | 10 | Texture | 10 | Validation | 10 | -| Project | 10 | Sample | 8 | Diagnose | 1 | - -\*ProBuilder 需 `com.unity.probuilder`,XR 需 `com.unity.xr.interaction.toolkit`,Netcode 需 `com.unity.netcode.gameobjects`,YooAsset 需 `com.tuyoogame.yooasset (≥2.3.15)`,DOTween 需 `DG.Tweening` +| PrimeTween* | 5 | PostProcess† | 10 | GameObject | 19 | +| Perception | 18 | Volume† | 9 | URP† | 7 | +| Decal† | 7 | Test | 13 | Editor | 14 | +| Script | 12 | Timeline | 12 | Physics | 12 | +| Asset | 11 | AssetImport | 11 | Camera | 12 | +| Package | 11 | Prefab | 11 | Shader | 11 | +| Graphics | 11 | Animator | 10 | Audio | 10 | +| Cleaner | 10 | Component | 14 | Console | 10 | +| Debug | 10 | Event | 11 | Light | 10 | +| Model | 10 | NavMesh | 10 | Optimization | 10 | +| Profiler | 10 | Scene | 10 | ScriptableObject | 13 | +| Smart | 10 | Terrain | 10 | Texture | 10 | +| Validation | 10 | Project | 10 | Sample | 8 | +| Diagnose | 1 | | | | + +\*ProBuilder 需 `com.unity.probuilder`,XR 需 `com.unity.xr.interaction.toolkit`,Netcode 需 `com.unity.netcode.gameobjects`,YooAsset 需 `com.tuyoogame.yooasset (≥2.3.15)`,DOTween 需 `DG.Tweening`,PrimeTween 需 `com.kyrylokuzyk.primetween` †Volume / PostProcess / Decal / URP 需 `com.unity.render-pipelines.universal`(URP 未安装时这 4 个模块以同名 stub 返回 `NoURP()` 提示)。 -**Advisory 模块 (20)**:architecture, patterns, performance, asmdef, async, inspector, blueprints, adr, project-scout, scene-contracts, script-roles, scriptdesign, testability, netcode-design, yooasset-design, addressables-design, unitask-design, dotween-design, shadergraph-design, yaml-editing — **纯架构/设计指导文档,无 REST Skills,无 C# 实现**;新增 advisory 时只动 `unity-skills~/skills/` 下文档,不要在 Editor/Skills/ 加 stub。 +**Advisory 模块 (23)**:architecture, patterns, performance, asmdef, async, inspector, blueprints, adr, project-scout, scene-contracts, script-roles, scriptdesign, testability, bookmark, history, netcode-design, yooasset-design, addressables-design, unitask-design, dotween-design, primetween-design, shadergraph-design, yaml-editing — **纯架构/设计指导文档,无 REST Skills,无 C# 实现**;新增 advisory 时只动 `unity-skills~/skills/` 下文档,不要在 Editor/Skills/ 加 stub。 --- diff --git a/docs/SETUP_GUIDE.md b/docs/SETUP_GUIDE.md index 73009489..9f011ac5 100644 --- a/docs/SETUP_GUIDE.md +++ b/docs/SETUP_GUIDE.md @@ -68,7 +68,7 @@ Select your AI tool and click **Install**. The installer copies the `unity-skill ``` SKILL.md # Main skill definition (AI reads this) -skills/ # Per-module skill docs (49 functional + 20 advisory) +skills/ # Per-module skill docs (48 REST/module + 23 advisory) scripts/unity_skills.py # Python client library scripts/agent_config.json # Agent configuration references/ # Unity development references