

UE 叫它 pipeline,是因为导入不是"读 FBX 然后直接生成 SkeletalMesh"这么单一步骤,而是分层处理:
- Translator 读源文件,比如 FBX/glTF/OBJ/贴图/音频,把内容变成 Interchange 节点和 payload。
- Pipeline 根据导入选项加工这些节点,比如是否导入 Skeletal Mesh、Animation、Materials、Textures、LOD、权重、法线切线、重导入策略。
- Factory 再把节点真正生成 UE 资产,比如 USkeletalMesh、UStaticMesh、USkeleton、UAnimSequence、UMaterial、UTexture。
本地源码入口可以看这些:
- Interchange 插件说明:Interchange.uplugin (line 6)
- Interchange 的模块列表:Interchange.uplugin (line 25)
- Generic Assets Pipeline 类:InterchangeGenericAssetsPipeline.h (line 42)
- Pipeline 执行入口:InterchangeGenericAssetsPipeline.h (line 164)
- FBX Translator:InterchangeFbxTranslator.h (line 77)
- FBX 支持格式注册:InterchangeFbxTranslator.cpp (line 262)
会走这个 pipeline 的是通过 Interchange 导入器导入的源文件,例如 FBX、glTF、OBJ、贴图、音频、MaterialX,以及 USD/OpenVDB 这类扩展 translator 支持的格式。它们最终可能生成 StaticMesh、SkeletalMesh、Skeleton、AnimSequence、Material、Texture、SoundWave 等资产。
UE 5.0 前后:Interchange 作为新框架出现
Interchange 的目标从一开始就不是"再写一个 FBX importer",而是把导入过程拆成可替换层:
文件格式解析
└─ Translator
中间数据表达
└─ Node Container
项目规则和选项
└─ Pipeline Stack
创建具体 UE 资产
└─ Factory
UE 5.5:资产导入被 Epic 判定为 production ready
Epic 在 UE 5.5 Release Notes 中写明:
Interchange
├─ Asset imports:Production Ready
└─ Level imports:Beta
同时继续完善 FBX level import、碰撞、reimport、动画和 Morph Target 等功能。Epic Games Developers
UE 5.7:FBX Import Into Level 默认切到 Interchange
UE 5.7 Release Notes 明确说:
FBX Level Import
└─ Interchange 成为默认路径
└─ 仍可通过 CVar 回退到 Legacy
一个模型导入器为什么还要兼容旧版?旧版不应该直接被取代吗
因为 UE 的"模型导入"不是一次性的文件转换器,而是资产生命周期的一部分。旧导入器一旦参与创建资产,它的处理结果和配置就已经写进项目。新导入器不仅要能读同一个 FBX,还必须决定是否能继续维护这些旧资产。
你混在一起的是两个问题:
问题 A:新导入器能不能导入新的 FBX?
└─ 通常可以直接取代旧导入器
问题 B:新导入器能不能无差异地 Reimport 旧项目里的资产?
└─ 不一定,因此旧路径不能立刻删除
Pose Asset 确实是一个独立资产,可以保存、复制、导出相关动画数据;
它绑定的是一个 Skeleton Asset,


而是:
有字幕轨道
└─ 但轨道 URL 仍处于 HTML 编码状态
└─ URL 查询参数边界被破坏
└─ YouTube 找不到对应字幕资源
└─ 返回 200 + 空 HTML
为什么是 200,而不是 400 或 403
因为从 HTTP 服务器角度看,这仍然是一个合法请求:
GET /api/timedtext?lang=en&v=xxx
它语法合法,服务器也成功处理了,所以状态码可以是 200。
只是它在业务层没有找到有效字幕,或者把请求导向了普通 HTML 响应路径。YouTube 的 timedtext 接口在缺少或错误签名、参数不完整等情况下,确实可能表现为空内容,而不是稳定返回明确错误码。
onus 来自拉丁语,原意就是"重量、负担",和 onerous "繁重的、负担沉重的"属于同一词源。Merriam-Webster+1
可以,而且已经查到了。三个模式主要差在这些文件:
```text
C:\Program Files\OEM\机械革命电竞控制台\UniwillService\MyControlCenter\UserPofiles\
```
对应关系大致是:
-
`Mode1_Profile1.json` = 均衡 / Game
-
`Mode2_Profile1.json` = 办公 / Office / Whisper
-
`Mode3_Profile1.json` = 狂暴 / Turbo
关键差异:
| 模式 | CPU PL1/PL2 | GPU TGP | GPU 超频 | Whisper | 风扇最大 |
|---|---|---|---|---|---|
| 均衡/Game | 75W / 75W | 115W | 0 / 0 | 关 | 90% |
| 办公/Office | 45W / 45W | 115W 但 TGP 开关关 | 0 / 0 | 开 | 55% |
| 狂暴/Turbo | 90W / 90W | 140W | 核心 +100 / 显存 +500 | 关 | 95% |
更具体:
`Mode1_Profile1.json` 均衡:
```json
"PL1": 75,
"PL2": 75,
"ConfigurableTGPTarget": 115,
"CoreClockOffset": 0,
"MemoryClockOffset": 0,
"WhisperModeSwitch": 0,
"TableName": "M1T1"
```
`Mode2_Profile1.json` 办公/Whisper:
```json
"PL1": 45,
"PL2": 45,
"ConfigurableTGPSwitch": 0,
"TargetTemperature": 87,
"WhisperModeSwitch": 1,
"TableName": "M2T1"
```
`Mode3_Profile1.json` 狂暴:
```json
"PL1": 90,
"PL2": 90,
"ConfigurableTGPTarget": 140,
"CoreClockOffset": 100,
"MemoryClockOffset": 500,
"WhisperModeSwitch": 0,
"TableName": "M3T1"
```
风扇曲线在这里:
```text
C:\Program Files\OEM\机械革命电竞控制台\UniwillService\MyControlCenter\UserFanTables\
```
对应:
-
`M1T1.json` = 均衡风扇表,最高 90%
-
`M2T1.json` = 办公风扇表,最高 55%
-
`M3T1.json` = 狂暴风扇表,最高 95%
所以三档不是只改名字,实际差异很大:办公档主要限制 CPU 和风扇,并开启 Whisper;狂暴档提高 CPU、GPU TGP、GPU Offset 和风扇上限。
a bird's-eye view鸟瞰视角;从高处看整体
因为鸟飞在高处,所以它看到的是整体布局,不是局部细节。
这句:
very bird's-eye-view paraphrased summary
意思接近:
用非常宏观、非常简化的方式概括一下。
paraphrased summary 就是:
经过改写、压缩后的概括
不是逐字准确复述,而是用自己的话讲大意。
we might want to holster the weapon
就是:
我们可能想把武器收起来。
在游戏语境里,holster 不一定只针对手枪。它常泛指"把当前武器从手上收回到身体上的默认携带位置"。
draw / unholster the weapon
└─ 拔出、拿出武器
holster the weapon
└─ 收起、归位武器
词源上,holster 原本主要指"枪套"。后来动词化,变成"把枪放进枪套"。在游戏开发里又进一步泛化,可以指:
-
枪放回腰间
-
剑挂回背后或腰侧
-
武器从手部 Socket 切换到背部 Socket
不是"美国人普遍习惯用日语表达",而是 katana 已经进入英语,成了一个非常普通的外来词。
在英语里:
katana /kəˈtɑːnə/
指日本刀,尤其是典型的单刃弯刀。
它的地位有点像:
-
sushi
-
karaoke
-
samurai
-
ninja
-
anime
-
tsunami
英语里的 katana 比日语原词 刀(かたな) 的使用范围更窄。日语里的 katana 本来可以比较广泛地表示"刀、刀剑";现代英语里,它几乎总让人想到:
日本武士使用的那种长刀
所以英语其实是把这个日语词"借过来以后,固定成了一个更具体的文化类别"。
美式英语会明显做成:
kə-TAH-nə
melee /ˈmeɪleɪ/ 在游戏里指:
近战
所以:
Is Melee = True
└─ 这是近战武器
Is Melee = False
└─ 这不是近战武器,可能是远程武器
比如:
Greatsword
└─ Is Melee = True
Katana
└─ Is Melee = True
Pistol
└─ Is Melee = False
genre 是「類型、體裁、流派」。
最常見用法:
-
film genre:電影類型
-
music genre:音樂流派
-
literary genre:文學體裁
-
game genre:遊戲類型
例如:
Horror is my favorite film genre.
恐怖片是我最喜歡的電影類型。
發音是:
genre /ˈʒɑːnrə/ 或 /ˈʒɑːn.rə/
大致像:ZHON-ruh
開頭不是普通英文的 g 音,而是 /ʒ/,就是 vision、measure 中間那個音。
genre
└─ 作品在歷史中形成的一套體裁規則
例如:horror、western、romance、RPG

-
hammer it in:把它敲進去,強調「記進腦中」
-
hammer it home:把重點打到位,強調「讓人徹底明白」
hammered that in
/ˈhæmɚd ðæt ɪn/
但實際口語不會逐字讀成:
HAM-mered / THAT / IN
而更接近:
HAM-er(d)-tha-din
或更潦草地像 HAM-er-a-din
/d/ 和 /ð/ 都在舌尖附近發音。美國人快速說時,不會把舌頭完整地:
先做 /d/
放開
再重新做 /ð/
而是一次舌尖動作滑過去。結果 /d/ 可能不爆破、變得極弱,甚至幾乎聽不見。
that in 也會繼續連讀。
that in
/ðæt ɪn/
t 位於兩個元音環境附近時,美式口語很容易變成 flap /ɾ/:
that in → 類似 tha-din

這兩個按鈕的作用是修改「選中的兩個 Physics Bodies 之間是否互相碰撞」。因此只有同時選中至少兩個 Body 時才會亮起;你目前沒有選中符合條件的一對 Body,所以它們是灰色的。
同一個 Skeletal Mesh 可以有不只一個 Physics Asset,而這個按鈕讓你切換目前要編輯哪一個。
先把畫面中的兩個動作分開:
上面藍色 Physics 圖示
└─ 進入 Physics Asset 編輯模式
藍色圖示旁邊的三點/下拉選單
└─ 選擇要打開哪一個 Physics Asset
The dropdown menu next to the Physics tab can be used to select any Physics Asset located in the Content Drawer that is using the currently opened Skeletal Mesh.
拆成實際關係:
目前打開的 Skeletal Mesh
└─ 例如 SK_Mannequin
Content Drawer 裡可能有
├─ MyPhysicsAsset
└─ SK_Mannequin_PhysicsAsset
兩者都以 SK_Mannequin 為對應 Mesh
└─ 所以都會出現在這個下拉選單中
也就是:
Physics 按鈕旁的選單,會列出 Content Drawer 中所有與目前這個 Skeletal Mesh 相容的 Physics Asset,你可以選其中一個來編輯。
你这个 Collection 里没有 UE 静态碰撞命名那套物体,比如 UCX_、UBX_、USP_、UCP_、MCDCX_。所以它不是"靠碰撞辅助网格导入物理"的路线。UE 对那套命名的识别在 FbxStaticMeshImport.cpp (line 2705)。
如果你导出的是 Alembic,那就没有 PhysicsAsset。Alembic 这边 static mesh 路径最多只会建 BodySetup,不是 UPhysicsAsset,见 AbcImporter.cpp (line 260)。
roadmap
人物物理
├─ 身體倒地、肢體碰撞
│ └─ Physics Asset:Bodies + Constraints
│
├─ 活著時被撞、身體偏移但仍追隨動畫
│ └─ Physical Animation / Physics Control
│
├─ 頭髮、裙擺、飾品的二級擺動
│ └─ AnimDynamics / Rigid Body / Chaos Cloth
│
└─ 肉體凹陷、軟組織
└─ Chaos Flesh 或專門形變方案

Chaos / Physics Simulation
-
在 Chaos Physics 模組中:
-
Rigid Body 或 Body Instance 是模擬單位
-
每個 Body 擁有:
-
質量、慣性矩
-
動態狀態(位置、旋轉、速度)
-
是否啟用模擬(Simulate Physics)
-
-
-
它可以被綁定到 Actor 的 Root Component 或 Skeletal Mesh 的骨骼。

这块分成 3 层看最清楚:`菜单文字`、`菜单是在哪组出来的`、`点下去真正执行到哪`。
**左上这个 `+` 菜单**
`+` 按钮本体在 [SSkeletonTree.cpp](/E:/UE_5.7/Engine/Source/Editor/SkeletonEditor/Private/SSkeletonTree.cpp:248),它调用 `CreateNewMenuWidget()`,菜单注册在 [SSkeletonTree.cpp](/E:/UE_5.7/Engine/Source/Editor/SkeletonEditor/Private/SSkeletonTree.cpp:1961)。
你圈出来这几项里,通用 Skeleton Tree 的部分在这里:
- `Add Socket`、`Add Time Blend Profile`、`Add Weight Blend Profile`、`Add Blend Mask` 的命令文字定义在 [SkeletonTreeCommands.cpp](/E:/UE_5.7/Engine/Source/Editor/SkeletonEditor/Private/SkeletonTreeCommands.cpp:32)
- 这些命令被放进 `SkeletonTree.NewMenu` 的地方在 [SSkeletonTree.cpp](/E:/UE_5.7/Engine/Source/Editor/SkeletonEditor/Private/SSkeletonTree.cpp:1976)
- `Add Virtual Bone` 子菜单也是在同一段里加进去的,见 [SSkeletonTree.cpp](/E:/UE_5.7/Engine/Source/Editor/SkeletonEditor/Private/SSkeletonTree.cpp:1979)
也就是说:
- `Add Socket`
- `Add Virtual Bone`
- `Add Time Blend Profile`
- `Add Weight Blend Profile`
- `Add Blend Mask`
这些本质上都是 `SkeletonEditor` 模块的菜单。
**`Add Box / Sphere / Capsule / Tapered Capsule`**
这 4 个不是 SkeletonEditor 原生菜单,是 `PhysicsAssetEditor` 往 Skeleton Tree 的 `CreateNew` 区域里扩展进去的。
位置:
- 命令文字定义在 [PhysicsAssetEditorActions.cpp](/E:/UE_5.7/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetEditorActions.cpp:77)
- 真正把它们塞进菜单的函数是 `FillAddPrimitiveMenu()`,在 [PhysicsAssetEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetEditor.cpp:199)
- PhysicsAssetEditor 把这个函数挂到 Skeleton Tree 的 `CreateNew` 扩展点,是在 [PhysicsAssetEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetEditor.cpp:258) 到 [PhysicsAssetEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetEditor.cpp:270)
所以你这个截图里的 `+` 菜单,其实是:
- 基础菜单:`SSkeletonTree`
- Physics Asset 特有扩展:`FPhysicsAssetEditor`
**右侧 `Body Creation / Constraint Creation` 面板**
这个面板的字段不是硬编码一行行 Slate 拼的,核心是一个 details view 绑定到 `UPhysicsAssetGenerationSettings`。
位置:
- 面板 widget 创建在 [PhysicsAssetEditorSharedData.cpp](/E:/UE_5.7/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetEditorSharedData.cpp:3561)
- `DetailsView->SetObject(GetMutableDefault<UPhysicsAssetGenerationSettings>())` 在 [PhysicsAssetEditorSharedData.cpp](/E:/UE_5.7/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetEditorSharedData.cpp:3575)
- 这些字段的声明在 [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:63)
你截图右边这些字段基本都在这里:
- `Min Bone Size` [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:63)
- `Primitive Type` [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:71)
- `Vertex Weighting Type` [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:75)
- `Auto Orient to Bone` [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:79)
- `Walk Past Small Bones` [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:87)
- `Create Body for All Bones` [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:91)
- `Disable Collisions by Default` [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:95)
- `Lod Index` [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:103)
- `Constraint Creation` 里的 `bCreateConstraints` / `AngularConstraintMode` 在 [PhysicsAssetUtils.h](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Public/PhysicsAssetUtils.h:83)
**点下去之后真正生成碰撞体 / body 的地方**
如果你要改"行为"而不是"UI",重点看这几处:
- `Add Sphere / Capsule / Box / Tapered Capsule` 命令绑定到 `OnAddSphere()` 等,在 [PhysicsAssetEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetEditor.cpp:1283)
- 它们最后都会走 `AddNewPrimitive(...)`,在 [PhysicsAssetEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetEditor.cpp:2327)
- 如果需要先给骨头创建 body,再给 body 生成碰撞,会走 `MakeNewBody(...)`,在 [PhysicsAssetEditorSharedData.cpp](/E:/UE_5.7/Engine/Source/Editor/PhysicsAssetEditor/Private/PhysicsAssetEditorSharedData.cpp:2717)
- 真正按骨骼和顶点权重拟合碰撞几何的底层算法在 `PhysicsUtilities`:
- `CreateFromSkeletalMesh(...)` [PhysicsAssetUtils.cpp](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Private/PhysicsAssetUtils.cpp:586)
- `CreateCollisionFromBoneInternal(...)` [PhysicsAssetUtils.cpp](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Private/PhysicsAssetUtils.cpp:697)
如果你下一步是想改这几个菜单的显示、禁用逻辑,还是想改 body 自动生成算法,我可以继续直接把调用链缩到最少一组文件。

为每类关节定义行为模板:
膝盖/手肘
└─ 接近铰链
├─ 一个主要 Swing 方向
├─ 另一个 Swing 很小
└─ Twist 很小
肩膀/髋关节
└─ 接近球窝
├─ 两个 Swing 都较大
└─ Twist 中等
脊柱
└─ 多段小角度累积
├─ 每节角度不大
└─ 整条脊柱合起来才有明显弯曲
头发/裙摆
└─ 软链
├─ Swing 较大
├─ Twist 受限
└─ 可加入 Angular Drive 或控制系统
是。`ragdoll` 运行时依赖的就是 `PhysicsAsset` 里的 `body` 和 `constraint`。
最直接的链路在运行时这里:
- `USkeletalMeshComponent::InitArticulated()` 会拿当前 `PhysicsAsset`
- 按 `PhysicsAsset->SkeletalBodySetups` 创建 `Bodies`
- 按 `PhysicsAsset->ConstraintSetup` 创建 `Constraints`
对应源码:
- 统计并实例化 body 的入口:[SkeletalMeshComponentPhysics.cpp](/E:/UE_5.7/Engine/Source/Runtime/Engine/Private/SkeletalMeshComponentPhysics.cpp:834)
- `InstantiatePhysicsAsset(*PhysicsAsset, ..., Bodies, Constraints, ...)`:[SkeletalMeshComponentPhysics.cpp](/E:/UE_5.7/Engine/Source/Runtime/Engine/Private/SkeletalMeshComponentPhysics.cpp:852)
- 按 `SkeletalBodySetups.Num()` 创建每个 `FBodyInstance`:[SkeletalMeshComponentPhysics.cpp](/E:/UE_5.7/Engine/Source/Runtime/Engine/Private/SkeletalMeshComponentPhysics.cpp:967)
- 按 `ConstraintSetup.Num()` 创建每个 `FConstraintInstance`:[SkeletalMeshComponentPhysics.cpp](/E:/UE_5.7/Engine/Source/Runtime/Engine/Private/SkeletalMeshComponentPhysics.cpp:1076)
所以结论可以拆成两句:
1. **没有 body,基本没有 ragdoll。**
因为真正进入物理模拟的是这些 `FBodyInstance`。`SetAllBodiesSimulatePhysics()` 也是直接遍历 `Bodies` 去开模拟:[SkeletalMeshComponentPhysics.cpp](/E:/UE_5.7/Engine/Source/Runtime/Engine/Private/SkeletalMeshComponentPhysics.cpp:1252)
2. **没有 constraint,不能形成正常"关节化"的 ragdoll。**
body 还能各自模拟,但骨段之间不会按你期望的关节限制连起来,表现更像散架/独立刚体,而不是标准人偶。
你现在在 Physics Asset Editor 里创建的内容,最终会落到这两个数据上:
- `body` -> `PhysicsAsset->SkeletalBodySetups`
- `constraint` -> `PhysicsAsset->ConstraintSetup`
自动生成这两者的编辑器侧逻辑也正是你刚看到的 `FPhysicsAssetUtils::CreateFromSkeletalMesh(...)`,它在生成 body 后也会顺带创建 parent-child constraint:[PhysicsAssetUtils.cpp](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Private/PhysicsAssetUtils.cpp:473) 和 [PhysicsAssetUtils.cpp](/E:/UE_5.7/Engine/Source/Developer/PhysicsUtilities/Private/PhysicsAssetUtils.cpp:508)
一句话说死:
- **ragdoll 一定依赖 body**
- **好用的 ragdoll 也依赖 constraint**
- **你在 Physics Asset 里调的 shape / body / joint,就是 ragdoll 真正在跑的那套数据**
如果你要,我下一步可以继续把"进入 ragdoll 时动画和物理是怎么切换的"那条源码链也拉出来。
UE 的核心設計不是"人體系統",而是通用的 articulated rigid-body system 。Epic Games Developers+1
Thigh Body
↕
Constraint
↕
Calf Body
Constraint 再用幾個數值表示:
Linear X/Y/Z
Swing 1
Swing 2
Twist
Drive
Damping
Break threshold

SpawnParams.Aggregate = UseAggregate;
BodyInst->InitBody(..., SpawnParams);
它表达的是:
创建这个 BodyInstance 时
└─ 是否把它加入一个 Aggregate
这里的 Aggregate 不是"聚合数据结构"这种泛泛概念,而是物理引擎里的:
把一组彼此关联的刚体,作为一个集合交给底层物理场景管理。
在 Skeletal Mesh / ragdoll 场景中,很多 Body 都属于同一个角色:
一个 SkeletalMeshComponent
├─ pelvis body
├─ spine body
├─ head body
├─ arm bodies
└─ leg bodies
如果逐个完全独立注册,底层物理场景要分别处理这些对象。Aggregate 的设计意图是把同一组关联 Body 聚在一起,减少某些场景管理、宽相碰撞或注册层面的开销。
InstantiatePhysicsAsset
└─ 遍历 SkeletalBodySetups
└─ new FBodyInstance
└─ 构造 FInitBodySpawnParams
├─ OwningComponent
├─ bPhysicsTypeDeterminesSimulation
└─ Aggregate
└─ UseAggregate
└─ InitBody(...)
└─ 创建 Chaos 刚体并注册到物理场景
UseAggregate 通常是前面根据当前实例化方式决定出来的某个 aggregate 指针或句柄
這個詞不能簡單理解成「銀河的」就結束了。它的結構是:
galaxy 星系、銀河系
└─ galactic 與星系有關的;達到星系尺度的
└─ galactic civilization
星系文明/能向整個星系擴張的文明
galaxy 是 /ˈɡæ.lək.si/,重音在第一節;但變成 galactic 後,重音移到第二節:
GAL-ax-y /ˈɡæləksi/
ga-LAC-tic /ɡəˈlæktɪk/
這是因為後綴 -ic 經常把重音拉到它前面一個音節:
PHOtograph → photoGRAPHic
EConomy → ecoNOmic
GALaxy → gaLACtic
所以不要沿著 galaxy 讀成 GALactic 。標準讀法就是 ga-LAC-tic 。Oxford 也標為 /ɡəˈlæktɪk/,詞源可追到希臘語中表示「銀河/乳白色星帶」的詞。编辑Oxford Learner's Dictionaries+1
更深一層,galaxy 最初和希臘語「乳、奶」有關。因為古人看到夜空中的銀河像一道乳白色帶,因此英語 Milky Way 和希臘來源的 galaxy,命名意象其實是同一個
其中俄語姓氏 Кардашёв 更接近 Kar-da-SHYOV ,因為最後的 -шёв 在俄語中含有接近 /ʂof/ 或 /ʂɵf/ 的音;但英語世界通常按拼寫讀成 kar-DAH-shev。所以這裡存在兩套讀法:
俄語原名:kar-da-SHYOV
英語慣用:kar-DAH-shev
Musk口語:接近 kar-DAH-shəv
Kardashev scale
他完整名字是 Nikolai Kardashev ,蘇聯/俄羅斯天體物理學家。1964 年,他提出用一個文明能夠控制和使用多少能量,來衡量其技術規模。编辑Wikipedia+1
最常見的三類是:
Type I
└─ 行星級
可利用一顆行星尺度的能源
Type II
└─ 恆星級
可利用一整顆恆星的能源
Type III
└─ 星系級
可利用整個星系尺度的能源
所以 Musk 前面說:
galactic civilization
後面馬上提 Kardashev three,兩者是直接連起來的:
galactic civilization
≈ Kardashev Type III civilization
≈ 星系級文明
不過他說 "you're not even registering as a Kardashev three" 時,語法稍微省略了。完整意思是:
You're not even registering as a Kardashev Type III civilization.
按卡爾達肖夫尺度衡量,我們甚至還完全算不上三級文明。
第一個問題是 as opposed to 後面為什麼接 worry ,而不是 worrying。
按較完整、較規整的書面形式,通常會說:
as opposed to worrying about small squabbles on Earth
因為這裡的 to 是介詞,不是不定詞標記:
as opposed to
└─ opposed to + 名詞/動名詞
└─ worrying about...
但 Musk 即興說話時用了:as opposed to worry about...
這是口語中的結構滑動。說話者腦中可能在兩個框架之間切換:
rather than worry about...
as opposed to worrying about...
最後說成了混合形式:
as opposed to worry about...
所以你可能是在問:這是不是不標準?為什麼我看著不對,但又能聽懂?
答案是:對,嚴格按規範語法,worrying 更整齊;但即興演講裡這種混合很普通,不妨礙理解。
squabble 的語感。
它不只是普通的 argument。它常暗示:為小事吵來吵去,而且從更大尺度看很不值得。
把地球政治、國家衝突之類壓縮成:small squabbles on Earth
航太語境裡常見的省略:tons delivered/launched to orbit
其中 delivered 或 launched 被省略了。
send 10 million tons to orbit
└─ 把一千萬噸東西送入軌道
10 million tons to orbit
└─ 被送入軌道的一千萬噸
每送入軌道一噸 AI 衛星/計算設備,可以形成約 100 kW 的計算功率或電力負載。
第一,供電。
在地球軌道附近,太陽輻照度大約是 1.36 kW/m²。假設太陽能電池效率約 30%,每平方米約產生 400 W。因此 100 kW 需要數百平方米級別的太陽能板;它面積很大,但薄膜太陽能板可以做得很輕。
第二,散熱。
AI 設備消耗的 100 kW 電力,最後基本都會成為約 100 kW 熱量。太空沒有空氣,不能靠風扇或空氣對流,只能靠紅外輻射把熱排走。NASA 將熱控制描述為管理航天器吸收、產生、儲存和排出的熱量;對高功率 AI 衛星而言,散熱器會是主要質量和面積來源之一。编辑NASA
地面太陽能
└─ 大氣吸收與散射
└─ 雲層
└─ 晝夜
└─ 季節與太陽高度角
└─ 面板通常不能永遠正對太陽
軌道太陽能
└─ 沒有大氣、雲層
└─ 可讓面板持續朝向太陽
└─ 某些軌道可大幅縮短進入地影的時間
單看正午、晴天、面板正對太陽:提升其實不大
地球大氣層外,在日地距離處,太陽輻照度約為:
1361 W/m² 。编辑earth.gsfc.nasa.gov+1
地面晴朗正午、面板正對太陽時,實際到達地面的直射加散射功率常可接近約 1000 W/m²。因此就「最佳瞬時輸入」比較:
太空:約 1361 W/m²
地面:約 1000 W/m²
└─ 只高約 36%
同樣一平方米面板,在晴朗正午,送到近地軌道是否突然多出五倍電力?不是,只是約 1.3~1.5 倍量級。
Musk 所說的五倍,實際是在比較「全年平均可用發電」
地面太陽能最大的損失,不只是大氣,而是一天和一年中大量時間沒有滿功率。
例如固定式地面面板:
夜晚
└─ 0
清晨、傍晚
└─ 太陽斜射,輸出低
陰天、雲層
└─ 顯著降低
冬季
└─ 日照時間短、入射角差
因此一套標稱 100 MW 的地面太陽能場,全年平均輸出可能只有額定功率的約 15%~30%。這就是所謂 capacity factor。
軌道面板若能長時間正對太陽,並避免大部分地影,其平均利用率可能接近 80%~95%。於是:
軌道平均利用率:約 90%
地面平均利用率:約 20%
90 ÷ 20 = 4.5 倍
所以 Musk 的「至少五倍」比較接近:
相同額定太陽能電池面積,在全年平均發電量上,軌道系統可能是普通地面系統的數倍。
而不是太陽光本身增強五倍。
但普通近地軌道並不是「always sunny」
這是他講得最粗糙的地方。
一般近地軌道衛星每繞地球一圈,都可能進入地球陰影。以國際太空站相似的軌道為例,一圈約 90 分鐘,其中可約有 55 分鐘日照、35 分鐘處於地影。NASA Technical Reports Server
普通 LEO
├─ 日照:約 60%
└─ 地影:約 40%
NASA 的資料也指出,近地軌道典型 eclipse fraction 可以接近 40%。NASA
因此在普通 LEO:
仍然需要電池,而且面板與電池要為地影期間的 100 kW 計算負載服務。
例如若每圈有 35 分鐘沒有陽光,100 kW 負載至少需要:
100 kW × 35/60 h
≈ 58 kWh
還未計入電池放電深度、退化、轉換損失和備援。這些都增加大量質量。
主要方法不是用電線,而是把電能轉成一束定向電磁波,傳到地面後再轉回電力。
太空太陽能板
└─ 陽光 → 直流電
└─ 直流電 → 微波/雷射
└─ 定向波束射向地面
└─ 地面接收站
└─ 微波/雷射 → 直流電
└─ 逆變器 → 電網交流電
目前主流有兩條路。
1. 微波傳輸
這是最常被研究的方案。
太空中的發射端會有一個巨大的相控陣天線。它不是像普通廣播那樣把能量向四周散掉,而是讓大量小天線單元精確控制相位,使電磁波在地面某一區域疊加成較集中的波束。
太陽能板
└─ 產生 DC 電
功率電子設備
└─ DC → 微波 RF
相控陣
└─ 數十萬或更多發射單元
└─ 控制每個單元的相位
└─ 將波束指向地面接收場
JAXA 的太空太陽能系統研究就是將太陽能轉成微波或雷射,再無線傳到地面;其微波方案的核心難題是高功率波束的精確控制。编辑Kenkai+2编辑Kenkai+2
地面怎麼接收
地面不是普通太陽能板,而是一片很大的 rectenna:
rectifying antenna
整流天線
它由大量小型天線和整流二極體組成:
微波
└─ 接收天線產生高頻交流電
└─ 二極體整流
└─ 直流電
└─ 逆變器
└─ 併入電網
所以 rectenna 本質上是:
antenna
└─ 接收電磁波
rectifier
└─ 把高頻交流整流成 DC
NASA 很早就做過公里級微波傳電實驗,也研究過 2.45 GHz 的太陽能衛星與 rectenna 系統。编辑NASA Technical Reports Server+2编辑NASA Technical Reports Server+2
2. 雷射傳輸
另一種方法是:
太陽能板產生電
└─ 驅動高功率雷射
└─ 雷射射向地面
└─ 專用光伏接收器
└─ 光 → 電
雷射的波長短,因此同樣大小的發射孔徑可以形成更窄的波束。JAXA 也在研究這種 laser-based SSPS。编辑Kenkai
但雷射有一個明顯問題:
微波
└─ 較能穿過雲、霧和部分降雨
雷射
└─ 很容易被雲層阻擋
└─ 對瞄準精度要求更高
└─ 功率密度過高時有視力與航空安全問題
因此,大規模穩定供電通常更偏向微波;雷射可能適合較小型、較精準的特殊用途。
為什麼波束不會全部散掉
它其實一定會散開,只是可以透過大型天線壓縮擴散角。
波束衍射的大致關係是:
擴散角
≈ 波長 ÷ 發射天線直徑
所以:
波長越短
└─ 越容易形成窄波束
發射天線越大
└─ 波束越集中
距離越遠
└─ 地面的光斑仍然越大
例如從地球同步軌道約 36,000 公里高度傳輸,即使使用數百米至公里級發射天線,地面接收場仍可能需要數公里寬。
這也是為什麼太空太陽能衛星不是:
一顆小衛星射一條細光線到一棟房子。
而更像:
公里級太空發射陣列
└─ 幾公里級微波波束
└─ 幾公里級地面 rectenna 農場
NASA 2024 年的太空太陽能評估方案就包含面向地球的微波發射面板,以及地面大型接收系統。编辑NASA
如何保證波束不射偏
典型設計會由地面 rectenna 發送一個低功率導引訊號:
地面發送 pilot signal
└─ 衛星相控陣接收
└─ 根據相位反向校正
└─ 功率波束自動鎖定接收站
這叫 retrodirective beam control,反向定向控制。
如果衛星失去導引訊號:
pilot signal 消失
└─ 發射單元無法維持相干疊加
└─ 波束擴散或關閉
└─ 不應繼續集中輸出
這種設計不是讓衛星「知道地面經緯度後盲射」,而是讓波束以接收站實際發出的參考訊號為鎖定基準。
能量損失有多大
完整鏈路中每一步都會損失:
太陽光
└─ 太陽能電池
DC 電
└─ 微波功率放大器
微波
└─ 發射天線與波束傳播
地面 RF
└─ rectenna 整流
DC
└─ 逆變與併網
可以用一個假設例子理解:
太陽能電池:35%
DC → 微波:80%
波束捕獲:85%
微波 → DC:85%
併網:95%
總效率
= 0.35 × 0.80 × 0.85 × 0.85 × 0.95
≈ 19%
也就是說,落到衛星太陽能板上的太陽能,最後可能只有約兩成進入電網。實際數字取決於架構,現在還沒有成熟商業系統可以給出統一結果。
NREL 對美國大型地面光伏使用的容量因子範圍約為 21.4%~34.0%,所以「太空日照約為地面年均輸出的三至五倍」在採光層面可以成立。编辑atb.nrel.gov 但 NASA 2024 年的評估也強調,太空太陽能必須承擔能源轉換、無線傳輸、巨大結構、發射及維護等完整系統成本,不能只用日照倍率判斷競爭力。编辑NASA
因此更準確的結論是:
軌道太陽能的 3~5 倍
└─ 是採光與容量因子的優勢
無線傳電的損失
└─ 會吃掉其中相當一部分
最後輸送到地面的淨電量
└─ 未必比地面太陽能高很多
這也正是為什麼 Musk 在演講裡不是主張把太空 AI 的電送回地球,而是主張:
在軌道發電
└─ 就地供給軌道 AI
這樣便能完全刪掉最吃虧的一段:
電力 → 微波/雷射 → 地面接收 → 再變成電力
如果電力最終仍然要送回地面,太空太陽能的優勢很容易被傳輸損失和建設成本抵消;
最有現實意義的用途:直接處理太空中產生的資料
例如地球觀測衛星每天拍攝大量影像。傳感器能產生的資料量,可能遠大於衛星能下載到地面的頻寬。
這時可以在軌道上先做:
衛星拍攝 100 TB 原始影像
└─ AI 在軌辨識
├─ 哪裡有森林火災
├─ 哪裡有船舶
├─ 哪裡有洪水
├─ 哪些影像被雲遮住
└─ 哪些影像值得保留
最後只傳回
└─ 少量有效影像
└─ 座標
└─ 警報
└─ 分析結果
NASA 已經測試讓軌道中的地球觀測衛星自行分析影像並決定下一步觀測目標;ESA研究太空資料中心的直接動機之一,也正是衛星資料不斷增加,而下載到地面成為瓶頸。编辑NASA+1
這種工作很合理,因為:
資料本來就在太空
└─ 不必先從地面上傳
原始資料很大
└─ 處理結果很小
要求快速反應
└─ 不必等待地面往返
NASA所稱的 edge computing 就是這個意思:在資料產生地附近先處理,而不是把所有原始資料送回中央資料中心。编辑NASA Science+1
第二種意義:讓太空設備自主運作
未來若有大量衛星、月球基地、採礦設備、機器人和飛船,不能所有事情都等待地面控制。
軌道 AI
├─ 衛星避碰
├─ 軌道調度
├─ 故障診斷
├─ 自主維修
├─ 月球/火星機器人控制
├─ 星際導航
└─ 通信網路路由
對月球還只是約一秒多的單程延遲;對火星,單程通信延遲會達數分鐘至二十多分鐘。這種情況下,本地計算不是降低成本的附加功能,而是設備能否自主工作的前提。NASA 的高性能太空計算項目就是面向未來航天器的 AI、科學處理和自主能力。编辑NASA+1
但這只能證明「太空需要一些高性能計算」,不能直接證明需要 Musk 所說的 terawatt 級。
比較適合
├─ 不要求極低延遲的批次推理
├─ 大型科學模擬
├─ 密碼學或數值搜索
├─ 已有資料駐留在太空的分析
└─ 輸入輸出小、計算量大的任務
不太適合
├─ 大量地面資料持續讀寫
├─ 即時遊戲與互動
├─ 高頻金融交易
├─ 依賴龐大地面資料庫的服務
└─ 需要頻繁更換 GPU 的工作

terrafab/advanced technology fab,不只是設計晶片,而是要自己建立一座能實際製造晶片的半導體工廠。
fab 就是 semiconductor fabrication plant ,也就是晶圓製造廠,不是一般意義的研究室。Intel 對 fab 的定義也是實際生產晶片的 semiconductor factory。编辑Newsroom+1


`"Graph is not editable."` 这句文案本身在这里:
- [BlueprintDetailsCustomization.cpp](/E:/UE_5.7/Engine/Source/Editor/Kismet/Private/BlueprintDetailsCustomization.cpp:5003)
真正把图设成只读的是这条链:
- `SGraphEditor` 绑定可编辑/只读状态:[BlueprintEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:1777)
- 可编辑条件:`InEditingMode() && !FBlueprintEditorUtils::IsGraphReadOnly(InGraph)`
见 [BlueprintEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:10769)
- `IsGraphReadOnly()` 的底层判断:
`!InGraph->bEditable`,或者它是 `Interface / Delegate / MathExpression` 图
见 [BlueprintEditorUtils.cpp](/E:/UE_5.7/Engine/Source/Editor/UnrealEd/Private/Kismet2/BlueprintEditorUtils.cpp:2811)
- `bEditable` 字段本身定义在 [EdGraph.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/EdGraph/EdGraph.h:81)
你这张图里更像是 **PIE/Simulation 导致当前 BlueprintEditor 不在 EditingMode**,不是单纯 graph 资源自己 `bEditable=false`。
因为 `InEditingMode()` 在 `PIE` 时会额外判断当前蓝图类是否允许边运行边改,逻辑在:
- [BlueprintEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:824)
也就是:
- 不在 PIE:直接可编辑
- 在 PIE/Simulation:只有"允许运行中重编译"的蓝图才可编辑
- 否则整个 graph 面板就只读
所以你要追"为什么你这个 `GameModeBase` 蓝图现在只读",优先看这两个点:
1. 当前是不是在 `Simulation/PIE`
2. `InEditingMode()` 在 PIE 下把这个蓝图判成了 `NotSafe`
如果你要,我可以继续把"这个 `GameMode` 类为什么在你当前工程里被判成 PIE 下不可改"再往项目设置那层追下去。
在 UE 里,`Kismet` 基本就是 **Blueprint 可视化脚本系统的历史名字和编辑器层名字**。
现在如果你在源码里看到:
- `Kismet` 模块
- `K2`
- `Kismet2`
- `FKismetEditorUtilities`
- `BlueprintEditor` 在 `Editor/Kismet/`
大多都可以理解成"Blueprint 编辑器/编译器/节点系统这一套"。
几个层次可以这样分:
- `Kismet`:偏编辑器层,Blueprint Editor、细节面板、图编辑器集成这些
例如你现在看的 [BlueprintEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp)
- `BlueprintGraph`:偏节点和图 schema
比如各种 `K2Node_*`
- `Kismet2`:老命名,通常是 Blueprint 工具函数和编辑器工具链那层
例如 [BlueprintEditorUtils.cpp](/E:/UE_5.7/Engine/Source/Editor/UnrealEd/Private/Kismet2/BlueprintEditorUtils.cpp)
- `K2`:通常特指 Blueprint 这代图系统,像 `UEdGraphSchema_K2`、`UK2Node_*`
历史上它来自 UE3/早期 UE4 的可视化脚本命名,后来用户层主要都叫 Blueprint 了,但源码和模块名里保留了很多 `Kismet`/`K2`。
如果压成一句话:
**Kismet = UE 源码里对 Blueprint 可视化脚本编辑系统的一套历史命名。**
如果你要,我可以顺手把 `Kismet / Kismet2 / K2 / BlueprintGraph` 这几个模块在源码里的职责边界再画清楚。
如果你问的是 **`GameMode` 和你刚才这套 `Kismet / BlueprintEditor / not editable` 的关系**,结论是:
**`GameMode` 本身不是一套单独的编辑器系统,它只是一个常见的 Blueprint 父类。**
所以你打开 `BP_ThirdPersonGameMode`,走的还是同一套 `Kismet/BlueprintEditor` 图编辑逻辑,不是 `GameMode` 专属编辑器。
源码里能看到几层关联:
1. `GameModeBase` 默认就是创建成 Blueprint 资产的
在 [BaseEditor.ini](/E:/UE_5.7/Engine/Config/BaseEditor.ini:272)
2. 项目默认 `GameMode` 也是指向 `AGameModeBase`
在 [BaseEngine.ini](/E:/UE_5.7/Engine/Config/BaseEngine.ini:17)
3. 编辑器里针对 `GameMode` 有一层"设置面板定制",方便你在 Project Settings / World Settings 里改 `DefaultPawnClass`、`HUDClass`、`PlayerControllerClass` 这些
核心在 [GameModeInfoCustomizer.h](/E:/UE_5.7/Engine/Source/Editor/UnrealEd/Public/GameModeInfoCustomizer.h:119)
4. 但 **graph 是否可编辑** 这件事,不是 `GameMode` 自己决定的,还是 BlueprintEditor 统一判定:
- [BlueprintEditor.cpp](/E:/UE_5.7/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:10769)
- [BlueprintEditorUtils.cpp](/E:/UE_5.7/Engine/Source/Editor/UnrealEd/Private/Kismet2/BlueprintEditorUtils.cpp:2811)
我这轮没看到 `GameMode` 在 `IsGraphReadOnly()` 里有硬编码特殊分支。
所以你截图里 `not editable`,更像是:
- 当前在 `Simulation/PIE`
- BlueprintEditor 当前不在 `EditingMode`
- 而不是"因为这是 GameMode,所以 graph 天生不能改"
如果你问的是 **运行时关联**,那是另一层:
- `GameMode` 只存在服务端 / authority 侧
- PIE 可以用 override 覆盖它
见 [PlayLevelNewProcess.cpp](/E:/UE_5.7/Engine/Source/Editor/UnrealEd/Private/PlayLevelNewProcess.cpp:77) 和 [PlayLevel.cpp](/E:/UE_5.7/Engine/Source/Editor/UnrealEd/Private/PlayLevel.cpp:3172)
一句话压缩:
**GameMode 和 Kismet 的关系,就是"GameMode 常常是用 Blueprint 写的一个类,而 Kismet/BlueprintEditor 是编辑它的通用系统";`not editable` 不是 GameMode 专属规则。**
如果你要,我可以继续把你这个 `BP_ThirdPersonGameMode` 在 `Simulation` 时为什么会落到 `InEditingMode() == false` 再往下追到具体配置。
从 `GameMode` 自己往外发散,源码里最核心的是这张关系图:
`World -> AuthorityGameMode -> GameSession / GameState / PlayerController / PlayerState / HUD / DefaultPawn / Spectator`
**1. 它先怎么"存在"**
`GameMode` 不是普通场景 Actor,它是 `UWorld` 在开局时挂上的"服务端规则对象"。
- `UWorld` 里直接存的是 `AuthorityGameMode`,而且注释写明了"只在 server 有效"
[World.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/Engine/World.h:1404)
- 真正创建它的是 `UWorld::SetGameMode()`
[World.cpp](/E:/UE_5.7/Engine/Source/Runtime/Engine/Private/World.cpp:5823)
- 选哪个类来生成,是 `UGameInstance::CreateGameModeForURL()` 决定的
[GameInstance.cpp](/E:/UE_5.7/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:1505)
类选择顺序的起点是:
- `WorldSettings.DefaultGameMode`
[GameInstance.cpp](/E:/UE_5.7/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:1521)
- 还可以被 URL 里的 `?GAME=` 覆盖
[GameInstance.cpp](/E:/UE_5.7/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:1524)
**2. 它直接"管"哪些类**
`AGameModeBase` 里最直接的关联字段都在这:
- `GameSessionClass`
- `GameStateClass`
- `PlayerControllerClass`
- `PlayerStateClass`
- `HUDClass`
- `DefaultPawnClass`
- `SpectatorClass`
- `ReplaySpectatorPlayerControllerClass`
定义都在 [GameModeBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameModeBase.h:79)
运行时实例也直接挂在它身上:
- `GameSession`
- `GameState`
[GameModeBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameModeBase.h:127)
这里最关键的一点是:
- `GameMode` 只在服务端 authoritative
- `GameState` 才是复制给客户端看的那份状态
`GameStateBase` 也明确写了:
- `AuthorityGameMode` 在非 authority client 上会是 `NULL`
- 客户端应该看 `GameState`
[GameStateBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameStateBase.h:45)
**3. 它的职责链**
如果按"玩家进来以后发生什么"看,`GameMode` 基本控制这整条流程:
- `InitGame()`:最早初始化参数和 helper classes
[GameModeBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameModeBase.h:56)
- `InitGameState()`:初始化 `GameState`
[GameModeBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameModeBase.h:64)
- `PreLogin()` / `Login()` / `PostLogin()`:管玩家登录与接入
[GameModeBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameModeBase.h:293)
- `HandleStartingNewPlayer()`:允许玩家真正进入游戏
[GameModeBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameModeBase.h:365)
- `ChoosePlayerStart()` / `FindPlayerStart()`:选出生点
[GameModeBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameModeBase.h:403)
- `RestartPlayer()`:重生总入口
[GameModeBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameModeBase.h:439)
- `SpawnDefaultPawnFor()`:真正生 Pawn
[GameModeBase.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameModeBase.h:451)
所以如果你问"GameMode 本身最像什么",答案不是"一个普通蓝图类",而是:
**它是服务端这一局游戏规则、玩家接入、出生/重生、默认角色体系、HUD/Controller/Pawn 配置的总入口。**
**4. `GameModeBase` 和 `GameMode` 的区别**
`AGameModeBase` 是基础版。
`AGameMode` 在它上面多了一整套 **Match 状态机**:
- `StartMatch()`
- `EndMatch()`
- `RestartGame()`
- `MatchState`
- `ReadyToStartMatch()`
- `ReadyToEndMatch()`
都在 [GameMode.h](/E:/UE_5.7/Engine/Source/Runtime/Engine/Classes/GameFramework/GameMode.h:39)
所以可以这么选:
- 只要"默认 pawn / controller / login / spawn"这类基础规则:`GameModeBase`
- 还要"比赛开始/结束/等待中"这套 match flow:`GameMode`
如果你要,我下一步可以继续把这张图再往外扩成一张"`GameMode -> GameState -> PlayerController -> Pawn -> PlayerState` 的完整职责边界图"。


服務端 GameMode
└─ 判斷玩家人數足夠
└─ 設定倒計時/準備開賽
GameState
└─ 複製 RemainingTime
└─ 每個客戶端 HUD 顯示 3、2、1
真正到 0 時:
GameMode::StartMatch()
↓
MatchState = InProgress
↓
GameState 收到並複製 MatchState
↓
所有客戶端更新 UI、解除角色控制限制
所以不能寫成:
Client HUD
└─ 直接改 GameMode.MatchState
Client Input
↓
PlayerController Server RPC
↓
GameMode
↓
GameState replicated property / MatchState
↓
Client HUD
玩家個別狀態不應放 GameState
還要再分一次:
GameMode
└─ 整局規則與服務端裁決
GameState
└─ 整局共享狀態
PlayerState
└─ 單一玩家、但所有人需要知道的狀態
├─ 分數
├─ 隊伍
├─ 擊殺
├─ 死亡
└─ Ready 狀態
PlayerController
└─ 單一連線的命令入口
├─ 接收本地輸入
├─ 發 Server RPC
└─ 管本地 UI
Spectator Class
└─ 玩家处于观战状态时使用的 Pawn 类
Replay Spectator Player Controller Class
└─ 播放 Network Replay 时使用的 PlayerController 类
Spectator Class:观战者控制的"身体"
普通玩家结构是:
PlayerController
└─ Possess
└─ DefaultPawn / Character
进入观战后则变成:
PlayerController
└─ 使用 SpectatorPawn
└─ 自由飞行相机、跟随其他玩家或自定义观战逻辑
SpawnSpectatorPawn() 会在 PlayerController 当前的位置和旋转生成一个 SpectatorPawn,并初始化为该 Controller 的观战对象。
ABP 的运行对象不是 Character,也不是 Skeletal Mesh Asset 本身,而是:
USkeletalMeshComponent
└─ 创建并持有一个 UAnimInstance
└─ 这个 UAnimInstance 的类来自你的 Animation Blueprint
ABP_Unarmed 资产编译后,本质上会生成一个 UAnimBlueprintGeneratedClass。当某个 SkeletalMeshComponent 把它设为 Anim Class 时,组件会创建一份运行时 AnimInstance。Epic 的 Get Anim Instance 文档也明确写着:返回的是驱动该 Skeletal Mesh Component 的动画实例,而且这个实例是 transient 的运行时对象。Epic Games Developers+2
BP_AglinaCharacter
└─ Mesh:USkeletalMeshComponent
├─ Skeletal Mesh = Aglina 的 SkeletalMesh Asset
├─ Animation Mode = Use Animation Blueprint
├─ Anim Class = ABP_Unarmed_C
└─ Anim Script Instance = ABP_Unarmed_C 的运行时实例
SkeletalMeshComponent
├─ 持有当前骨骼网格
├─ 收集动画更新时间
└─ 调用自己的 AnimInstance
↓
AnimInstance 更新变量
↓
State Machine / Blend Space / Montage 求值
↓
AnimGraph 产生最终 Pose
↓
SkeletalMeshComponent 把 Pose 写到骨骼
↓
蒙皮网格变形并渲染
因此 ABP 最终控制的是:一个 SkeletalMeshComponent 的骨骼 Pose
官方也把 Animation Blueprint 定义为控制 Skeletal Mesh 最终动画姿势的专用 Blueprint。Epic Games Developers
選中的是 Body ,所以右側 Details 顯示的是質量、阻尼、Physics Type 等剛體屬性;中心點、旋轉、尺寸屬於 Body 裡面的 Capsule Primitive,不屬於 Body 本身。
RBAN(Rigid Body Animation Node)
所以你這個資產:PA_Mannequin_RBAN可以拆成:
PA
└─ Physics Asset
Mannequin
└─ 給 Mannequin 骨架使用
RBAN
└─ Rigid Body Animation Node
└─ 專門配合 AnimGraph 裡的 Rigid Body 節點使用
它不是普通「整個人物倒地」用的 ragdoll Physics Asset。它更偏向:
角色原本動畫
└─ Rigid Body Anim Node
└─ 在動畫姿勢上追加局部物理模擬
├─ 頭髮
├─ 裙擺
├─ 配件
├─ 胸部/軟組織骨骼
└─ 次級擺動骨骼
官方 API 也直接把 RBAN 解釋成 Rigid Body Anim Node;Physics Asset 的 Solver Type 還會區分:
World
└─ 世界物理模擬/ragdoll
RBAN
└─ AnimGraph 的 Rigid Body 節點內部模擬
兩者都使用 Physics Asset,但求解環境不同。RBAN 節點通常擁有自己的局部物理解算器,不等同於 Skeletal Mesh Component 在世界中啟用 Simulate Physics。Epic Games Developers
是否真的互相排斥,取決於這兩個 Body 之間是否啟用了碰撞
pelvis capsule
└─ 需要覆蓋骨盆和髖部
spine_01 capsule
└─ 需要覆蓋下腹和腰部
如果兩者完全不重合,中間很容易留下碰撞空洞;如果為了貼合人體而稍微放大,它們自然會在腰部交疊。
這本身沒有問題,前提通常是:
pelvis ↔ spine_01
└─ Constraint 相連
└─ 彼此 Collision Disabled
相鄰 Body 已經由 Constraint 維持關係,通常沒有必要再讓它們互相碰撞。否則初始狀態一旦重合,Chaos 會同時收到兩條互相衝突的要求:
Constraint:兩個 Body 應維持關節位置
Collision:兩個 Body 必須立刻分開
碰撞關係是按 Body Pair 設定的:
上臂 ↔ 前臂
└─ 通常禁用
因為是直接相連的關節
前臂 ↔ 胸口
└─ 可以啟用
防止手臂穿進軀幹
左手 ↔ 右手
└─ 視需求啟用
頭髮物理 Body ↔ 頭部/肩部 Body
└─ 通常啟用
用來阻止頭髮穿過身體
hysics Asset Editor 裡,沒有一個獨立清單直接列出「這個 Body 與哪些 Body 是碰撞對」。UE 5.7 的標準查看方式是:選中一個 Body,讓視口用顏色顯示它與其他 Body 的配對狀態
Epic 官方文檔對這個顏色規則的描述
No Gravity 適合檢查 Body 初始重疊:開始模擬後,可以拖動或碰撞剛體,觀察它們是否互相排斥、爆開或因 Constraint 持續抖動。Selected Simulation 則只模擬目前選中的 Body 及其骨骼層級。编辑Epic Games Developers
McKinsey & Company
麥肯錫公司(McKinsey & Company)創立於1926年, 是全球最具影響力的頂尖管理諮詢公司之一 。其專注於為企業與政府的高層管理者提供戰略、營運、組織及技術等層面的解決方案,有「顧問界的高盛」之稱,常與波士頓顧問公司(BCG)、貝恩策略顧問公司(Bain & Company)並列為全球三大管理顧問公司(MBB)。
rhombus 菱形
└─ square 正方形:四個角又恰好都是 90°
They press the emote key, and they emote.
傳統英語的 emote 是動詞,意思是把情緒明顯地表現出來,尤其帶有演員以臉部、聲音和肢體「演出情緒」的感覺。Merriam-Webster
進入網路遊戲後,它被具體化成一套可觸發的角色行為:
wave 揮手
dance 跳舞
cheer 歡呼
laugh 大笑
sit 坐下
taunt 挑釁
所以遊戲中的 an emote 通常是「一個預設的社交/表意動畫」,不必真的表達某種內心情緒。揮手、坐下、跳舞也都可以叫 emotes。G2A+1
它比 animation 更窄:
animation
└─ 任何動畫:走路、攻擊、死亡、開門......
emote
└─ 玩家主動觸發、主要用來表意或社交的動畫
這是英語常見的「名詞直接放在另一個名詞前面」:
jump key 跳躍鍵
attack key 攻擊鍵
interact key 互動鍵
emote key 表情動作鍵
這裡不是「情緒的鑰匙」,而是the key used to trigger an emote
最後的 and emote
語法上,主語 they 同時控制兩個動詞:
所以完整展開是:They press the emote key, and they emote.
不過從遊戲系統的精確責任來看,實際上是:
player presses the key
└─ game triggers an emote
└─ character plays the animation
講者把「玩家操作」和「角色執行」合併成了日常說法 the player emotes。
發音
emote
美式:/ɪˈmoʊt/ 或 /iˈmoʊt/
近似:ih-MOHT
句子中連讀:
and emote
/ən dɪˈmoʊt/ → 常聽成 ən-emote
emote 是從 emotion 反向造出的動詞:看到 emotion ,英語使用者把它理解成「emote 所產生的東西」,於是造出了 emote 。OED 記錄它約在 1900 年開始出現。Oxford English Dictionary
而更深一層的 emotion 來自拉丁語:
ex- 向外
movere 移動
└─ emovere:攪動、使向外移動
因此它最底層的隱喻不是單純「有感情」,而是:
內部受到攪動,然後把這種狀態向外顯露。
遊戲裡的 emote 正好把這個抽象概念變成可播放的角色動作。
edifying
edifying /ˈed.ə.faɪ.ɪŋ/ 是形容詞,意思不是普通的「有趣」,而是:
能讓人的知識、思想或品格有所提升的;有教益的。
接近:
-
instructive:能教會你東西
-
educational:具有教育性的
-
enlightening:讓你忽然看明白一些事情
-
beneficial to the mind:對思想有所增益
詞典通常把它解釋為「以改善心智或品格的方式提供知識」。它略帶正式、書面甚至傳統宗教語感。Cambridge Dictionary+2
所以講者在教程結尾說:I hope this was edifying.
不是僅僅希望你記住了操作步驟。
而更像希望這整個過程讓你理解得更深、腦中建立起了一些東西。
它底層其實是「蓋房子」edify 最早不是抽象的「教育」,而是「建造」。
Latin aedificare
└─ build, construct
└─ 建造房屋
└─ figuratively build up a person
└─ 建立人的思想、信念、品格
它與 edifice「大型建築物、宏偉建築」是同一家族。
edifice
└─ 建成的建築物
edify
└─ 把人的思想/品格建造起來
edifying
└─ 具有這種「建造作用」的
這個「物理建造 → 精神建造」的隱喻在中世紀宗教語境中尤其常見:不是把知識塞進人腦,而是逐層把一個人的信仰或心智結構搭建起來。後來詞義才擴展為一般的「有教益、增長見識」。编辑Etymology Online+1
所以它比 educational 多一點「人被改善了」的味道:
educational
└─ 與學習、教育有關
informative
└─ 提供了資訊
edifying
└─ 資訊不只進來了,還把你的心智往上建了一層
edifying /ˈed.ə.faɪ.ɪŋ/ED-uh-fy-ing
edification /ˌedəfəˈkeɪʃən/ 教益;啟迪
Animation Blueprint 的 Event Graph
├─ 技術上:能修改哪些 UObject/Actor/Component
└─ 動畫架構上:應該負責修改哪些資料
核心答案是:Event Graph 不只可以修改動畫變數。它是一個以 UAnimInstance 為 Self、運行在 Game Thread 上的普通 Blueprint Event Graph。只要取得有效引用,技術上也能呼叫外部 Actor、Component 和其他 Blueprint 的函數。
abp是class
class有setting,
class 有運行
運行Character class,內部有輸入檢測邏輯,viewport不根據輸入 響應

IA_Move =trigger Event file




└─ 使用這套骨骼語言產生 Pose 的程序


Compatible skeletons can share Animation Sequences, Montages, Animation Blueprints, and more.
manquin Skeleton--SKM-quin
manquinSkeleton-ABP
myModelSkeleton-SKM-myModel
在retarget Manager内设置mymodel Skeleton为 mannquin的compatible Skeleton,于是mymodelSkeleton--manquinABP
需求是my model SKeleton的模型骨骼"name"和层级数量必须和manquin Skeleton完全相同?

Character 是 ABP Class 的成員變數
但沒有開啟 Instance Editable
右下角 Anim Preview Editor > Edit Defaults

fire hydrant
water main 地下自來水主管
└─ fire hydrant 消防栓
└─ fire hose 消防水帶接上去取水
hydr- 就是「水」這個詞根,和以下單詞同源:來自希臘語 hydōr,即「水」。
hydro-
├─ hydraulic 液壓的
├─ hydrate 補充水分
├─ dehydration 脫水
├─ hydrogen 氫
└─ hydrant 供水裝置
hydrant 已經負責表達「取水裝置」,前面的 fire 說明用途:
fire hydrant
= hydrant for firefighting
= 用於消防的取水栓
類似:
fire truck
消防車,不是「火做的車」
fire door
防火門,不是「著火的門」
fire hydrant
消防用取水栓

是class,有default, 分instance editable,
class綁定skeletal mesh(preview 特殊)
ABP Generated Class 的成員屬性。
有 Class Default:
└─ Character = None
沒有 Instance Exposure:
└─ Instance Editable = false
運行時:
└─ 每個 AnimInstance 自己執行 Set Character,
將它改成自身所屬的 Character Actor。
剛選擇時,它只改變當前 Persona Preview Scene,所以提示:
The preview mesh has changed, but it will not be able to be saved until it is applied to the asset.
點擊:Apply To Asset之後,才把這個 Preview Mesh 選擇持久化到目前的 ABP_Aglina 資產。官方也把 Preview Mesh 定義為「為目前資產設定的預覽 Skeletal Mesh」,其用途只是編輯器預覽。编辑Epic Games Developers+2编辑Epic Games Developers+2
Preview Mesh承接ABP 產生Pose

名片的核心可以理解為:
把現場的人際接觸,轉換成可在未來重新啟動的關係接口。
例如展會上在一小時內接觸二十個人,只交換口頭姓名,幾天後很容易混淆。名片把姓名、公司、職位、接觸背景和聯絡方式綁在一起,成為記憶索引。對銷售、商務拓展、顧問、律師、房仲、招聘者、自由職業者、企業代表和政治活動人員,這種功能仍然存在。
名片還有一個經常被忽略的功能:它是一種低強度的聯絡授權。
直接詢問私人電話、通訊軟體帳號,可能帶有侵入性;主動遞出名片則是在表達:「可以通過這些公開渠道繼續聯絡。」因此它同時劃定了職業身份與私人身份的邊界。
現在當然仍然存在,只是「紙片」不再是唯一形態。日本等商務文化中,交換實體名片仍是一種正式的身份確認儀式,甚至對遞交和接收方式有明確慣例。编辑Japan Guide LinkedIn 也正式提供個人 QR Code,掃描後直接進入個人資料並建立聯繫,實際上就是數位名片。编辑LinkedIn 現在更常見的是混合形式:紙質名片保留姓名、公司和視覺識別,再加 QR Code,將人導向 LinkedIn、作品集、公司頁面或聯絡人資料。
輝達早期尚未建立市場地位時,名片是直接的銷售工具。2026 年的一則韓國報導提到,黃仁勳回憶自己曾親自前往首爾龍山電子市場發名片。當時名片所表達的是:「這家公司與這個人存在,請記住,之後可能合作。」编辑매일경제
名片不是用來完整複製一個人,而是補上當場接觸後最容易遺失的資訊。
見面時,臉已經被直接看見;真正缺少的是姓名怎麼寫、職位是什麼、屬於哪家公司、之後怎麼聯絡。因此傳統名片優先保存「臉無法提供的資訊」,而不是再次印一張臉。
照片並不是不能用。當「記住這張臉」比「記住這家公司」更重要時,照片就會出現,例如:
-
房仲、保險業務、政治人物;
-
模特、演員、自由工作者;
-
大型展會中接觸大量陌生人的場合;
-
線上數位名片,因為接收者可能從未見過本人。
cel shading /sel ˈʃeɪdɪŋ/
cel 和 cell 發音完全相同,都是 /sel/,
Britannica 對 cel animation 的描述正是:人物動作被畫在一連串透明 celluloid sheets 上,再疊到靜態背景上拍攝。编辑Encyclopedia Britannica

看到的 ILM texture、Blue channel 做高光 mask、手動控制明暗分界,精確指的是:
GUILTY GEAR Xrd -SIGN-
不是泛指整個《Guilty Gear》系列,也不是後來的 GUILTY GEAR -STRIVE-。
GUILTY GEAR 系列
├─ 早期作品
│ └─ 主要使用 2D sprite
│
├─ GUILTY GEAR Xrd -SIGN-
│ └─ 這套著名的「看起來像 2D 動畫的即時 3D」技術來源
│ ├─ ILM texture
│ ├─ 手繪光影控制
│ ├─ 修改 vertex normal
│ ├─ 陰影 threshold
│ └─ 反轉模型描邊
│
├─ Xrd -REVELATOR-
├─ Xrd REV 2
│ └─ 延續並改良 Xrd 的整體視覺管線
│
└─ GUILTY GEAR -STRIVE-
└─ 下一代作品,不能直接假定材質資料和 Xrd 完全相同
最直接的證據是,2014 年那篇詳細拆解 ILM texture 各通道的技術訪談,完整標題就明確寫著 《GUILTY GEAR Xrd -SIGN-》的即時 3D 圖形秘密 ;文中所分析的也是該作基於 Unreal Engine 3 建立的材質與製作流程。编辑4Gamer
2015 年最常被 Blender、Unity 和 Unreal 教程引用的 GDC 演講,正式名稱是:
GuiltyGearXrd's Art Style: The X Factor Between 2D and 3D
Arc System Works 官方對該演講的介紹也是由《Xrd》的技術美術本村・C・純也講解這套美術與程式研發成果;配套演講 PDF 的標題則直接標成 GUILTY GEAR Xrd -SIGN- 。编辑arcsystemworks.com+1
