☰
Godot AI插件开发:从骨架、请求链路到安全落地
2026/11/2 7:54:11 网站建设 项目流程

1. 先把问题想清楚:Godot AI 插件到底补的是哪块短板

我自己用 Godot 做项目有几年了,最烦的从来不是"不会写",而是那些机械重复又必须精确的活儿:一个 UI 面板二十个节点要按规范改名、一批脚本要补统一格式的注释头、几十个道具的 description 字段要从 Excel 里转成 Resource 文件。这些事有技术含量吗?没有。但做错一个字符,运行时就是 null 引用。

Godot AI 插件这个概念,说白了就是把这些"有脑子但不需要创造力的活"外包给模型,然后在编辑器里直接把结果落回项目文件。它不是在游戏里跑 AI NPC 那种运行时智能,而是编辑器内智能——你在 Godot 编辑器右侧多出一个面板,选中一段代码或者一个节点,说人话让它干活,结果以 diff 的形式给你确认,确认完直接写盘。

这个东西能解决三件事:一是模板化产出,比如按命名规范批量重命名节点、按项目风格生成脚本骨架;二是局部理解,比如选中一个 200 行的脚本,问它"这个_physics_process里为什么会抖动",它会结合上下文给你分析;三是跨格式转换,策划给的表格转成.tres,散落的文本转成.csv本地化表。

适合谁看?我的判断是分三档。第一档是刚上手 Godot、还在熟悉Node和Scene概念的开发者,插件能帮你把"这个场景该怎么搭"的疑问快速变成可运行的验证代码;第二档是有一定经验、能自己写@tool脚本的中级开发者,这是最划算的人群,因为你知道哪些东西不能让它碰;第三档是独立开发者或小团队,一个人负责全流程,最缺的就是"第二双手"。

需要提前说明一句:这篇内容里所有接口调用、密钥管理、代码落地方式,都是基于通用实践做的设计说明,你自己接的服务、选的模型、用的版本号肯定和我写的不完全一样,思路照搬、细节自己调。别指望复制粘贴就能跑,那样反而容易出事。

2. 三步走的设计取舍:为什么是这个架构

2.1 为什么把"三步"拆成骨架、链路、落地

很多人在做编辑器插件时容易犯一个错:一上来就写请求函数,跑通了很开心,然后发现结果没地方放。要么手动复制粘贴,要么写了个半成品把项目文件覆盖了,还没法撤销。这一步步踩下去,热情消耗得比进度快。

我把整个插件拆成三步,本质上对应三个风险等级:

步骤核心目标风险等级失败后果
第一步:立骨架插件能加载、面板能显示极低编辑器报错,删掉目录即可恢复
第二步:通链路请求能发出、结果能拿回中报错、超时、花钱,不影响项目文件
第三步:落到活结果安全写回项目高可能污染资源,需要有回滚机制

这个顺序不能乱。先把骨架立起来,你每次改代码都能在编辑器里立刻看到面板变化,反馈周期短,调试成本低。链路那一步可以慢慢磨,反正最坏情况也就是弹个错误提示。落地这一步才需要如临大敌,因为它真的会动文件。

从我自己的经验看,绝大多数人卡在第二步的异步和鉴权上,然后第三步的安全写入是最容易被忽略、也最容易出事的。所以这篇的重点会放在这两块。

2.2 为什么选编辑器插件而不是外部工具

有人会问,我直接用编辑器外的对话窗口,复制粘贴代码不好吗?也能干。但体验差三个档次:

第一是上下文收集成本。在外部窗口里,你得手动复制相关脚本、说明项目结构、描述节点层级,一篇文章写下来比写代码还累。做成插件以后,这些上下文由编辑器 API 自动抓取,EditorInterface.get_script_editor().get_current_script()一行就能拿到当前打开的脚本,get_edited_scene_root()拿到当前场景根节点,你只需要补充"想干什么"。

第二是结果回流成本。外部窗口给你一段代码,你得自己找位置、自己缩进、自己检查语法。插件可以在内存里先做语法校验,通过了才允许写盘,写盘前还能给你看 diff。

第三是一致性。项目里可能有五个人,命名习惯各不一样。插件可以在系统提示词里固定编码规范,让输出永远是同一个风格。这一点在团队协作里价值非常大,比"生成速度快"重要得多。

2.3 技术选型的三个关键决定

决定一:用EditorPlugin+ Dock 面板,而不是独立的EditorScript。EditorScript是一次性执行的东西,跑完就没了,做不成常驻工具。EditorPlugin有完整的生命周期,_enter_tree里挂面板、_exit_tree里清理,还能监听编辑器信号(比如文件保存、场景切换)。面板本身用Control写,@tool标注,能实时响应。

决定二:用HTTPRequest节点做请求,而不是HTTPClient手动轮询。HTTPRequest是引擎封装的便捷节点,一次request()调用,request_completed信号回来,代码量少,错误处理清晰。代价是它不支持流式输出——必须等整个响应体收完才回调。这个代价在编辑器场景里几乎无感,因为一般就是几百个 token 的事儿。但如果你要做"边生成边显示",那确实得换HTTPClient手动处理分块,代码量翻三倍,我个人不建议一开始就上。

决定三:把模型调用封装在一个单例服务里,而不是散落在面板脚本中。面板脚本负责 UI,服务脚本负责请求、重试、缓存、成本统计。这样以后想换服务、想加本地模型、想加缓存,只改一处。这个分层在项目变大以后会救命。

3. 第一步:半小时把插件骨架立稳

3.1 目录结构与plugin.cfg的最小写法

Godot 的插件规范很明确:所有插件代码必须放在res://addons/下,每个插件一个独立目录,根目录里有plugin.cfg描述文件。这个约定不是可选的,plugin.cfg缺失的话,项目设置里的插件列表根本不会出现你的条目。

我习惯的目录长这样:

[plugin] name="AI Copilot Lite" description="在编辑器内调用模型,做代码补全、节点批量重命名、注释生成" author="某开发者" version="0.1.0" script="ai_copilot.gd"

对应的文件布局:

res://addons/ai_copilot/ ├── plugin.cfg # 插件描述,Godot 靠它识别插件 ├── ai_copilot.gd # EditorPlugin 主脚本 ├── ui/ │ ├── dock.tscn # 面板场景 │ └── dock.gd # 面板逻辑,@tool ├── core/ │ ├── ai_client.gd # 请求封装,单例 │ └── prompt_tpl.gd # 提示词模板 └── icons/ └── icon.svg # 面板图标,16x16 即可

description那一行别糊弄,它在项目设置的插件列表里会显示出来,团队里别人看到就知道这插件干什么的。version建议用语义化版本,改了什么在提交说明里对应一下,后面排查问题方便。

注意:plugin.cfg的script字段路径是相对于插件目录的,不是res://开头。写成res://addons/...会导致插件加载失败,而且报错信息不明显,很多人卡在这里。

3.2EditorPlugin生命周期里必须做的三件事

主脚本继承EditorPlugin,必须带@tool标注,否则编辑器里不会执行。核心是_enter_tree和_exit_tree这一对:

@tool extends EditorPlugin const DockScene := preload("res://addons/ai_copilot/ui/dock.tscn") var _dock: Control func _enter_tree() -> void: _dock = DockScene.instantiate() add_control_to_dock(DOCK_SLOT_RIGHT_UL, _dock) func _exit_tree() -> void: if is_instance_valid(_dock): remove_control_from_docks(_dock) _dock.queue_free() _dock = null

三件事:创建面板、挂到 Dock、退出时清理。第三件最容易被忘。忘了会怎样?你在项目设置里禁用插件,面板还挂在那儿,点一下报一堆空引用错误,重启编辑器才恢复。_exit_tree里必须remove_control_from_docks再queue_free,顺序不能反,反了会残留一个空壳控件在 Dock 上。

DOCK_SLOT_RIGHT_UL是右上角位置,RIGHT_BL是右下角。我一般放右上,因为检查器和场景树都在右边,操作路径短。你的面板宽度别做太宽,超过 320 像素会挤压场景树,用户会烦。

3.3 面板脚本的@tool陷阱

面板脚本继承Control,同样要@tool。这里有个非常经典的坑:@tool脚本在编辑器里运行,_ready会执行,但_process也在跑。如果你在_process里做轮询、读文件、算东西,编辑器会持续掉帧,项目一大就卡得没法用。

我的做法是:面板里不写_process。所有更新都由信号驱动。按钮按下、请求回调、编辑器信号,这三类事件足够覆盖所有场景。确实需要定时刷新的东西(比如请求耗时计时器),用Timer节点,wait_time设成 1.0,one_shot = false,只在请求进行中start(),请求结束stop()。这样空闲时零开销。

还有一个坑:@tool脚本里访问EditorInterface有版本差异。4.2 之后EditorInterface是全局可用的单例,直接写名字就行;4.0 和 4.1 得用get_editor_interface()。如果你要兼容多个版本,包一层:

func _get_editor() -> EditorInterface: # 4.2+ 直接可用;旧版本走方法调用 return EditorInterface if Engine.has_singleton("EditorInterface") else get_editor_interface()

实际写的时候优先用新 API,plugin.cfg里version注明最低支持版本,别为了兼容老版本把代码写得全是判断。

4. 第二步:把请求链路打通,密钥、超时、提示词一个都不能马虎

4.1 密钥怎么存才不算自找麻烦

这一块必须先说,因为它是安全事故的高发区。我见过不止一个插件把 API Key 硬编码在脚本里,然后项目传到公开仓库,第二天收到账单。

正确的做法分三层:

第一层,优先读环境变量。OS.get_environment("AI_COPILOT_KEY"),本地开发时在启动脚本或系统环境里设置,代码里永远不出现明文。这个方式在 CI 和多人协作里最干净。

第二层,编辑器设置存储。EditorSettings支持项目级和全局级设置,可以把 Key 存进EditorSettings的项目配置,但要注意这个值会写进project.godot或者.godot/editor_settings-4.tres,前者会进版本库,后者不会。所以我只往全局设置写,不往项目设置写。

第三层,用户目录下的私有文件。存在user://ai_copilot.cfg里,用ConfigFile读写。这个路径在系统用户目录下,天然不进版本库。缺点是换机器要重新填,但这反而是好事。

# core/ai_client.gd 片段 const KEY_ENV := "AI_COPILOT_KEY" const CFG_PATH := "user://ai_copilot.cfg" func _load_key() -> String: var env_key := OS.get_environment(KEY_ENV) if not env_key.is_empty(): return env_key var cfg := ConfigFile.new() if cfg.load(CFG_PATH) != OK: return "" return cfg.get_value("auth", "key", "")

然后在输入框里做一次"记住密钥"的勾选,勾了就写ConfigFile,不勾就只存在内存里,关掉编辑器就没了。这个交互细节看着小,实际用起来很关键——共享机器上不勾,自己的机器上勾上,两头都照顾到。

注意:面板上的密钥输入框一定要设secret = true,否则录屏、开会投屏的时候,那一串字符就明晃晃摆在屏幕上。

4.2 请求封装:一次request()要处理几种失败

HTTPRequest的调用很直白,但失败路径比想象中多。我把它们归成四类,每一类都要有独立的提示文案,否则用户看到"请求失败"四个字完全不知道该改什么。

func ask(prompt: String, context: String, on_ok: Callable, on_err: Callable) -> void: var payload := { "model": _model_name, "messages": [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": context + "\n\n---\n\n" + prompt} ], "temperature": 0.3, "max_tokens": 800 } var headers := PackedStringArray([ "Content-Type: application/json", "Authorization: Bearer " + _key ]) var err := _http.request(ENDPOINT, headers, HTTPClient.METHOD_POST, JSON.stringify(payload)) if err != OK: on_err.call("请求发起失败,错误码 %d,先检查地址格式和网络状态" % err) return _pending_ok = on_ok _pending_err = on_err

回调这一侧:

func _on_request_done(result: int, code: int, _headers: PackedStringArray, body: PackedByteArray) -> void: if result != HTTPRequest.RESULT_SUCCESS: _pending_err.call("网络层异常,结果码 %d。常见原因:超时、DNS 解析失败、证书校验不通过" % result) return var text := body.get_string_from_utf8() if code == 401 or code == 403: _pending_err.call("鉴权未通过,检查密钥是否正确、是否过期") return if code == 429: _pending_err.call("触发频率限制,等几秒再试,或降低并发") return if code >= 400: _pending_err.call("服务返回 %d:%s" % [code, text.left(200)]) return var parsed = JSON.parse_string(text) if parsed == null: _pending_err.call("响应不是合法 JSON,前 200 字符:" + text.left(200)) return _pending_ok.call(_extract_content(parsed))

参数上几个关键点。timeout我设 45 秒,因为代码生成类请求的输出往往比闲聊长,30 秒经常不够。temperature设 0.3,代码任务不需要创造力,低温度让输出更稳定、更少幻觉。max_tokens设 800 是成本控制的硬闸门,很多人忘了设,结果模型一口气输出三千字然后把你的余额吃光。

4.3 提示词模板:决定成败的不是模型,是这段文字

这一点我特别想说,因为我见过太多人抱怨"模型生成的 GDScript 全是错的",一问提示词就一句"帮我写一个角色控制器"。这不是模型不行,是你没告诉它规则。

系统提示词里我固定这几段内容,效果立竿见影:

角色锚定。第一句明确"你是一个 Godot 4.x 的 GDScript 专家,只输出 GDScript 代码,不要输出解释文字、不要输出 Markdown 代码围栏"。最后那句特别重要,模型默认爱加 ``` 包裹,写进.gd文件直接语法错误。让它别加,你就不用写正则去剥。

版本与 API 约束。明确写出目标版本,比如"面向 Godot 4.3,使用@export、signal、await语法,不使用 Godot 3 的yield、export、onready写法"。这个信息不给,模型有相当概率给你混入 3.x 语法,因为它训练数据里 3.x 占比不小。我实测过,加上这一句,语法错误率能下去一大截。

项目约定。这一段是团队价值的核心。比如"节点命名使用 PascalCase,脚本文件使用 snake_case,私有成员以下划线开头,所有公共方法必须有##文档注释"。写进提示词以后,生成的东西和团队风格一致,评审时不用来回改。

输出格式契约。明确"只输出完整可运行的单个文件内容,不要省略号,不要 '此处省略',不要写 TODO"。这一条能避免最尴尬的情况:生成了一段带省略号的代码,你还得自己补。

模板化以后,用户只需要填"要干什么",规则部分自动拼上:

const SYSTEM_PROMPT := """你是 Godot 4.3 的 GDScript 专家。 规则: 1. 只输出 GDScript 源码,不加 Markdown 围栏,不加任何解释。 2. 使用 Godot 4 语法:@export / signal / await,禁止 yield 和 onready。 3. 节点命名 PascalCase,脚本文件 snake_case,私有成员前缀下划线。 4. 公共方法必须带 ## 文档注释。 5. 不得输出省略号或 TODO 占位。 """

心得:提示词改一次,效果变一次,所以要留版本记录。我在prompt_tpl.gd里用常量加注释日期,改了什么、为什么改,都写清楚。不然三个月后你根本不知道当初为什么加那一句。

4.4 上下文怎么塞进去才不会超预算

上下文不是越多越好。塞一整个项目的源码进去,token 账单会教你做人,而且模型在长上下文里对关键信息的注意力会下降。

我的策略是精确选取 + 分级裁剪:

  • 一级上下文(必带):当前选中或当前打开的脚本内容,超过 400 行就截断到前 400 行加尾部 50 行,中间用注释标记# ... 中间省略 N 行 ...。这个标记本身也是给模型的信号,让它知道这里不完整。
  • 二级上下文(按需):当前编辑场景的节点树结构,只给节点名和类型,深度限制 3 层。用get_edited_scene_root()递归遍历,拼成缩进文本。
  • 三级上下文(用户手动勾选):项目里其他相关脚本。面板上做一个文件选择器,用户自己挑。

这样一次请求的输入基本控制在 2000 token 以内,成本可控,响应也快。

5. 第三步:让生成结果安全落地,这是最容易出事的一步

5.1 写盘之前必须先过语法检查

这一条我要加重强调:绝对不能把模型输出直接写进res://。模型有概率输出语法错误、有概率输出半截、有概率输出带 Markdown 围栏的文本。直接写盘,项目里就多一个解析失败的脚本,而且 Godot 的脚本解析错误会在加载时打断整个场景,排查起来很难定位。

正确的顺序是:拿到文本 → 清洗 → 内存校验 → 预览 → 用户确认 → 写盘。

清洗很简单,去掉首尾的 ``` 围栏和语言标识行。校验用GDScript类在内存里编译:

func _validate_gdscript(source: String) -> String: var probe := GDScript.new() probe.source_code = source var err := probe.reload() if err != OK: return "语法校验未通过(错误码 %d),已阻止写入" % err return ""

reload()返回Error,非OK就是有问题。这个方法在编辑器环境里好用,因为它不依赖文件系统,纯内存编译。

但说实话,这个方法有局限:它只能告诉你"有错",不告诉你"错在哪一行"。想要更精确的报错,可以用命令行兜底:

godot --headless --check-only --script res://addons/ai_copilot/tmp_draft.gd

先把草稿写到一个临时路径,跑一遍检查,退出码非 0 就丢弃。这个方案慢一点(要起一个新进程),但报错信息完整,适合在"写入正式文件"这最后一道关卡上做。我的做法是内存校验做第一道,命令行检查做可选的第二道,用户在设置里开关。

5.2 diff 预览:让人做最后一道判断

校验只能保证语法对不对,保证不了逻辑对不对。模型可能给你一个语法完美但把_process写成死循环的实现。所以用户确认这一步不能省。

我的面板设计是:生成结果进右侧预览区,同时和当前文件做一个行级 diff,新增行绿底、删除行红底,用户扫一眼就知道改了什么。diff 算法不用自己写,用最朴素的逐行比对就够了——代码生成场景下改动通常很集中,简单的"最长公共子序列"实现百来行代码,或者干脆用"前后各 3 行不变、中间整段替换"的粗粒度方案,可读性反而更好。

确认按钮分两种:覆盖当前文件和另存为新文件。后者在生成新脚本时用。覆盖前自动备份一份到user://ai_backup/下,文件名带时间戳。这个备份功能看着不起眼,但救我过至少两次——一次是模型把整个文件重写了一遍,删掉了我一个关键函数,靠备份直接还原。

5.3 节点批量重命名:一个真正能立刻见效的场景

前面说的都是骨架和链路,这里给一个当天就能用起来的具体场景,让你感受到插件的实际价值。

需求:一个 UI 场景里有二十几个节点,名字是Label2、TextureRect5、Button12这种自动编号,完全没法维护。你想按规范重命名成TitleLabel、IconTexture、ConfirmButton这种语义化名字。

手工干要半小时,而且容易点错。用插件干:

第一步,拿到场景树结构。上面说的二级上下文,只给名字和类型。

第二步,提示词写"根据节点类型和在树中的层级,为每个节点生成一个语义化的 PascalCase 名字,保持唯一性,输出 JSON 数组,每项包含path和new_name"。

第三步,解析 JSON,逐个调用Node.name = new_name。这里要注意:改名操作必须包裹在EditorInterface的撤销事务里,否则用户按 Ctrl+Z 撤不回来,这是致命体验问题。

func _rename_nodes(root: Node, mapping: Dictionary) -> void: var undo := get_undo_redo() undo.create_action("AI 批量重命名节点") for path in mapping.keys(): var node := root.get_node_or_null(path) if node == null: continue undo.add_do_property(node, "name", mapping[path]) undo.add_undo_property(node, "name", node.name) undo.commit_action()

get_undo_redo()是EditorPlugin提供的方法,create_action/add_do_property/add_undo_property/commit_action这四步是标准流程。加上以后,用户按一次 Ctrl+Z 全部回滚,体验完全不一样。

6. 常见问题与排查实录

6.1 一张速查表覆盖八成故障

现象最可能的原因排查动作
插件列表里看不到条目plugin.cfg格式错误或script路径写成res://检查 INI 段落是否为[plugin],script只写相对路径
面板显示但一片空白面板脚本缺@tool,或_ready里用了编辑器不支持的方法加@tool,把可疑逻辑挪到_enter_tree之后
禁用插件后报空引用_exit_tree没清理 Dock 控件补remove_control_from_docks+queue_free
请求永远不回调HTTPRequest没add_child到场景树检查节点是否真的挂上了,编辑器里也必须进树
请求偶发超时timeout太短,或输出 token 上限设太高提到 45 到 60 秒,max_tokens降到 800 以内
生成的脚本解析失败输出里带 Markdown 围栏或省略号清洗首尾围栏,提示词里禁掉省略号
中文注释变成乱码字节流直接按默认编码转字符串统一用get_string_from_utf8()
编辑器越用越卡@tool脚本里有_process轮询删掉轮询,改成信号驱动

6.2 三个我踩过的坑,写出来省你时间

坑一:HTTPRequest在编辑器里"看起来"不工作。我最早把HTTPRequest创建成局部变量,request()一调,什么都没发生。原因很简单——它没进场景树。节点类的异步能力依赖节点树的处理循环,编辑器环境里也一样。后来改成add_child(_http),一切正常。这个坑网上说法很乱,记住一句话就够:只要是 Node,就必须进树。

坑二:request_completed信号重复连接。面板脚本在_enter_tree里连信号,_exit_tree里没断开。来回切几次场景,一次请求触发四五次回调,写入逻辑重复执行,文件被写了好几遍。修法是信号连接和断开严格成对,或者用CONNECT_ONE_SHOT。我倾向后者,每次请求前重新连接,天然不会重复。

坑三:res://写入后编辑器不刷新。用户看到面板提示"已写入",但文件系统停靠面板里还是旧内容,以为没成功。原因是编辑器的文件系统扫描有缓存。解决办法是调用EditorInterface.get_resource_filesystem().scan()强制刷新,或者在写盘后延迟一帧再 scan。加上这一句,体验立刻正常。

6.3 并发与批量操作的安全边界

插件一旦好用,用户就会想批量跑。比如"把这 30 个.tres文件的描述字段全部补齐"。这时候一旦并发失控,要么触发服务端频率限制,要么本地文件写入冲突。

我的做法是串行队列 + 可中断。维护一个Array当任务队列,同时只跑一个请求,跑完弹下一个。队列里每一项都有状态(待处理、进行中、完成、失败),面板上给一个进度条和"中止"按钮。中止时清空后续任务,正在进行的那个等它回来再丢弃结果。

这个设计比并发快多少?说实话慢一些。但批量改文件的场景下,慢而可控远比快而混乱重要。你不可能接受一个"改了 12 个文件,剩下的不知道改没改"的结果。

7. 性能与成本:别让助手变成负担

7.1 token 预算怎么算才不至于月底肉疼

这一块我做得比较细,因为吃过不估算的亏。一次典型请求的成本可以这么拆:系统提示词大概 300 token(这部分固定),上下文大概 800 到 2000 token(浮动最大),用户指令 100 token,输出平均 400 token。按输入输出分别计价,一次请求的量级心里有数。

关键在于控制上下文。上面说的三级裁剪,实际能把平均上下文从 3000 压到 1200 左右,成本直接降一半多。再叠加一层结果缓存:以"提示词哈希 + 上下文哈希"为键,把结果存到user://ai_cache/,同一个操作重复执行时直接命中缓存,零成本。

还得有个用量统计。我在面板底部放一行小字,显示"本次会话:请求 12 次,输入约 1.4 万 token,输出约 4800 token"。这个数字不是为了炫技,是为了让人有感知。看到数字在涨,自然会少问废话。

7.2 大文件与长响应的处理策略

超过 800 行的脚本,别整份丢给模型。我的处理是:如果用户在编辑器里选了片段,只发片段;如果没选,发当前函数(通过EditorInterface拿光标位置向上向下找函数边界);如果连函数都定位不到,才发整个文件并截断。

长响应也一样。max_tokens设了 800,模型输出到上限会被截断,得到一个半截的 JSON 或者半截的代码。这个必须检测:解析失败就提示"输出可能被截断,请缩小任务范围"。不要傻傻把半截内容拿去写盘。

7.3 什么活适合交给它,什么活坚决别碰

用了几个月,我自己的分工很清楚。

适合交给它的:模板代码生成(信号定义、导出变量、基础状态机骨架)、批量文本转换(表格转资源、命名规范统一)、局部重构建议("这个函数太长,帮我拆")、注释和文档生成、报错信息解读。

坚决别碰的:涉及存档格式的核心逻辑、网络同步的状态机、性能敏感的循环体、任何涉及用户数据的加密解密。这些地方的错误代价太大,而且模型给你的"看起来对"是最危险的——它不自检边界条件。

我有一个简单的判断标准:这段代码写错了,我五分钟内能不能发现?能,交给它;不能,自己写。

7.4 后续还能往哪扩

骨架搭好以后,扩展成本很低。我列几个自己已经在用的方向:

一是本地化文本批量生成。选中.csv,按英文列生成中文列初稿,再人工校对。这个能省 70% 的重复打字。

二是场景文档自动生成。遍历当前场景树,生成一份 Markdown 说明,列清楚每个节点的作用、挂的脚本、关键导出参数。新人接手项目时,这份文档比看代码快得多。

三是提交前自检。监听文件保存信号,对刚保存的脚本跑一遍规则检查(命名规范、注释覆盖率、TODO 遗留数),有问题在面板上标黄。这个不依赖模型,纯本地规则,但和 AI 面板放在一起,用起来很顺。

最后分享一个我个人的使用习惯:每次让插件干活之前,先手动保存一次。不是为了防它出错,是为了给自己一个明确的还原点。编辑器里的 Ctrl+S 只要零点几秒,但这个动作能让你在试错的时候心态完全放松——反正能回去,随便它折腾。这个习惯比任何技术手段都管用,我用到现在没丢过一次代码。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询