自由学习记录(158)

不能直接"自动连接",但你可以通过 "手动搬运 + Rehash" 的方式,把它们收编进 pyenv-win 的管理体系中。

由于 pyenv-win 只认自己 versions 文件夹下的结构,

虚拟环境(venv) :如果你以前的项目里已经有 .venv 文件夹,它们内部记录的是旧的绝对路径 。收编后,这些旧的虚拟环境可能会失效。建议直接删掉旧的 .venv 文件夹,用新环境重新生成一个:python -m venv .venv

  • 更稳妥的方法 :如果原来的 Python 里没装太多复杂的库,最推荐的做法是直接 pyenv install 3.10.11 重新装一遍,然后用 pip install -r requirements.txt 恢复库,这样最干净,不会有路径残留问题。

截图要求你将 ...\bin...\shims 放在 PATH 的最前面(High Priority)。

  • 原因 :Windows 寻找 python 命令是按 PATH 列表从上到下挨个找的。
  • 风险 :如果你以后安装了其他软件(比如某些 IDE 或工具)也带了 Python,或者你没卸载干净旧 Python,它们的路径可能会排在 pyenv 前面。
  • 如果你以后安装了其他软件(比如某些 IDE 或工具)也带了 Python,或者你没卸载干净旧 Python,它们的路径可能会排在 pyenv 前面。
  • 后果 :到时候你敲 python ,系统会跳过 pyenv 去执行别的 Python,导致 pyenv global 失效,让你抓狂。

也是好事啊,ue里就内置python,总不能抢占了吧,所以这些都是为掌控欲强的用户设计的,

为了不让大脑过载,你只需要记住这 5 个 核心动作:

动作 命令 什么时候用?
安装 pyenv install 3.x.x 想要一个新版本时。
查看 pyenv versions 忘了自己装了啥,或者确认当前在用谁。
全局切 pyenv global 3.x.x 想改全电脑默认的 Python 时。
项目切 pyenv local 3.x.x 最常用! 进入项目文件夹后,锁定该项目版本。
刷新 pyenv rehash 救命药! 发现命令不灵、或者刚装完新版本/插件时,敲一下。

  1. 一个终极原则(避坑指南)
    只要你用了 pyenv ,请刻在脑子里:
    永远不要再通过 .exe 安装包去官网下载 Python 了!
    所有的下载、删除、切换,全部交给 pyenv 这一间办公室处理。

在环境变量里没有看到pyenv额外加python的什么环境变量,为什么不用担心?
这正是
pyenv-win 设计最精妙的地方!你之所以在环境变量里看不到每一个具体 Python 版本的路径(比如 ...\versions\3.12.0 ), 是因为它使用了 "以一抵百"的垫片(Shims)机制
为什么不需要额外的环境变量?
传统的安装方式是把每一个 Python 的 bin 目录都塞进 Path 。但 pyenv 只在你的 Path 里塞了 两个固定的位置:

  • ...\.pyenv\pyenv-win\bin (存放 pyenv 命令本身)
  • ...\.pyenv\pyenv-win\shims (存放垫片程序

关键点: 无论你安装了 5 个还是 10 个 Python 版本,你的系统 Path 永远只需要这两行,保持得非常干净。
"垫片 (Shims)" 是如何工作的?
当你输入 python 命令时,系统并不知道你具体要用哪个版本,它只会在 Path 里找到 shims 文件夹下的一个名为 python.bat (或 .exe )的伪装程序:

  1. 拦截 :你敲 python ,实际上运行的是 shims 里的那个"伪装者"。
  2. 判断 :这个伪装者会立刻问 pyenv :"嘿,当前用户是在哪个文件夹?他有没有设置 local 版本?或者有没有 global 版本?"
  3. 转发 :一旦确定是 3.12,它就瞬间把你的指令转发给 ...\versions\3.12.0\python.exe

所以: 你不需要为每个版本加环境变量,因为 Shims 文件夹已经代表了所有版本
什么是 Shim(垫片/填隙片)?
在机械工程中, Shim 是一种塞进缝隙里的小垫片,用来对齐零件。在计算机软件中,它指的是 "透明拦截层"

rehash vs. refresh 有什么区别?
pyenv rehash(核心命令)

  • 字面意思:重新哈希/重新扫描。
  • 它在做什么 :它会扫描你所有已安装的 Python 版本(versions 文件夹),看看里面有没有新的可执行文件(比如你刚装了 pip 插件带的命令)。
  • 什么时候用
    1. 你刚用 pyenv install 装了一个新 Python 版本
    2. 你刚用 pip install 装了一个带有命令行工具的库 (比如 pytest flake8 black )。
  • 效果 :它会在 shims 文件夹里生成对应的"管家"文件。如果你不 rehash ,你可能敲 pytest 会提示"找不到命令",尽管你已经装了它。

Refresh(通常指刷新环境变量/终端)

重启你的 PowerShell/CMD 窗口 或者手动让 Windows 重新读取 PATH 变量。

没有 LFS 时?

Git 对所有文件(不管文本还是二进制)都是一视同仁:

每次修改 → 生成一个完整的新 blob(对象)

git gc 时尝试 delta 差量压缩(找相似对象做 diff)

但二进制文件(图片、视频、PSD、模型文件、exe 等)几乎无法有效 delta(改 1 个像素,整文件就变了)

结果就是:

仓库 .git/objects/ 和 packfile 里塞满巨大 blob

每次 push / pull / gc 都要读写海量数据 → 磁盘 IO 爆满、CPU 狂转

几百人同时提交 → git服务器直接卡死("磁盘IO卡死"就是这个场景)

Skills Marketplace(http://skillsmp.com)已收录超过 70 万个技能包,涵盖代码审查、文档生成、测试用例、安全审计、数据分析等各个领域。

Content 的本质Content 文件夹里的 .uasset .umap 二进制文件。AI 无法像阅读代码那样"阅读"模型或材质的内部数据,更无法直接修改它们。
在虚幻引擎(UE)中,

.uasset 资源文件是二进制格式的,Aider 无法像修改代码那样直接编辑它们。要实现"修改材质实例参数"或"绑定图片"的自动化,最高效的源码级流程是利用 UE Python API
你可以让 Aider 编写一段 Python 脚本,然后在 UE 编辑器中运行该脚本来完成修改。
核心实现流程

  1. 准备工作
    确保你的 UE 项目已启用以下插件:
  • Python Editor Script Plugin
  • Editor Scripting Utilities
  1. 让 Aider 编写 Python 自动化脚本
    你可以直接给 Aider 下达类似这样的指令:
    "编写一个 UE Python 脚本,修改路径为 /Game/Materials/MI_Test 的材质实例。要求:将标量参数 Roughness 设为 0.5 ,并将纹理参数 BaseTexture 绑定到 /Game/Textures/T_Color 。"
    如何在 UE 中执行

  2. 在 Aider 中生成文件 :让 Aider 将上述代码保存为 update_mi.py

  3. 在 UE 中运行

    • 方法 A:打开 UE 菜单 Tools > Control Assets > Python Console ,输入 py "你的脚本完整路径"
    • 方法 B:直接将脚本文件拖入 UE 界面(如果安装了相关辅助工具)。

适用场景 :纯 C++ 插件开发,或者使用外部同步工具(如 Perforce, PlasticSCM, 或网盘)来同步 Content 文件夹。
是的,Unreal Engine (UE) 项目根目录下的

Config 文件夹存储的是项目设置(Project Settings)以及引擎的配置文件。它采用 .ini 格式,用于控制项目配置、输入绑定、插件设置和打包选项,是版本控制中必须纳入的关键目录。

  • .aider.tags.cache.v4 (文件夹):这是 Aider 最关键的缓存。它存储了项目代码的"代码标签(Tags)"索引。Aider 靠它来理解代码之间的引用关系,从而即使不把所有文件加入对话,也能定位到相关的函数定义。
  • .aider.chat.history.md :这是 Aider 自动记录的聊天日志。它以 Markdown 格式保存了你和 AI 之间的所有对话记录和修改历史。
  • .gitignore 中的内容(可能) :如果你在启动 Aider 时它发现没有 Git 仓库,它会建议初始化并可能自动在 .gitignore 中加入上述两个缓存文件的路

.ignore 是 Aider 生成的吗?
结论:不是由 Aider 默认生成的。

  • Aider 规范 :Aider 默认使用 Git 进行版本控制,并严格遵循 .gitignore 的规则。
  • .ignore 的来源 :这个文件通常由 IDE 插件 (如 VS Code 的 "Ignore" 插件)或者某些 特定的 CLI 工具 生成。在你的截图中,它被识别为 "IGNORE 文件",且修改日期(4/5)早于 .gitignore 的最近修改日期(4/7)。
  • 注意 :在 Git 的逻辑中,.ignore 文件本身并没有官方效力,除非它是某些特定同步工具(如 Syncthing)的配置文件。

.sln 是一个派生文件 (Derived File)。只要你有 .uproject Source/ 文件夹,你随时可以右键点击 .uproject 选择 "Generate Visual Studio project files" 来重新生成它。

Aider 默认只在检测到 Git 仓库时才允许大规模操作。这是为了确保每一行 AI 生成的代码都有 Git 提交记录,方便你随时回滚(Undo)。

"You can /add any file in your project to the chat, even if it's not yet tracked by git. Once added, Aider can read and edit that file."
(你可以将项目中任何文件 /add 到对话中,即使它尚未被 Git 追踪。一旦添加,Aider 就能读取并编辑该文件。)


Repo-map: using 4096 tokens 表示 Aider 已经扫描了你的项目结构,并创建了一个"代码地图",这样 AI 就能知道不同文件之间的引用关系,而不需要读取每一个文件的全文。

复制代码
aider --model openrouter/openai/gpt-4o

aider --models openrouter/

In-chat Commands
启动时切换 (CLI Flags)
在终端启动 Aider 时,通过参数直接指定模型:

  • aider --model <模型名称> :指定主模型。
  • aider --list-models <搜索词> :在启动前列出匹配的模型名称。

最新版本的 Aider 支持为不同任务指定不同的模型以优化成本和性能:

  • --editor-model :专门用于代码编辑的模型。
  • --weak-model :用于简单任务(如生成 commit 信息、总结历史)的廉价模型。
  • --thinking-tokens :针对 Claude 3.7 Sonnet 等推理模型,可以设置思维链(thinking)的 token 预算,例如 --thinking-tokens 4k
  • /models <搜索词> :如果你不确定完整的模型 ID,可以用此指令搜索可用模型。
    • 示例/models claude 会列出所有包含 "claude" 字符的模型全称。
  • /think-tokens <数量> (针对推理模型):在切换到如 Claude 3.7 Sonnet 等支持推理的模型后,可用此指令设置"思考"部分的 Token 预算。
    • 示例/think-tokens 4k
  • /reasoning-effort <等级> (针对 o1 系列):控制推理模型的思考强度(如 low , medium , high

输入 /tokens 可以查看当前生效的模型信息、剩余上下文窗口以及计费标准。
针对
Silicon Flow (硅基流动) 这种兼容 OpenAI 接口的自定义 API,Aider 目前 无法直接在会话内 (in-chat) 通过一条指令同时修改 Base URL 和 API Key。
你需要先通过环境变量配置好 API 信息,然后在启动或会话内指定模型。以下是具体操作步骤:
会话内切换 (In-chat)
如果你已经按上述步骤启动了 Aider,想在会话中切换到 Silicon Flow 上的其他模型,直接使用 /model 指令:

  • /model openai/deepseek-ai/DeepSeek-R1
  • /model openai/Pro/deepseek-ai/DeepSeek-V3 (根据 Silicon Flow 具体的模型 ID 填写)

别名建议 :如果你觉得每次输入太长,可以在启动时设置别名:
aider --alias sf:openai/deepseek-ai/DeepSeek-V3

之后在会话内只需输入 /model sf 即可快速切换。
使用 .env 本地文件(最推荐)
在你的项目根目录下创建一个名为 .env 的文件,将 Silicon Flow 的配置写进去:
bash

复制代码
OPENAI_API_BASE=https://siliconflow.cn
OPENAI_API_KEY=你的SiliconFlow_API_KEY

优点: Aider 启动时会自动读取当前目录下的 .env 。你甚至可以为不同的项目设置不同的 Key,互不干扰。
使用 Aider 专用的 yaml 配置文件
在项目根目录创建 .aider.conf.yml ,直接定义模型和 API 行为:
yaml

复制代码
model: openai/deepseek-ai/DeepSeek-V3
openai-api-base: https://siliconflow.cn
openai-api-key: 你的SiliconFlow_API_KEY

优点: 连启动命令都省了,直接输入 aider 就能自动加载 Silicon Flow 的配置。
Editor Model (編輯模型) ------ 「代碼打字員」
這是一個比較特殊的角色,通常在主模型 無法穩定生成正確的代碼差異 (diff) 時被激活。

  • 職責: 專門負責將主模型的「意圖」轉化為具體的「代碼修改指令」。

  • 用途: 如果主模型很聰明但不太會寫 Aider 指定的 diff 格式,Aider 會請一個專門擅長寫 diff 的模型來幫忙完成最後的「寫入」動作。

  • 現狀: 對於 Claude 3.5 Sonnet GPT-4o 這種強大模型,它們通常自己就能兼任 Editor,所以你可能看不到獨立的 Editor Model。

    /model

    Aider v0.86.2
    Main model: openrouter/anthropic/claude-sonnet-4 with diff edit format, infinite output
    Weak model: openrouter/anthropic/claude-3-5-haiku
    Git repo: .git with 0 files
    Repo-map: using 4096 tokens, auto refresh

命令行参数的优先级高于配置文件。如果你在 .aider.conf.yml 中默认配置了 gpt-4o ,但想临时换用 claude-3-5-sonnet ,直接在启动时指定:
bash

复制代码
aider --model claude-3-5-sonnet-20240620

默认 开启的 (默认即生效)

  • stream: true :默认会流式输出字符。
  • pretty: true :默认会使用彩色终端和表情符号。
  • check-update: true :默认启动时会检查是否有新版本。
  • show-diffs: true :默认在修改代码后会显示差异(Diff)。

默认 关闭的 (需要你在配置文件中手动开启)

  • auto-commits: false 这是最关键的 。默认情况下,Aider 修改完代码后会问你"是否提交?",只有你输入 /commit 或设置 true 后才会自动提交。
  • architect: false :默认进入的是 code 模式(直接写代码)。最新的"先思考再写"模式(Architect)需要手动开启或启动时加参数。
  • chat-language :默认跟随系统环境(通常是英文)。如果你希望 AI 始终回中文,建议手动设为 zh
  • cache-prompts: false :由于不是所有 API 供应商都支持(目前 Anthropic 和 DeepSeek 官方支持较好),Aider 默认不强制开启缓存。
  • dirty-commits: false :如果你的 Git 仓库有未提交的改动,Aider 默认会警告你,甚至拒绝运行。

流做法是將 OpenCV 作為圖像輸入的橋樑,核心識別則依賴 MediaPipe。

本质上是一个连续信号问题,不是离散状态问题。摄像头里的人脸位置本来就是连续变化的,最后你还要做平滑、死区、灵敏度调节、阈值判断。这个时候直接输出:

  • HorizontalOffset[-1, 1]

  • VerticalOffset[-1, 1]

是最干净的底层接口。

Actor 比 Component 更适合第一版落地

第一版目标是先把整条链跑通,不是做最终最优架构。独立 Actor 的优点是:

  • 放进关卡就能跑

  • 生命周期清晰

  • 调试方便

  • 不需要先考虑挂到谁身上

  • 便于可视化和快速验证

Component 当然在长期架构上更灵活,但第一版会引入更多设计问题:

  • 挂在哪个 Actor 上

  • 是否要求宿主必须有 Tick

  • 多实例管理怎么做

  • 与摄像机/角色耦合边界怎么划

把核心检测和计算逻辑抽到 UObject / Component / Subsystem

这时再考虑复用性和架构收敛。

我给你一个很明确的判断:

  • 想要最快做成、后面不吃亏 → 选 归一化数值 + Actor

  • 想要最省脑但后面很快重构 → 方向标签版

  • 想要架构更漂亮但当前开发更慢 → Component 版

USTRUCT 是 Unreal 的反射宏。给结构体加上它以后,这个结构体就能被 UE 的反射系统识别,进而支持蓝图、序列化、编辑器显示、网络复制等一部分能力。

USTRUCT(...) 是给 UE 看的,不是普通 C++ 关键字。

用了 USTRUCT 的结构体,通常还要配 GENERATED_BODY()

结构体里的成员如果想暴露给蓝图或编辑器,一般还要写 UPROPERTY(...)

这个头文件通常还要包含对应的 xxx.generated.h,并且放在最后一个 #include

#pragma once

#include "CoreMinimal.h"

#include "FaceTrackerTypes.generated.h"

USTRUCT(BlueprintType)

struct FFaceTrackerResult

{

GENERATED_BODY()

UPROPERTY(BlueprintReadOnly, EditAnywhere)

bool bFaceVisible = false;

};

加了像 USTRUCTUCLASSUPROPERTYUFUNCTION 这些宏之后,UE 就会把它登记到自己的系统里。

就可能出现在:

编辑器 Details 面板里,能手动改值;

Blueprint 里,能读、能写、能连线调用;

序列化/保存加载/网络复制这些 UE 功能里。

这个变量能在 Unreal Editor 里显示出来,比如你点中某个 Actor,在右边 Details 面板里能看到这个变量,并且可能可以直接改。

UPROPERTY(EditAnywhere)

float Speed = 100.f;

这通常表示这个值可以在编辑器里改。

你把某个蓝图类、Actor 实例选中后,可能就能在 Details 面板看到 Speed

可以让它间接调用你写的 HLSL

Custom Material Expression 支持写自定义 HLSL,并且有 Include File Paths 这类能力,说明它本来就支持把代码组织到外部 include 文件里

.usf 更像 shader 源文件/实现文件.ush 更像 shader 头文件/include 文件

明确把 .usf 叫 Unreal Shader files ,用于存放引擎使用的着色器代码;而在社区官方教程里也直接把 .usf / .ush 分别解释成 Unreal Shader FileUnreal Shader Header

"生成出来的 HLSL"通常是:

  • 引擎内部编译产物/中间结果

  • 混有大量 UE 材质模板、宏、平台适配代码

  • 不是给你当成干净的、可长期维护的 .usf/.ush 源文件直接回写工程用的。

Material Parameter / Material Instance Parameter 跟 Sequencer 联动,所以视频里才会提到参数命名、唯一名之类的事。因为 Sequencer 要知道它到底驱动哪个参数。

FFaceTrackingResult 里的 F 表示它是一个 struct/value type 这一类的 UE 类型前缀 。更准确说,这是 Epic 的历史命名约定,不是标准 C++ 语法要求,也不是反射系统硬性要求必须这样写。

F:普通结构体 / 值类型 / 非 UObject 基础类型

S:Slate 相关类型里很常见

  • FFaceTrackingResult:一个结构体结果数据

  • AFaceTrackerActor:一个 Actor

  • UFaceTrackerComponent:如果以后写组件,通常这么命名

  • EFaceTrackingMode:如果以后做枚举,通常这么命名

  • IFaceTrackerProvider:如果以后做接口,通常这么命名

读代码时类型类别一眼可见

看到 Axxx,你知道这是场景对象。

看到 Uxxx,你知道这是 UObject 体系。

看到 Fxxx,你知道它更像一个数据包、数学类型、描述结构,而不是需要 GC 管理的对象。

UE 里很多经典类型都是 F

  • FVector

  • FVector2D

  • FTransform

  • FRotator

  • FHitResult

  • FColor

  • FString

  • FName

这些都不是 Actor,也不是普通 UObject 资源对象,而是"值型数据"。

F 类型

  • 常常可以按值传递或作为成员保存

  • 一般不走 UObject 的 GC 生命周期

  • 不是通过 NewObject / SpawnActor 这种方式实例化

  • 更像普通 C++ 数据结构

FFaceTrackingResult,就非常适合做:

  • 一帧检测结果

  • Blueprint 输出参数

  • 当前追踪状态缓存

虽然 USTRUCT(BlueprintType) 理论上不强制你一定叫 F...,但 Unreal 社区和官方代码都默认 struct 这么命名。

你如果不用这套约定,代码也许能编,但别人一看会觉得别扭,而且你自己以后读大型 UE 代码也会更混乱。

跟 UHT/反射生态配合时更清晰

Editor 界面本身,大量都是用 Slate 画出来的。

  • Slate

    底层原生 UI 框架,主要给 Editor、工具、插件、自定义面板用。

  • UMG

    Unreal Motion Graphics。它是更高层、更面向游戏开发者的 UI 系统。

    你在蓝图里拖按钮、图片、文本,大多是在用 UMG。

  • Slate / SlateCore

    UMG 底下很多能力最终还是建立在 Slate 上。

  • 反射系统 提供"有什么属性、什么函数、什么类型"的元数据

  • Details 面板系统 + Slate 决定"这些东西在 Editor 里怎么画出来"

比如一个 UPROPERTY(EditAnywhere)

  • 反射系统说:这里有个 float,可编辑

  • Property Editor 模块说:这个 float 应该显示在 Details 面板

  • Slate 负责真正画出那个数值输入框、分类折叠栏、标签文字

定义模块 ZMDRender 的构建规则。

PublicDependencyModuleNames.AddRange(new string[]

{

"Core", "CoreUObject", "Engine", "InputCore"

});

虚幻引擎(UE)的架构中,"一切皆模块"。你的项目 ZMDRender 确实是以一个外部模块的形式挂载到引擎中运行的。
Runtime 核心运行时模块 ( Engine/Source/Runtime )
这是引擎最核心的部分,包含了游戏运行所需的所有基础功能。

  • Core : 最底层的模块,包含基础数据类型、内存管理、容器(如 TArray , TMap )等。
  • CoreUObject: 实现了虚幻的反射系统(UObject、UClass 等)。
  • Engine: 包含了 Actor、Component、世界逻辑、物理、网络等最常用的游戏框架。
  • Renderer : 渲染器的核心逻辑(你现在的 ZMDRender 应该是与这个模块配合工作的)。
  • Slate / SlateCore: 虚幻的底层 UI 框架。
  • RHI (Rendering Hardware Interface): 硬件渲染接口,负责对接 DirectX, Vulkan, Metal 等底层 API。

Editor 编辑器模块 (Engine/Source/Editor )
这些模块只在编辑器环境下存在,负责处理我们在 UE 界面上看到的一切。

  • UnrealEd: 编辑器的核心模块。
  • BlueprintGraph: 处理蓝图节点、编译和逻辑。
  • LevelEditor: 场景编辑器的核心逻辑。
  • PropertyEditor: 负责你在"细节"面板看到的属性调节界面。

Developer 开发者工具模块 ( Engine/Source/Developer )
提供给开发者在开发阶段使用的工具,通常不打入发布包。

  • TargetPlatform: 处理不同平台的打包逻辑。
  • ShaderCompilerCommon: 负责着色器编译。
  • FunctionalTesting: 自动化测试相关。

Plugins 插件模块 ( Engine/Plugins )
UE 的很多高级功能其实也是以"插件"形式存在的模块。

  • Niagara: 粒子系统插件。
  • Chaos: 物理破碎系统插件。
  • EnhancedInput: 增强输入系统。

Programs 独立程序 ( Engine/Source/Programs )
这些是独立于引擎本体运行的辅助程序。

  • UnrealHeaderTool (UHT) : 扫描你代码里的 UCLASS() 等宏并生成 .gen.cpp 文件。
  • UnrealBuildTool (UBT) : 也就是你正在写的 .Build.cs 文件所服务的构建系统。

导出 Shipping(发行) 版本的游戏时,这些模块会被 UBT(Unreal Build Tool)自动排除,以减小安装包体积。

  1. 你的模块需要在手机端运行,不能PublicDependencyModuleNames 中依赖这些模块,否则打包会报错。

决定了引擎如何编译代码、渲染画面、压缩资产以及最终如何封装生成该平台可执行文件。
具体细节如下:

  • 编译与资产处理:确定目标平台架构(如 x64, ARM64)和资产优化策略(如纹理压缩格式 ASTC/DXT)。
  • 特性与限制:依据硬件能力启用或禁用渲染特性(光追、移动端优化)和功能模块。
  • 平台特定规则:处理签名、应用包结构(如 APK/IPA)、权限定义和存储限制。

构建系统集成 :它与 UnrealBuildTool (UBT) 紧密配合,决定了编译时使用的 C++ 编译器宏、链接库以及输出的可执行文件格式(.exe, .apk, .ipa 等)。

不同性能等级的设备(如移动端 vs 主机端),TargetPlatform 允许配置不同的 HLOD(层次细节) 策略或网格体简化程度,以确保在低配硬件上也能流畅运行。

定义不同硬件设备(如 Windows, iOS, Android, PS5 等)的各项参数与限制。

规定了特定平台支持的图形 API(如 DirectX 12, Vulkan, Metal)、纹理压缩格式、最大内存限制以及特定的着色器模型。

**平台覆盖(Platform Overrides)**来实现。

资产级的压缩设置

项目级的纹理组(Texture Group) 以及**平台覆盖(Platform Overrides)**来实现。
资产级:手动指定压缩类型 (Compression Settings)
在纹理编辑器(Texture Editor)的 Details 面板中,你可以直接为每张图片选择 Compression Settings

  • Default (DXT1/5, BC1/3):适用于普通颜色贴图。
  • Normalmap (BC5):专门用于法线贴图,通过丢弃蓝色通道并保留高精度的 RGBA 以减少伪影。
  • Masks (sRGB 禁用):适用于金属度、粗糙度或 AO 等遮罩贴图。
  • UserInterface2D:适用于 UI,通常不压缩或使用低损耗格式以保证文字清晰。
  • Grayscale:适用于单通道灰度图,节省空间。

项目级:纹理组配置 (Texture Group / Device Profiles)
虚幻引擎根据图片的用途将其分类为"纹理组"(如 World , Character , UI , Sky )。

  • 全局规则 :在 DefaultDeviceProfiles.ini 或项目设置中,你可以为每个组定义特定平台的默认压缩和分辨率限制。
  • LOD Group :在纹理设置中选择一个 LOD Group ,引擎在烘焙(Cooking)时会自动应用该组对应的平台压缩策略。

平台级:特定格式覆盖 (Platform Overrides)
对于跨平台项目,同一个资源可以根据目标硬件采取完全不同的策略:

  • 移动端特殊处理 :例如,你可以设置项目在打包 Android 时,普通贴图强制转为 ASTC 4x4 格式以平衡质量与内存,而在 PC 端则保持 BC7
  • 分辨率缩减 (Downscale) :在纹理编辑器中,可以利用 Downscale 选项针对特定平台(如移动端)进一步降低分辨率,而无需修改原始资产。

自动化处理:纹理编码与 RDO
对于需要极致优化容量的项目:

  • Oodle 压缩 :UE5 集成了 Oodle Texture ,可以开启 RDO (Rate Distortion Optimization)。这允许你在项目设置中全局调节纹理的压缩强度(Lambda 值),甚至可以针对单个纹理覆盖该强度,以在几乎不损失肉眼视觉质量的情况下显著减小安装包大小。

在虚幻引擎(Unreal Engine)中,每个模块(Module)都必须有且仅有一个唯一的 .Build.cs 文件

相关推荐
华法林的小助手2 小时前
[学习笔记]在ros humble里使用qt
笔记·qt·学习
智慧化智能化数字化方案2 小时前
向华为学习——解读质量管理培训 IPD基础知识研发质量管理【附全文阅读】
学习·华为ipd流程·ipd基础知识·研发质量管理
Fanfffff7202 小时前
前端进阶:从请求竞态到并发控制(系统学习笔记)
前端·笔记·学习
山甫aa2 小时前
STL---常见数据结构总结
开发语言·数据结构·c++·学习
小琪爱学习2 小时前
项目学习代码
学习
&&Citrus11 小时前
【CPN学习笔记(二)】Chap2 非分层颜色 Petri 网——从一个简单协议开始读懂 CPN
笔记·学习·php·cpn·petri网
小橘子83112 小时前
(学习)Claude Code 源码架构深度解析
学习·程序人生·架构
diablobaal14 小时前
云计算学习100天-第102天-Azure入门4
学习·云计算·azure
AI_零食14 小时前
Flutter 框架跨平台鸿蒙开发 - 自定义式按钮设计应用
学习·flutter·ui·华为·harmonyos·鸿蒙