上岸的鱼

心中有光,便可使整个世界升起太阳

Aether - 开启 macOS 的空间交互时代 / Entering the Era of Spatial Interaction for macOS

中文版本 | English Version

[CN] 🚀 开发者自白:当传感器遇上交互灵感

最初写 Aether,其实是因为我戴着 AirPods Pro 在写代码时产生的一个脑洞:既然耳机里塞满了加速计和陀螺仪,既然系统已经能追踪我的空间音频,为什么不能用它们来做点更酷的事?

我想探索一种更具“未来感”的交互——离开键盘和鼠标,也能用 Mac。这不仅仅是为了炫技,更是为了在我的双手正忙(或是单纯想换个姿态)时,能用一种更自然、更“空间化”的方式与设备交流。

这是一款极客味很重的作品,也是我对“下一代交互”的一次小规模实验。

Aether 是一款挖掘 macOS 隐藏交互潜力的工具。它让你用声音完成输入和常见电脑操作,不用每一个小动作都再回到键盘和鼠标。这不只是针对 AirPods 用户的增强,更是为了实现 “离开键盘鼠标,也能用 Mac” 的完整愿景。


✨ 核心逻辑与功能

1. 听写输入 (Dictation)

回消息、改名字、写笔记。最直接的效率提升:说出来,它就出现在你要的地方。建议开启“按住说话 (Push to Talk)”来获得最稳定的体验。

2. 语音控制 (Voice Control)

点击、右键、双击、撤销、滚动。把那些总把你拉回触控板的小动作交给 Aether。它让键盘鼠标变成可选,而不是必须。

3. 头控指针 (Head Pointer)

利用 AirPods Pro / Max 的传感器,像移动头部一样自然地控制光标。结合姿态引导和重新校准,提供了丝滑的指向体验。


🛠️ 这样开始最稳妥

由于空间感知交互需要一定的适应期,我们建议按照以下顺序循序渐进:

  1. 先安装,再授权:先把 Aether 移到 /Applications,再授予权限。这样系统会记住正确路径。
  2. 先试语音输入:确认听写流程稳定,输入框能正常出字。
  3. 再试语音控制:尝试简单的点击、滚动命令。
  4. 最后开头控指针:头控是补充层,不是先决条件,放在最后开启最轻松。

更多信息请访问官网:aether.7caifei.com


[EN] 🚀 Project Introduction

If you are wearing AirPods, why move your hands back and forth between the keyboard and trackpad just to switch music, flip documents, or control the cursor?

Aether is a tool that unlocks the hidden interaction potential of macOS. It allows you to use your voice for input and common Mac actions, eliminating the need to revert to the keyboard and mouse for every small task. This is more than just an enhancement for AirPods users—it’s a step toward the vision of “Using Mac without keyboard & mouse.”


✨ Core Features

1. Voice Input (Dictation)

Reply to messages, rename files, and take notes. The most direct efficiency boost: say it, and it appears where you need it. We recommend starting with “Push to Talk” for the most stable experience.

2. Voice Control

Clicks, right-clicks, double-clicks, undo, scroll. Offload the small actions that keep pulling you back to the trackpad. It makes the keyboard and mouse optional, not required.

3. Head Pointer

Utilizing sensors in AirPods Pro / Max to control the cursor as naturally as moving your head. Combined with posture guides and re-centering, it provides a smooth pointing experience.


🛠️ Getting Started the Right Way

As spatial interaction requires an adaptation period, we suggest following this sequence:

  1. Install First, Then Grant Permissions: Move Aether into /Applications before granting permissions. This ensures macOS binds accessibility, microphone, and speech permissions to the final path.
  2. Start with Voice Input: Confirm the dictation workflow is stable and text appears correctly in input fields.
  3. Try Voice Control Next: Test simple commands like click and scroll.
  4. Turn on Head Tracking Last: Head tracking is an optional layer, not a prerequisite. Enabling it last makes the transition much smoother.

🔒 Privacy & Local Logic

Aether is designed to keep interaction logic as local to the Mac as possible. Your dictation text and documents are not uploaded to our servers as part of normal use.


For more information, visit the official website: aether.7caifei.com

Aion (灵汐) - 重新定义 macOS 后台自动化 / Redefining macOS Background Automation

中文版本 | English Version

[CN] 🚀 开发者自白:为什么有了灵汐 (Aion)?

作为一名重度 Mac 用户,我一直对“自动清理”类工具又爱又恨。大多数工具在后台杀进程时都太“暴力”了:下载到一半的应用、正在开会的 Zoom,甚至是在后台跑着 AI 任务的浏览器,常常因为几分钟没被点过就被强行收割。

我想要的是一个能感知上下文、能跟我建立信任感的助手。它应该像一个懂行的管家:当你真在忙正事时(哪怕应用在后台),它保持安静;只有当一个应用彻底变成“僵尸”状态时,它才出面收拾。

这就是 Aion (灵汐) 的由来——它不仅是清理工具,更是一场关于“自动化中‘信任感’边界”的编程实践。

核心理念

信任感是自动化的基石。 Aion 的核心目标不是多关几个后台,而是让你放心地把“关闭后台”这个决定权交给它,而不用担心它会在你下载 99% 时突然断掉你的浏览器。


✨ 核心功能详解

🎯 智能感知与守护

1. Smart Guards (智能护卫)

灵汐默认是偏保守的:会先判断应用当前在做什么,再决定是否退出。

  • 自动保护正在下载的应用:网络活动会让应用处于保护状态,而非过早退出。
  • 自动保护音乐与视频播放:正在播放媒体的应用受保护。
  • 自动保护麦克风和摄像头占用:你正在开会、通话或录音时,相关应用受保护。

2. AI App Protection (AI 应用保护)

当本地 AI / Agent 工作流正在使用某个应用时,灵汐可以把它保护起来,而不是把它当成普通后台闲置应用来清理。

📊 信任链路建设

1. 活动记录 (Activity Log)

这是 Aion 最近几个版本中最重要的更新。它公开了自动化的“黑盒”,你可以清晰地查看到:刚才哪个应用被尝试关闭了,以及为什么它被保留了下来。

2. 瞬时任务 (Instant Task)

针对计算器、词典等小工具,灵汐可以让这类短时工具用完即走,不留痕迹。

为什么灵汐比纯计时型工具更稳妥?

很多工具只看“闲置了多久”,灵汐在决定前还会判断“它还在做正事吗”:

  • 浏览器下载:超时后计时型工具仍可能清理,灵汐则会识别下载活动。
  • 系统清理:灵汐可以自动清理残留安装盘 (DMG) 和关闭无窗口的 Dock 应用。

更多信息请访问官网:aion.7caifei.com


[EN] 🚀 Project Introduction

On macOS, we often face a dilemma: to keep the system smooth, we want to clear redundant background processes; but to avoid interrupting the workflow, we fear that tools might “mistakenly kill” critical tasks running in the background (such as large file downloads, video rendering, or meetings).

Aion is a background automation assistant designed specifically to solve this pain point. It no longer simply relies on “idle time” to decide whether to close an app, but instead judges whether an app is “truly idle” through a deep context-aware system.

Core Philosophy

Trust is the foundation of automation. Aion’s core goal is not just to close more background apps, but to let you confidently hand over the decision of “closing background apps” to it, without worrying that it will suddenly cut off your browser while your download is at 99%.


✨ Core Features

🎯 Smart Guards & Context-Awareness

Aion is conservative by design. It checks what the app is doing before it quits anything.

  • Protects Active Downloads: Network activity keeps the app protected instead of being quit too early.
  • Protects Music and Video Playback: Apps currently playing media are protected.
  • Protects Mic and Camera Activity: If you are on a call or recording, the relevant app stays protected.

2. AI App Protection

Aion can protect an app while a local AI or agent workflow is actively using it, instead of treating that app like ordinary background idle time.

📊 Building the Trust Loop

1. Activity Log

This is the most important update in recent versions. It opens up the “black box” of automation, allowing you to clearly see: which app was attempted to be closed just now, and why it was retained.

2. Instant Task Mode

For small utilities like calculators or dictionaries, Instant Task mode lets short-lived apps disappear right after use.

Why Aion feels safer than timer-based tools?

Most tools only look at “how long it has been idle”. Aion looks at “whether it is still doing productive work” before deciding:

  • Browser Downloads: Timer-based tools might still clean them up after expiration; Aion recognizes the download activity.
  • System Cleanup: Aion can automatically clean up leftover installer DMGs and close Dock apps with no windows.

🌟 Creator’s Note

A background tool itself should not become a new background burden.

We’ve optimized Aion’s resource usage to ensure it remains nearly invisible:

  • Visibility Driven: Interface logic only refreshes when the menu bar or HUD is visible.
  • Minimal Resource Footprint: All judgments are completed locally on your Mac, ensuring privacy and performance.

For more information, visit the official website: aion.7caifei.com

本文包含中文与英文两个版本。
This post includes both Chinese and English versions.

中文版

现象

这次遇到的问题是:Antigravity 聊天框里消息可以发出去,但一直没有回复

最开始最显眼的报错是:

1
2
3
4
5
[Error] Server initialization failed.
Message: Pending response rejected since connection got disposed

[Error] antigravity client: couldn't create connection to server.
Error: connect ECONNREFUSED 127.0.0.1:60557

另外还有一条容易让人分心的错误:

1
Error generating commit message: [unknown] core.repositoryformatversion does not support extension: worktreeconfig

但排查到最后,这两类信息都不是根因。

先排掉假线索

第一条假线索是 worktreeconfig
它确实会影响 Git 相关能力,比如自动生成 commit message,但它和聊天框“不回复”不是一条链路。

第二条假线索是 ECONNREFUSED
继续追日志后会发现,language server 后面其实已经成功拉起:

1
2
3
4
LS lspClient started successfully
Language server started
loadCodeAssist
fetchAvailableModels

所以端口拒绝连接更像是启动阶段的一次短暂失败,而不是最后把聊天功能彻底卡死的根因。

真正的问题在 renderer

真正关键的报错出现在 renderer 日志里:

1
[createInstance] ... depends on UNKNOWN service agentSessions

同时还能看到类似提示:

1
command 'workbench.action.chat.newChat' not found

这说明问题已经不只是 language server,而是聊天工作台本身依赖的会话服务没有被正常注册
也就是说,输入框虽然还在,但聊天的前端主链路已经坏了。

为什么重装当前版本没用

我后面做了一个关键对比:不仅看本机 /Applications/Antigravity.app,还去下载并比对了当时官方 releases 提供的当前版本安装包。

结论是:

  1. 本机当前版本和官方当前版本是一致的。
  2. 所以不是“这台机器装坏了”。
  3. 至少在这次命中的链路里,当时的当前官方包本身就有问题

也正因为如此,单纯删掉再重装最新版没有意义。

为什么没有直接热补丁 App 包

排查过程中,我一度已经定位到工作台主包里可疑的注册缺失点,也做过本地补丁尝试。

但在 macOS 上很快就会撞到系统安全策略:

1
2
Security policy would not allow process
The file is adhoc signed or signed by an unknown certificate chain

意思很直接:

  1. 技术上能改。
  2. 但改完的包不适合长期稳定运行。
  3. 因为只要动了已签名 App 的资源,后面就会遇到签名链、AMFI 或系统策略的问题。

所以“直接热补丁现有安装包”不是一个稳妥方案。

最后可用的修法

最后真正可用的修法不是继续硬修当前版本,而是:

  1. 换成一份官方签名的旧版 Antigravity 1.20.6
  2. 把 language server 路径一起切到这份旧版自带的二进制。
  3. 关闭自动更新,避免它再次跳回坏版本。

关键配置在:

1
$HOME/Library/Application Support/Antigravity/User/settings.json

核心字段如下:

1
2
3
4
5
{
"codeiumDev.languageServerBinaryPath": "$HOME/Applications/Antigravity 1.20.6.app/Contents/Resources/app/extensions/antigravity/bin/language_server_macos_arm",
"antigravity.persistentLanguageServer": false,
"update.mode": "none"
}

其中:

  • codeiumDev.languageServerBinaryPath:强制指向旧版 1.20.6 自带的 language server。
  • antigravity.persistentLanguageServer: false:避免继续黏住旧的异常状态。
  • update.mode: none:防止自动更新把运行链路再次切回坏版本。

这条路更稳的原因在于:它仍然使用的是官方签名包,没有继续破坏应用完整性。

这次排查最值得记住的几点

  1. 不要被第一条报错带偏。
  2. 要先区分“噪音错误”和“致命错误”。
  3. 不要默认“重装最新版”一定有用。
  4. 在 macOS 上,热补丁已签名 App 通常不是长期修法。
  5. 如果问题确实出在某个发布版本里,官方签名旧版 + 锁版本 往往比自行魔改更现实。

结语

这次问题最难的地方,不是没有日志,而是日志太多,而且有不少误导项

表面看像 language server,像 Git,像本地缓存,最后真正影响聊天恢复的,却是工作台聊天链路和版本选择。

最后真正把它拉回正常的,不是继续修当前安装,而是:

回退到官方签名的 1.20.6,切换 language server 路径,并锁住更新。


English Version

Symptom

The problem looked simple at first: messages could be sent in Antigravity chat, but no reply ever came back.

The first errors that stood out were:

1
2
3
4
5
[Error] Server initialization failed.
Message: Pending response rejected since connection got disposed

[Error] antigravity client: couldn't create connection to server.
Error: connect ECONNREFUSED 127.0.0.1:60557

There was also another distracting error:

1
Error generating commit message: [unknown] core.repositoryformatversion does not support extension: worktreeconfig

In the end, neither of them turned out to be the real root cause.

Removing the false leads first

The worktreeconfig error was the first false lead.
It can affect Git-related features such as commit message generation, but it is not on the same path as “chat sends but never replies”.

The second false lead was ECONNREFUSED.
Once I kept reading the logs, it became clear that the language server was eventually starting successfully:

1
2
3
4
LS lspClient started successfully
Language server started
loadCodeAssist
fetchAvailableModels

So the refused localhost port looked more like a startup race or transient failure, not the final blocker.

The real failure was in the renderer

The truly important error showed up in the renderer log:

1
[createInstance] ... depends on UNKNOWN service agentSessions

There was also a related message like:

1
command 'workbench.action.chat.newChat' not found

That changes the diagnosis completely.
At that point, the issue is no longer just the language server. It means the chat workbench itself is missing a required session service registration.

In other words, the input box may still be visible, but the front-end chat pipeline is already broken.

Why reinstalling the current version did not help

I compared not only the local /Applications/Antigravity.app, but also the then-current official installer downloaded from the official releases feed.

The result was:

  1. The local current version matched the official current version.
  2. So this was not simply “a corrupted install on this Mac”.
  3. On the code path I hit during this debugging session, the current official build itself appeared to be problematic.

That is why deleting and reinstalling the latest version did not meaningfully help.

Why I did not hot-patch the app bundle

At one point I had already narrowed the issue down to a suspicious missing registration in the workbench bundle and even tried building a local patch.

On macOS, that quickly runs into system policy:

1
2
Security policy would not allow process
The file is adhoc signed or signed by an unknown certificate chain

That means:

  1. You can patch it technically.
  2. But the patched app is not a good long-term runtime target.
  3. Once you modify resources inside a signed app, you start fighting code signing, AMFI, and system policy.

So “hot-patching the installed app” is not a reliable long-term fix.

The fix that actually worked

The working solution was not to keep patching the broken current version, but to:

  1. Switch to an officially signed older build, Antigravity 1.20.6.
  2. Repoint the language server path to the binary shipped inside that build.
  3. Disable auto-update so it would not jump back to the broken version.

The key configuration lives in:

1
$HOME/Library/Application Support/Antigravity/User/settings.json

The important fields were:

1
2
3
4
5
{
"codeiumDev.languageServerBinaryPath": "$HOME/Applications/Antigravity 1.20.6.app/Contents/Resources/app/extensions/antigravity/bin/language_server_macos_arm",
"antigravity.persistentLanguageServer": false,
"update.mode": "none"
}

Why this is safer:

  • It keeps using an officially signed build.
  • It avoids breaking the integrity of the installed app bundle.
  • It pins the runtime to a version that still behaves normally.

The most useful lessons from this debugging session

  1. Do not let the first visible error dictate the whole investigation.
  2. Separate noisy errors from fatal ones.
  3. Do not assume reinstalling the latest build will always help.
  4. On macOS, patching a signed app is rarely the best long-term answer.
  5. If a release itself is the problem, an officially signed older version plus update pinning is often much more practical.

Closing note

The hardest part of this issue was not the lack of logs.
It was the opposite: there were too many logs, and several of them were misleading.

At first glance it looked like a language server problem, or a Git problem, or a cache problem.
In the end, the real issue was the chat workbench path itself and the version being used.

What finally brought the app back to a usable state was:

rolling back to the officially signed 1.20.6 build, repointing the language server path, and locking updates.

UE5 插件开发:C++ Tooltip 本地化失效的避坑指南

在进行 UE 插件开发时,我们通常会为 UPROPERTY 编写注释,期望这些注释能作为 Tooltip 在编辑器中显示,并支持多语言本地化。但在实际操作中,经常会遇到翻译失效的问题。

问题现象

当你完成了以下步骤:

  1. 代码注释: 编写了 /** My Tooltip with \n Newline */
  2. 文本收集: 成功 Gather 到了对应的 SourceString。
  3. 完成翻译: 在 PO 文件中填好了对应的中文并编译为 LocRes。

却发现编辑器里悬停显示的依然是旧的英文,甚至当你删除了代码中的注释,编辑器里依然顽固地显示着之前的旧文本。

这种情况通常不是缓存的问题,而是掉进了 UE 本地化中最隐蔽的陷阱:UHT 元数据持久化 (Metadata Persistence)


原因分析

UE 的 Tooltip 并非在运行时直接读取代码注释,其真实流程如下:

  1. 编译期 (UHT): Unreal Header Tool 解析 .h 文件。它读取注释并将其转换为一个字符串常量,作为 MetaData 烧录进生成的 .gen.cpp 文件中,最终编译进二进制。
  2. 运行期 (Editor): 编辑器通过反射系统 (FProperty::GetToolTipText) 获取这个硬编码在二进制里的 SourceString
  3. 查字典: 编辑器拿着这个 SourceString 去 LocRes 里寻找匹配的翻译。

核心症结:SourceString 的不确定性

UHT 在处理注释时非常不透明:

  • 它可能会将 /** A \n B */ 解析为 "A\nB",也可能解析为 "A B"
  • 解析结果受操作系统换行符(CRLF/LF)和缩进的影响。

导致失效的典型场景:

  1. 最初写的注释生成的 Key A 被烧录进了二进制。
  2. 你发现翻译不对,修改了注释,UHT 生成了 Key B。
  3. 由于增量编译或构建缓存的原因,二进制文件没有彻底更新,或者 UHT 认为该 .h 无需重新处理。
  4. 结果是:LocRes 里存的是 Key B 的翻译,但二进制里残留的依然是 Key A。 由于 SourceString 不匹配,翻译永远无法生效。

解决方案:显式元数据 (Explicit Meta)

与其去猜测 UHT 会如何解析注释,不如直接接管这个过程。

最佳实践:对于必须本地化的编辑器属性,不要依赖注释,直接使用显式元数据。

修改方式

1
2
3
4
5
6
7
8
9
10
11
// ❌ 依赖注释(不推荐)
/**
* The Enhanced Input Action.
* Triggers the attack.
*/
UPROPERTY(EditAnywhere)
UInputAction* InputAction;

// ✅ 显式覆盖(推荐)
UPROPERTY(EditAnywhere, meta=(ToolTip="The Enhanced Input Action. Triggers the attack."))
UInputAction* InputAction;

为什么这样做有效?

  1. 跳过不确定解析: meta=(ToolTip="...") 是直接赋值。UHT 不会对其进行任何“智能化”处理,你写什么,二进制里就是什么。
  2. 跨平台一致性: 无论什么操作系统或 IDE,这个字符串在二进制层面上是绝对一致的。
  3. 强制 UHT 更新: 修改 meta 会明确告知 UHT 文件已变更,从而确保重新编译并刷新二进制中的元数据。

结语

如果你遇到了“代码改了、翻译更新了,但编辑器死活不认”的本地化难题,请尝试以下操作:

  1. 放弃依赖注释: 在对应的 UPROPERTY 中添加 meta=(ToolTip="你的文本")
  2. 手动强制更新: 如果可能,清理并重新编译项目,确保二进制中的 SourceString 被刷新。
  3. 重新收集文本: 运行一次新的 Gather Text 流程。

这通常是解决 UE Tooltip 本地化顽疾最稳妥、最高效的方法。

MacMessageBackup:iMessage 和通话记录备份到 Gmail

把 macOS 上的短信和通话记录备份到 Gmail,支持日历同步。原生 SwiftUI 界面,菜单栏常驻。


为什么做这个

iMessage 数据只存在本地 ~/Library/Messages/chat.db,换电脑或者重装系统就没了。

之前用过 SMS Backup+ 备份安卓短信到 Gmail,体验很好 —— 邮件搜索功能用来找历史记录非常方便。macOS 上没找到类似的工具,就自己写了一个。

功能

iMessage & 短信 → Gmail
通话记录 → Gmail(保留时长、类型等元数据)
通话记录 → 日历同步(方便在日历里回看)
断点续传 - 记录进度,中断后继续
菜单栏常驻 - 实时显示进度如 “52/460”

效果

备份后在 Gmail 里长这样:

  • 每条短信/通话是一封邮件
  • 自动加 Label 分类(如 SMS 或Call Log`)
  • 保留原始时间戳,按日期排序

技术实现

数据读取

直接读 SQLite 数据库:

1
2
短信:~/Library/Messages/chat.db
通话:~/Library/Application Support/CallHistoryDB/CallHistory.storedata

需要 Full Disk Access 权限,应用首次启动会引导授权。

上传到 Gmail

用 Python 的 imaplib 做批量 IMAP APPEND。

为什么用 Python 而不是纯 Swift?

  • Swift 的 IMAP 库不太成熟
  • Python 复用连接,批量上传很快(每秒几百条)
  • macOS 自带 Python 3,不需要额外依赖

流程:

1
Swift 读取数据库 → 生成 .eml 文件 → Python 批量 IMAP APPEND → Gmail

密码安全

Gmail 应用专用密码存在 macOS Keychain 里,不走任何中间服务器。

安装使用

系统要求:macOS 13.0+

步骤

① 下载或编译 app
② 首次运行右键"打开"(绕过 Gatekeeper)
③ 授权 Full Disk Access
④ 填入 Gmail 和应用专用密码
⑤ 点 Backup

生成应用专用密码

Google 账户 → 安全性 → 两步验证 → 应用专用密码

不要用主密码。

代码结构

1
2
3
4
5
6
7
8
9
10
11
12
MacMessageBackup/
├── App/ # 入口
├── Models/ # Message, CallRecord, BackupConfig
├── Services/
│ ├── IMAPService.swift # Gmail 上传核心(运行时生成 Python 脚本)
│ ├── MessageDatabaseService.swift
│ ├── CallHistoryService.swift
│ └── LocalCalendarService.swift
└── Views/
├── ContentView.swift
├── MenuBarView.swift
└── SettingsView.swift

已知限制

  • 只读备份,不能从 Gmail 还原回手机(iOS 系统限制)
  • 需要 Full Disk Access 权限
  • 没有 Apple 开发者签名,首次运行要手动信任

🔗 项目地址:GitHub - MacMessageBackup

MIT License

QuickEventFunctionCreator - 革命性的UE5蓝图开发插件

🚀 项目简介

作为一名UE开发者,我深知蓝图开发中重复性操作的痛点。创建变量、函数、事件往往需要大量的点击操作,严重影响开发效率。为了解决这个问题,我开发了 QuickEventFunctionCreator - 一个革命性的Unreal Engine编辑器插件。

核心理念

通过统一的自然语言语法,您可以瞬间创建变量、函数、事件、宏和变量节点,配合智能别名和智能定位功能。原本需要数分钟点击的操作,现在只需几秒钟的输入。

✨ 插件功能详解

🎯 核心创建功能

1. 变量创建系统

  • 全局变量创建: 在蓝图类中创建成员变量

  • 局部变量创建: 在函数内创建临时变量

  • 智能上下文检测: 自动判断创建全局还是局部变量

  • 完整类型支持: 支持所有UE数据类型,包括自定义类型

2. 函数创建系统

  • 标准函数: 普通的蓝图函数

  • 纯函数: 无副作用的计算函数

  • 常量函数: 不修改对象状态的函数

  • 参数支持: 完整的输入/输出参数定义

  • 返回值支持: 自动创建返回节点

3. 事件创建系统

  • 自定义事件: 蓝图内部事件

  • 网络事件: Server/Client/Multicast事件

  • 可靠性控制: Reliable网络事件

  • 参数传递: 支持复杂参数结构

  • 执行引脚: 自动生成执行流控制

4. 宏创建系统 (v2.1)

  • 蓝图宏: 可重用的节点组合

  • 参数方向: in/out/inout/exec完整支持

  • 智能引脚生成: 根据参数自动创建输入输出引脚

  • 执行流控制: 支持多个执行路径

5. 变量节点生成

  • Get节点: 为现有变量创建获取节点

  • Set节点: 为现有变量创建设置节点

  • 智能定位: 节点出现在鼠标点击位置

  • 自动连接: 可选的自动连接功能

🧠 智能化特性

1. 统一语法系统

  • 一致性: 所有创建操作使用相同的语法规则

  • 直观性: 自然语言风格的命令结构

  • 可扩展性: 易于添加新的创建类型

2. 智能别名系统

  • 事件别名: e→event, s→server, c→client等

  • 函数别名: fn→func, p→pure, k→const等

  • 变量别名: var→variable, lv→local等

  • 类型别名: i→integer, f→float, str→string等

  • 节点别名: g→get, st→set等

3. 上下文感知

  • 作用域检测: 自动识别当前编辑环境

  • 变量类型推断: 根据上下文选择合适的变量类型

  • 智能默认值: 为不同类型提供合理的默认设置

4. 精确定位

  • 鼠标位置创建: 节点精确出现在点击位置

  • 图表适配: 自动适应不同类型的蓝图图表

  • 布局优化: 智能避免节点重叠

🔧 高级功能特性

1. 参数系统

  • 复杂参数支持: 支持多个输入输出参数

  • 参数类型推断: 自动识别参数类型

  • 默认值设置: 为参数提供合理默认值

  • 引用传递: 支持inout参数类型

2. 网络功能

  • 多播事件: Multicast事件创建

  • 服务器事件: Server RPC事件

  • 客户端事件: Client RPC事件

  • 可靠性控制: Reliable网络传输

3. 类型系统

  • 基础类型: Boolean, Integer, Float, String等

  • 复合类型: Vector, Rotator, Transform等

  • UE特有类型: Name, Text, Object引用等

  • 自定义类型: UCLASS, USTRUCT, UENUM支持

4. 工作流集成

  • 热键激活: Shift + 左键快速激活

  • 工具栏集成: 可选的工具栏按钮

  • 设置面板: 完整的配置选项

  • 即时生效: 设置修改立即生效

🎨 用户体验功能

1. 输入辅助

  • 语法提示: 实时显示可用命令

  • 自动补全: 智能命令补全

  • 错误提示: 清晰的错误信息

  • 使用示例: 内置语法示例

2. 可定制性

  • 别名自定义: 完全可定制的别名系统

  • 热键配置: 自定义激活快捷键

  • 行为设置: 可调整的创建行为

  • 界面选项: 可控制的UI元素

3. 性能优化

  • 轻量级设计: 不影响编辑器性能

  • 即时响应: 快速的命令处理

  • 内存效率: 优化的内存使用

  • 稳定性: 经过充分测试的稳定性

🔧 技术规格

支持的引擎版本

  • Unreal Engine 4: 4.26, 4.27

  • Unreal Engine 5: 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6

  • 平台: Windows 64-bit, macOS

兼容性

  • ✅ 适用于所有项目类型

  • ✅ 无需C++环境

  • ✅ 即插即用,自动启用

📝 统一语法详解

基础结构

1
2
3

[修饰符] 类型 名称 [参数]

创建类型示例

变量创建

1
2
3
4
5

var <type> <name> // 全局变量

local <type> <name> // 局部变量

函数创建

1
2
3
4
5
6
7

func <name> [parameters] // 标准函数

pure func <name> // 纯函数

const func <name> // 常量函数

事件创建

1
2
3
4
5
6
7
8
9

event <name> [parameters] // 自定义事件

server event <name> // 服务器事件

client event <name> // 客户端事件

multicast event <name> // 多播事件

宏创建

1
2
3
4
5
6
7

macro <name> [parameters] // 蓝图宏

macro Calculate(float Input, out float Result)

macro ProcessData(exec In, string Data, inout bool Flag, out exec Success)

⚡ 智能别名系统

事件别名

| 别名 | 完整命令 | 示例 |

|------|----------|------|

| e | event | e OnDeath |

| s | server | s OnUpdate |

| c | client | c OnInput |

| m | multicast | m OnBroadcast |

数据类型别名

| 别名 | 完整类型 | 替代别名 |

|------|----------|----------|

| b | boolean | bool, boolean |

| i | integer | int, int32, integer |

| f | float | float, double |

| str | string | string |

| v | vector | vec, vec3, vector |

🧪 实际使用示例

完整工作流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

// 1. 创建变量

var i PlayerHealth // 全局整数变量

var f MaxSpeed // 全局浮点变量

lv str PlayerName // 局部字符串变量



// 2. 使用变量(创建节点)

g PlayerHealth // 为PlayerHealth创建Get节点

st PlayerHealth // 为PlayerHealth创建Set节点



// 3. 创建函数

fn CalculateDamage // 标准函数

p fn GetPlayerScore // 纯函数

k fn GetMaxHealth // 常量函数



// 4. 创建事件

e OnPlayerDeath // 自定义事件

s OnServerUpdate // 服务器事件

rel m OnGameStateChanged // 可靠多播事件



// 5. 带参数示例

fn CalculateDamage(i BaseDamage, f Multiplier)

e OnPlayerHit(i Damage, v HitLocation, str AttackerName)



// 6. 宏示例

m Calculate(f Input, out f Result) // 宏:计算

macro ProcessData(exec In, str Data, inout b Flag, out exec Success)

🎮 使用方法

快速开始

  1. 打开任意蓝图图表(事件图表、函数图表等)

  2. 使用 Shift + 左键点击 在图表任意位置激活

  3. 输入创建命令,使用统一语法

  4. 按回车键 - 节点精确出现在点击位置!

效率对比

  • 传统方法: 15+ 次点击,2-3分钟

  • 插件方法: 输入 var i Health → 2秒钟 ⚡

⚙️ 设置选项

导航至 项目设置 → 插件 → Quick Event Function Creator 进行全面自定义:

📁 常规设置

  • 显示使用提示: 在输入对话框中切换语法帮助

  • 显示工具栏按钮: 在蓝图编辑器中显示/隐藏工具栏按钮

  • 重置所有设置: 一键恢复默认设置

⌨️ 热键设置

  • 激活组合键: 自定义热键(默认:Shift + 左鼠标按钮)

🎯 行为设置

  • 默认创建类型: 未指定关键字时的默认创建类型

  • 变量节点自动生成模式: 创建变量时自动生成Get/Set节点

🌟 开发心得

设计理念

在开发这个插件的过程中,我始终坚持以下原则:

  1. 用户体验至上: 每个功能都经过反复测试和优化

  2. 语法一致性: 统一的语法规则,降低学习成本

  3. 智能化: 上下文感知,自动做出最佳选择

  4. 可扩展性: 模块化设计,便于后续功能扩展

技术挑战

开发过程中遇到的主要挑战:

  1. UE蓝图系统的复杂性: 需要深入理解UE的蓝图编译和节点系统

  2. 参数解析: 实现灵活而准确的参数解析算法

  3. 上下文检测: 智能判断当前编辑环境,提供合适的创建选项

  4. 性能优化: 确保插件不影响编辑器性能

🔗 获取插件

下载渠道

社区支持

插件优势

开发效率提升

  • 时间节省: 将分钟级操作缩短到秒级

  • 减少点击: 大幅减少重复性鼠标操作

  • 专注创意: 更多时间投入逻辑设计而非机械操作

  • 学习成本低: 直观的自然语言语法

工作流程优化

  • 无缝集成: 完美融入现有UE开发流程

  • 即插即用: 安装后立即可用,无需额外配置

  • 兼容性强: 支持所有UE项目类型

  • 稳定可靠: 经过大量测试,确保稳定性

💬 结语

QuickEventFunctionCreator 不仅仅是一个插件,它代表了我对提高开发效率的不懈追求。通过将复杂的操作简化为直观的语法,我们可以将更多时间投入到真正的创意和逻辑设计中。

如果您是UE开发者,强烈推荐尝试这个插件。它将彻底改变您的蓝图开发体验,让您的开发效率提升数倍。


本文介绍的插件完全由作者独立开发,如有任何问题或建议,欢迎通过上述渠道联系。

本目录为“多人在线生存”教程的章节索引与导航。点击任意章节快速跳转;建议从上到下依次阅读。

导读

章节导航

  1. 第一章:项目入门
  2. 第二章:构建物品系统框架
  3. 第三章:快捷栏与斧头装备
  4. 第四章:采集系统
  5. 第五章:制作系统
  6. 第六章:玩家属性系统
  7. 第七章:印痕系统
  8. 第八章:护甲装备
  9. 第九章:建造系统
  10. 第十章:存储容器
  11. 第十一章:物品制作
  12. 第十二章:部落系统
  13. 第十三章:社交系统
  14. 第十四章:开放世界地图
  15. 第十五章:程序化植被
  16. 第十六章:AI 系统
  17. 第十七章:程序化刷新区
  18. 第十八章:地图系统与复活功能
  19. 第十九章:存档系统
  20. 第二十章:网络会话与前端UI
  21. 第二十一章:专用服务器设置与托管
  22. 第二十二章:附加内容
0%