DaVinci-13

独立游戏开发者 · UE5 C++ 技术博客
记录学习和创业中的点滴

记一次团结引擎 + iOS 26 上的 TMP InputField 乱码 Bug

一句话速览 团结引擎 1.8 打包到 iOS 26 上时,若 TMP InputField 开启了 Hide Mobile Input,输入字符后 InputField 会先失活再重新获得焦点,此时文本被全选,再输入任意字符,开头的第一个字符变成乱码。这是 Unity 2021 时代的老 Bug 在团结引擎上的复现。 一、场景:一个"本不该出问题"的输入框 故事从一个非常常规的需求开始:给 iOS 端的用户做个输入框,需要屏蔽掉系统键盘自带的输入预览条(就是那个键盘上方悬浮的白色条)。 做法也很常规——勾上 TMP_InputField 的 Hide Mobile Input(代码里就是 shouldHideMobileInput = true)。 在编辑器里测试一切正常。打包上 iOS 26 真机之后,Bug 出现了。 二、现象:精确到每一步的复现路径 预期的行为 步骤 正常应发生的事 ① 点击输入框 聚焦,弹出键盘 ② 输入若干字符 输入框正常展示字符 ③ 点击输入框外部再点回来 光标定位到最后,继续输入正常 ④ 多轮输入 全文无乱码,一切正常 实际的行为(Bug 复现路径) 步骤 实际发生的事 ① 点击输入框 ✅ 聚焦,键盘弹出 ② 输入若干字符(如 “Hello”) ✅ 显示正常 ③ 输入框失活 → 再激活(获得焦点) ⚠️ 文本被全选(全部高亮) ④ 再输入任意字符(如 “X”) ❌ 开头的字符变成乱码,如 “䮙ello” 或类似不可识别字符 这个 Bug 不是偶发——稳定复现,只要 Hide Mobile Input + 输入框经历"失活→重新聚焦"这个流程,必现。 ...

July 14, 2026 · 2 min

我对 AI 的一点基础认识(一):AI 开发可以再分两层

写在前面 这是一篇"主观认识"系列的开篇。我是一个做了十年游戏 / 客户端开发的工程师,今年才开始认真碰 AI,水平大致在"能调 API、看得懂科普、论文还吃力"的初级阶段。 这个系列不追求严谨,也不打算教别人什么——只是把我自己对 AI 的一些粗浅但真实的认识记下来,既是梳理,也方便以后回看自己当时有多 naive。 第一篇,先聊一个对我来说很重要的"分法":把"AI 开发"再拆成两层。 一、AI 开发可以再分两层:算法侧 vs 应用侧 概念:我以前把"做 AI"想简单了 很长一段时间里,我默认"做 AI" ≈ “训练模型”。直到自己真上手去用 AI 做事,才发现这个词底下其实藏着两条几乎不相交的路: AI 算法(模型侧 / Algorithm side):研究怎么"造出那个会思考 / 会生成的东西本身"。它关心模型架构、训练、微调、推理优化、底层框架(PyTorch / JAX 那一套)、数据和数学。这一侧的产出物是"模型 / 能力"。 AI 应用开发(工程侧 / Application side):拿到现成的、或别人微调好的模型,把它真正塞进产品和工作流里用起来。它关心 API 调用、Prompt 工程、RAG、Agent 编排、向量数据库、评估与线上监控。这一侧的产出物是"能用的功能 / 产品"。 🔧 技术校准(AI 专家视角):这个二分法在业界有对应的说法。研究 / 模型侧常叫 ML Research / Deep Learning;把模型落地成系统的那一侧,近年被 Chip Huyen 等人明确称为 AI Engineering,也叫 Applied ML / ML Engineering。需要注意:两层之间并没有一道墙——微调(fine-tuning)、MLOps、模型压缩这些恰好卡在中间,所以"算法"和"应用"更像光谱的两端,而不是非黑即白。 对比:两条路的难度维度根本不同 AI 算法(模型侧) AI 应用开发(工程侧) 像什么 科研:深、窄、靠硬功 工程:广、快、靠整合 核心门槛 懂模型、懂数学 / 系统 懂产品、懂怎么把模型用出价值 周期 长,迭代慢 短,能快速出 demo 我的位置 门外,只浅尝过 正在摸门 我自己是游戏 / 客户端工程师出身,天然更靠近应用侧:我不需要从零训一个大模型,但我能用"API + RAG"很快把一个知识库变成能对话的东西。一度我因此产生一种错觉——“原来我也能做 AI 了”。后来才意识到,我做的只是应用侧里很薄的一层。 ...

July 10, 2026 · 1 min

2026 下半年学习路线图

为什么要写这个 跨四个领域的并行学习,如果不把路线拆清楚,很容易陷入"什么都想学、什么都推进不动"的状态。这篇路线图不是一份完美计划,而是一张"此刻的自我定位地图"——知道自己站在哪里、下一站去哪里、哪些路暂时不走。 四个领域按目标性质可以粗分为两类:产出驱动型和基础建设型。Unity 自定义渲染管线、UE5 Steam 项目是"先做出东西来再说";GAMES101、OpenGL、机器学习课程则更偏向打基础——短期内不一定出成果,但决定你一年后能走多远。两类要并行,但节奏和验收标准不一样。 一、Unity:自定义渲染管线 目标 从写到跑通一个完整的 SRP(Scriptable Render Pipeline),理解渲染管线是怎么"串起来"的。 拆解 从 Built-in RP 切到 URP,先搞清楚 URP 的 Asset/Renderer/RenderPass 分层 手写一个最简单的自定义管线(不继承 URP,自己写 RenderPipeline 子类),跑通最基本的渲染 往管线里加自己的 Pass:后处理、自定义光照、G-buffer 输出 跟已有的 SRP 教程对标一下差异 这里容易翻车的是"一上来就想做大而全的管线"。正确的姿势是先跑通最简版本——一个能渲染纯色 Cuboid 的自定义管线已经值 60 分了,后面的 pass 是往里插的。 验收 Unity 场景里有一个物体是用你自己的自定义管线渲染的,能切回 Built-in 对比效果。时间不要拖超过两周。 二、UE5:第一个能上架 Steam 的项目 这个目标本身有歧义,需要先拆清楚——“能上架 Steam 程度"不等于"做一个惊天动地的大作”,而是:有完整循环(开始→游玩→结束)、没有崩溃级 bug、有商店页面的最小体量游戏。 方向建议 跟 Unity 的 SRP 学习不太一样——那个偏技术实验,这个偏产品交付。所以项目体量一定要小到能一个人 3-4 个月收尾。具体做什么我不替你做判断,但你心里要有数:如果是俯视角潜行、小型解谜、视觉小说这种 Scope,可行。如果是开放世界第三人称刷刷刷,这里大概率是坑。 技术要点 Gameplay Ability System 如果是目标项目的核心,值得现在就学 上架流程的坑不在游戏本身,在 Steamworks 接入、打包配置、商店图素材、Depot 上传——这些最好提前两周单独排时间 第一次上架建议走 Steam Direct,准备 100 USD 费用 误区 “先做个完整的 Demo 再考虑上架”——不是的。做一些核心玩法后就该跑一遍完整的打包和上架流程(用临时名字),确认这个链路没断,再回头完善内容。上架是另一个技能树,不是游戏开发的自然延伸。 ...

July 10, 2026 · 1 min

动画插件 Fresh Cooked Tween 入门:让 UE5 动画插值更顺手

前言 在 UE5 日常开发里,我们经常需要做各种“过渡动画”: UI 面板淡入淡出 物体平滑移动和缩放 相机参数渐变 数值从 A 过渡到 B(例如血条、进度条) 这些需求可以用 Timeline、动画蓝图或手写 Tick 实现,但当项目里“轻量过渡动画”越来越多时,代码和蓝图会逐渐分散。Fresh Cooked Tween 这类 Tween 插件的价值,就是把这类逻辑统一成更高复用、可读性更好的工作流。 1. Fresh Cooked Tween 是什么 Fresh Cooked Tween 是面向 Unreal 的 Tween 动画插件,核心目标是: 用更简洁的方式描述“某个值在一段时间内如何变化” 提供常见缓动(Easing)曲线 支持回调与链式组织,降低样板代码 一句话理解:它把“插值过程”从零散的 Tick 逻辑中抽离出来,变成结构化的动画任务。 2. 它解决了什么问题 1) 降低样板代码 手写插值通常要自己管理: 起始值、目标值 已经过时间 每帧更新 完成回调 中途取消/中断 Tween 插件会把这些通用步骤封装好,让你聚焦“做什么动画”,而不是重复“怎么驱动时间”。 2) 统一动画语义 当团队都用统一 Tween 风格时,像“EaseOut、Yoyo、Loop、Delay”这些概念更容易沟通。 3) 适合技术美术协作 对于技术美术和玩法程序协作场景,Tween 非常适合做: UI 动效原型 镜头参数微调 交互反馈(按钮弹性、悬停位移、提示浮动) 3. 核心概念(入门必懂) 无论具体 API 名称如何,Tween 工作流通常都围绕以下概念: ...

April 8, 2026 · 2 min

UE5 C++ 脚本常用父类:生命周期、常用属性/函数/委托速览

前言 在 UE5 C++ 开发里,“选对父类”几乎决定了脚本的生命周期、可放置位置、初始化时机,以及你能用到哪些系统能力(输入、碰撞、网络复制、UI、动画等)。 这篇文章按“实战常用频率”整理: 常见父类分别适合做什么。 每类对象的核心生命周期顺序。 常用属性、函数和委托(含高频回调)。 说明:本文聚焦入门和日常开发高频内容,细节会因引擎版本和项目架构(单机/联机)略有差异。 1. UObject:一切反射对象的基础 适用场景 纯数据对象 工具类对象 不需要直接出现在场景中的逻辑对象 生命周期要点 Constructor:构造默认值。 PostInitProperties:属性初始化后调用。 BeginDestroy / FinishDestroy:销毁流程。 常用属性/函数 GetWorld():部分上下文可用,不是所有 UObject 都有有效世界。 GetOuter():获取所属外部对象。 IsValid()(配合对象指针检查):避免访问失效对象。 常见委托 UObject 本身没有像 Actor 那样丰富的生命周期委托,但可以参与你自定义的动态委托系统。 2. AActor:关卡中最核心的可放置对象 适用场景 场景实体(可见或不可见) 可复制的游戏逻辑载体 挂组件、处理交互、触发器、机关等 生命周期(常见顺序) Constructor OnConstruction(编辑器放置或属性变更后触发) PreInitializeComponents PostInitializeComponents BeginPlay Tick(启用时每帧) EndPlay Destroyed 常用属性 PrimaryActorTick.bCanEverTick:是否允许 Tick。 bReplicates:是否参与网络复制。 NetUpdateFrequency:网络更新频率。 Tags:对象标签,快速分类检索。 常用函数 BeginPlay() / Tick(float DeltaSeconds) / EndPlay() SetActorLocation() / SetActorRotation() / SetActorTransform() Destroy() HasAuthority():联机场景判断服务器权限。 GetComponentsByClass():运行时检索组件。 常见委托 OnActorBeginOverlap OnActorEndOverlap OnTakeAnyDamage OnDestroyed 3. APawn 与 ACharacter:可控制角色核心 3.1 APawn 适用场景 可被 Controller 控制的对象 载具、飞行器、棋子等不一定是“人形角色”的可控实体 生命周期要点 继承 AActor 生命周期,同时常见控制链路是: ...

April 5, 2026 · 2 min

UE5 C++ 脚本的基本类型

前言 在 Unreal Engine 5 的 C++ 开发中,除了标准 C++ 类型,还会频繁接触 UE 自己封装的一套类型系统。本文作为入门草稿,先把最常用、最容易混淆的类型梳理清楚。 1. 数值与布尔类型 UE5 中可以直接使用标准 C++ 基本类型,但官方代码风格更常见的是固定宽度别名: int8 / uint8 int16 / uint16 int32 / uint32 int64 / uint64 float double bool 示例: int32 Health = 100; float MoveSpeed = 600.0f; bool bIsAlive = true; 说明: int32 在 UE 项目中非常常用,跨平台行为更稳定。 uint8 常用于小范围状态值或位标记。 布尔变量通常以 b 开头(如 bIsAlive),是 UE 常见命名习惯。 2. 字符串相关类型 UE 里最常见的文本类型有 3 个:FString、FName、FText。 为什么不建议在 UE5 C++ 脚本里优先用 C++ 原生 std::string: 与 UE 反射系统和编辑器生态耦合较弱,不能直接享受 UPROPERTY、蓝图暴露和常见序列化工作流。 与 UE 常用 API 对接时通常还要频繁做类型转换(std::string <-> FString / FText),会增加样板代码和维护成本。 本地化场景下,FText 有完整的文本管线支持;std::string 更适合纯底层逻辑,不适合直接做玩家可见文本。 UE 社区和官方示例主要围绕 FString、FName、FText,团队协作和排查问题时可读性更高。 FString 可变字符串,适合拼接、调试输出、运行时处理。 类似“通用字符串容器”。 FString PlayerName = TEXT("DaVinci"); FString Msg = FString::Printf(TEXT("玩家: %s"), *PlayerName); FName 不区分大小写语义(底层做了名称表优化)。 适合做标识符、标签、键值名、资源名。 频繁比较时通常比 FString 更高效。 FName SocketName = TEXT("WeaponSocket"); FText 面向本地化显示文本(UI 文本优先用它)。 需要给玩家看的文本,优先考虑 FText。 FText DisplayText = FText::FromString(TEXT("开始游戏")); 3. 常用数学结构体 UE5 提供了大量数学类型,最常见的是: ...

April 5, 2026 · 2 min

My First Post

Introduction This is bold text, and this is emphasized text. Visit the Hugo website!

February 15, 2026 · 1 min