Open WangShuXian6 opened 9 months ago
https://docs.unrealengine.com/5.3/zh-CN/working-with-modular-characters-in-unreal-engine/ 通过组合多个骨骼网格体组件来创建角色。
https://www.youtube.com/watch?v=CeaSv7eiWo8
https://youtu.be/7IUpa3Pxqug https://www.bilibili.com/video/BV1we4y1M7SV/?spm_id_from=333.337.search-card.all.click&vd_source=f259d77343588259f8e1b4ae567b1d34 使用UE5 Lyra示例项目作为样例,本会话将讨论添加、交换和自定义角色的各种可用技术。
Stylized Character Kit: Casual 01 风格化角色套件 https://www.unrealengine.com/marketplace/zh-CN/product/stylized-male-character-kit-casual?lang=zh-CN
打开 BP_ModularCharacter
选择风格化角色套件下的多个人物网格体
拖入 BP_ModularCharacter
选择 MESH_L_01 腿部组件 -细节-动画-动画模式-使用动画资产 要播放的动画-ThirdPersonIdle 此时,只有腿部有动画。其他部位静止。
重命名各个部分: FaceAccessory 脸部附属品 Hair 头发 Beard 胡须 Head 头 LowerBody 下肢 Hands 双手 UpperBody 上肢
删除重复的上肢
将 UpperBody 上肢 附加到 LowerBody 下肢 将 Hands 双手,Head 头 附加到 UpperBody 上肢 将 FaceAccessory 脸部附属品,Hair 头发,Beard 胡须 附加到 Head 头。
此时,依然只有下肢在运动
construction script 事件图表:
设置引领姿势组件 set leader pose component Lower Body 为领导者组件
其他部位组件全部为目标组件 FaceAccessory 脸部附属品 Hair 头发 Beard 胡须 Head 头 Hands 双手 UpperBody 上肢
下肢组件的骨骼动画将复制到内存中, 其他组件如果有相同的骨骼将使用该动画。 头发没有骨骼将不会使用骨骼动画。 优点是高性能, 缺点是其他部分都需要配套骨骼。 现在整个角色的全部网格体都会播放下肢同样的动画。
添加一个网格体SM_Bag到 上肢组件子级
将 网格体SM_Bag 附加到角色的插槽上
网格体SM_Bag -细节-插槽-父项套接字-spine_03 这里可以显示上肢的所有骨骼 此时背包位置仍需要调整 在此处直接调整背包位置,将不能适应角色的其他情况,例如角色使用披风而非背包。 应该在上肢骨架中添加插槽,然后调整骨架的插槽位置。
在Spine_03骨骼处添加插槽 attach_backpack attach_backpack 添加预览资产 背包网格体
调整attach_backpack位置
网格体SM_Bag -细节-插槽-父项套接字-attach_backpack
使背包的2个下摆可以在角色跑步时摆动
ABP_Bag 动画图表:
将角色动画应用到背包 input pose 自父项实例输入到子动画图表。
使用自身的刚体 RigidBody 此模拟根据骨骼网格体组件的物理资源进行操作
RigidBody-细节-设置-覆盖物理资产-bag_p 使用背包自己的物理资产
添加 Transform (Modify) Bone 用来测试物理资产效果【稍后删除】 "变换骨骼(Transform Bone)"节点将处理骨骼的变换--即为平移、旋转或缩放 Transform (Modify) Bone-细节-骨骼控制-要修改的骨骼-Root 即背包的根骨骼 平移-平移模式-替换现有项 现在移动背包根骨骼可预览物理资产效果,背包摆件应该可以摆动
删除测试 Transform (Modify) Bone
方法1:bag_skm 直接使用 ABP_Bag 动画资产
打开 bag_skm 骨骼网格体 资产详情-骨骼网格-后期处理动画蓝图-ABP_Bag
背包通过自己根骨骼触发摆件动画
如果上身网格体新增了源角色不具有的骨骼,默认无效,所以新增的骨骼不会产生动画。因为上身网格个体依然复制领导者网格体的骨骼动画。
ABP_Upper 动画图表: input pose
RigidBody RigidBody-细节-设置-覆盖物理资产-PA_Upper 使用上身自己的物理资产,可以新建,使用MESH_T_01
调整力量
UpperBody 组件使用 MESH_T_01 骨骼网格体 UpperBody 使用蓝图动画 ABP_Upper
预构造事件中不再为 UpperBody 设置跟随下身领导者
此时上身不会同步动画, 与背包不同,背包使用自己的根骨骼,在角色动画之后生成摆动动画。 上身需要复制自己的父节点骨骼动画
动画图表: Copy Pose From Mesh "从网格体复制姿势(CopyPoseFrom Mesh) "节点可将另一个组件的姿势数据复制到该组件。只有命名匹配时才能完成操作。
Copy Pose From Mesh-细节-拷贝-使用附加的父项 如SourceMeshComponent无效、此项为true,其将查找附加的父项作为源 这将直接使用 下身的父项-上身作为复制姿势的来源。 或者手动设置来源。
复制曲线-启用 复制自定义属性-启用 这将复制父项的肌肉,变体动画。
现在,上身将随着下身执行一致的动画。 这样,无需修改基本骨架【根组件,下身的骨架】,就可以为上身添加骨骼,物理资产,用以运动。
脸部通常具由复杂的表情动画,但不应使用完整的全身骨骼来携带多余的全身曲线信息。 所以脸部通常使用单独的骨架和动画蓝图。
ABP_Head 动画图表:
Copy Pose From Mesh Copy Pose From Mesh-细节-拷贝-使用附加的父项 复制曲线-启用 复制自定义属性-启用
Head 脸部组件: 使用动画蓝图 ABP_Head
预构造事件图表: 不再为 Head 脸部组件跟随下身领导者组件
此时脸部动画与主动画一致。
将 BP_ModularCharacter 拖入关卡
添加 关卡序列 HeadSequence
场景中选择 BP_ModularCharacter 拖入轨道中
点击轨道右侧+号,添加 Head 脸部组件
点击 Head 脸部组件右侧+号-控制绑定-基于资产的控制绑定- 选择一个【需创建】
此时 BP_ModularCharacter 右侧+号没有 控制绑定 选项,这需要将角色 下身组件设为根组件,替换默认的场景组件
直接 将 LowerBody 拖入 DefaultSceneRoot 即可
现在 BP_ModularCharacte 也可以创建控制绑定
点击轨道右侧+号,添加 Head 脸部组件 点击 Head 脸部组件右侧+号-控制绑定-基于资产的控制绑定- 选择一个【需创建】 Head 的控制绑定将无效,脸部表情不会变化。 这是因为 脸部的根组件为上身 UpperBody。 但 UpperBody 没有曲线。 脸部从上身复制了无效的曲线。 所以需要将脸部附加到根组件 下身
现在脸部控制绑定将生效
关卡中选择定向光 DirectionalLight
事件图表:
创建对场景的定向光的引用 create a reference to DirectionalLight
event tick 添加浮点类型变量 DaySpeed 默认值15 multiply 乘以 delta seconds 增量 结果输出至 make rotator-Y (Pitch) DirectionalLight - add actor localRotation
事件图表: 事件-mouse wheel axis 获取弹簧臂组件 camera Boom get target arm length multiply -10 add clamp (float) camera Boom set target arm length
打开 玩家蓝图 BP_ThirdPersonCharacter_Time 事件图表: keyboard event k set global time dilation set global time dilation-time dilation- 0.5 1 表示原速 小于1表示减慢时间流失 大于1表示加快时间流速
keyboard event s set global time dilation-time dilation-1
https://www.unrealengine.com/zh-CN/metahuman
详细文档: https://dev.epicgames.com/documentation/en-us/metahuman/metahuman-documentation
https://www.unrealengine.com/marketplace/zh-CN/product/metahuman-plugin
从安装版虚幻引擎 的 D:\program\UE_5.3\Engine\Plugins\Marketplace\MetaHuman
目录,拷贝到源码版的相同目录。
启用插件
MetaHuman插件包含两个强大的功能集。
网格体转MetaHuman:
虚幻引擎的MetaHuman插件包含网格体转MetaHuman功能。有了这项激动人心的功能,你可以将通过扫描、雕刻或传统建模创建的自定义网格体转变成具有完整绑定的MetaHuman。然后,你可以在MetaHuman Creator中进一步完善你的角色。
MetaHuman Animator:
MetaHuman Animator是我们新推出的功能集,允许你使用iPhone或立体头戴式摄像机系统(HMC)捕捉演员的表演,并将其转化成MetaHuman角色脸上高保真的面部动画。每个微妙的表情、神态和情绪都会被精确地捕捉下来,忠实地还原到你的数字人类上。它实现这些出色结果的方式简单明了——任何人都可以完成这项任务。 Metahuman Animator通过使用4D解算器,将视频及深度数据与表演者的MetaHuman代表模型结合在了一起。动画是使用GPU硬件在本地处理的,几分钟内即可得到最终动画。
要使用MetaHuman Animator,你需要UE 5.2或更高版本。
UE限定内容 - 只允许在基于虚幻引擎的产品中使用 技术细节 查看教程,详细了解其工作原理。网格体转MetaHuman快速入门 标签
安装metahuman插件 https://www.unrealengine.com/marketplace/zh-CN/product/metahuman-plugin
虚幻引擎查看器 最后更新: 06.01.2022
虚幻引擎资源查看器(以前称为虚幻模型查看器)是一个程序,用于查看和提取使用虚幻引擎制作的各种游戏中的资源。有时该程序被称为“umodel”,即“unreal”和“model viewer”的缩写。 https://www.gildor.org/en/projects/umodel#files
从RO2游戏文件中提取出: 模型文件:例如 Actbox_01.gltf,Actbox_01.bin
相关的贴图文件 png
网格体文件:例如 Actbox_01.psk
动画文件:例如 actbox_01ani.psa,actbox_01ani.config
https://www.gildor.org/projects/unactorx ActorX Importer 补充了 Epic Games ActorX Exporter 的功能。Epic 的插件可以从 3ds Max、Maya 和 XSI 导出 psk 和 psa 文件。此页面中的插件具有相反的功能:您可以将 psk 和 psa 文件加载回 3ds Max(没有适用于 Maya 和 XSI 的版本)。
特征 将 psk 和 pskx 网格加载到 3ds Max 中 加载 PSA 动画 自动创建和分配由UE Viewer生成的素材 将网格/动画批量转换为 max、fbx 或 ase 格式
将插件文件夹放入3ds Max 安装目录的 Autodesk\3ds Max 2024\stdplugs\ActorX Importer
启动 3ds Max 后会自动加载该插件
例如 H:\ro2\Animations-psk\Rag2Npcs_Ma
包含子文件夹。
可以设置为所有材质的根目录。
点击 ActorX 导入器-工具-清空场景
每次导入新的网格体和动画前都需要清空场景
点击 导入 PSK 文件,,只选择一个
点击 导入 PSA 动画文件,只选择一个 点击 全部加载 ,将加载所有动画
使用 3ds max 内置的导出
psk文件路径 选择psk网格体所在目录。 提示材质0时,选择材质目录的第一个材质,将自动使用全部相关材质 点击 导出网格 ,可以批量导出网格体以及附带的物理资产,材质,贴图到网格体目录下的 fbx文件夹
点击 导出动画,动画将导出到同目录的fbx目录下
改动画包含了网格体组件
批量选择fbx,导入 不要勾选导入动画
导入时,勾选 导入动画,并且选择之前导入的骨骼 导入后回生成重复的网格体,物理资产,材质,贴图,全部删除。 只保留动画序列
添加-形状-立方体
选中立方体-右键-浏览至资产
拷贝 cube至自定义文件夹中 重命名为 SM_cube
场景添加 SM_cube,移除原cube. SM_cube 默认启用了碰撞。
玩家也具有碰撞。 现在运行游戏,玩家角色无法推动 SM_cube
SM_cube 无法直接模拟物理
BP_Cube 中添加 静态网格体组件 SM_cube
场景添加 BP_Cube BP_Cube 的 SM_cube 组件 默认启用了碰撞。 玩家也具有碰撞。 现在运行游戏,玩家角色无法推动 BP_Cube
BP_Cube-SM_cube 组件-物理-模拟物理-启用
现在,玩家将可以推动 BP_Cube
BP_Cube-SM_cube 组件-物理-质量(公斤)-启用 100 BP_Cube 质量越重,玩家推动BP_Cube 的距离越小, 质量为1时,可以将 BP_Cube 推飞。 质量很大时,只能推动BP_Cube前进很小距离。
取消重力后,BP_Cube 将悬浮,但由于模拟物理和启用质量,仍会与玩家发生作用力。
添加3个静态网格体
多选这3个静态网格体,右键-关卡-创建已打包关卡actor
保存为关卡 NewMap 再保存为预制件 BPP_Prefabs
BPP_Prefabs 包含关卡实例组件 https://docs.unrealengine.com/5.3/zh-CN/level-instancing-in-unreal-engine/
现在将 BPP_Prefabs 拖入场景将包括3个静态网格体
内容浏览器-添加-添加功能或内容包- 内容-starter content
Door 使用初学者包中的门静态网格体 SM_Door
Frame 组件使用初学者包中的静态网格体 SM_DoorFrame
调整 Door 的位置 0,45,0
由于 Door组件的SM_Door没有碰撞体,所以默认无法启用模拟物理
不再修改和使用原网格体。 BP_PhysicsDoor使用复制的网格体
物理-物理模拟-启用
由于启用了模拟物理 ,默认情况下,受到外部碰撞,门将倒下
碰撞-碰撞预设-无碰撞 防止门框干扰碰撞
约束门的位置 PhysicsConstraint 物理约束组件默认位于门的底部中心,球形,默认可以任意方向旋转
Angular limits-摆动1运动-自由 Angular limits-摆动2运动-锁定 这回摆脱垂直球体
Angular limits-扭曲运动-锁定 这将禁止移动
现在只显示水平的红色圆形,表示只可以水平旋转
PhysicsConstraint -细节-约束-组件命名1-组件名称-Door 【门组件的名称】 表示约束 Door 组件,即门。 要约束的首个组件属性的命名。如Actor1为空,将在拥有者中查看。如此项为空,将使用Actor1的RootComponent
现在 Door 组件 周围将显示红色边框
此时玩家碰撞门,门将绕门的中轴旋转。 因为物理约束组件位于门的底部中心,且约束门绕约束组件的水平轴旋转
Angular limits-摆动1运动-受限 此时可以调整 摆动1限度 Angular limits-摆动1限度-90 表示门可以向内或向外旋转90度
默认的红色半圆表示门在x方向的左右90度旋转,这与门的旋转不一致
调整后
现在碰撞门,可以使门向内开90度
也可以使门向外开90度
PhysicsConstraint 物理约束组件 -细节-角发动机-角驱动模式-扭曲和摇摆 路径被分解为扭曲(滚动约束)和摇摆(椎体约束)。如不跟随最短弧可能导致万向节锁定。可与锁定角约束共用。
角发动机-目标方向-驱动-摇摆-启用 控制当前朝向/速度和目标朝向/速度之间的椎体约束驱动。只要至少一个摇摆限制设为不受限或受限,此项便可用。
现在默认力将起作用
现在 碰撞将门推开后,门将内外晃动,直到很久以后彻底停止晃动,缓慢归位到门框。
Door组件-细节-物理-角阻尼-15 添加后用于减弱角运动的“拖拽”力
现在,门被碰撞推开后,将快速返回的原位置。
https://docs.unrealengine.com/5.3/zh-CN/skeletal-mesh-editor-in-unreal-engine/
需要以 standalone game 独立进程游戏 模式运行游戏。 需要打开 steam
https://github.com/mordentral/AdvancedSessionsPlugin https://github.com/Risensy/Steam Discord Server - https://discord.gg/AyPUwKdbTK
Online Subsystem Steam Online Subsystem Steam的概述,包括如何设置项目以在Valve的Steam平台上分发。 https://docs.unrealengine.com/5.3/zh-CN/online-subsystem-steam-interface-in-unreal-engine/
多人游戏中的关卡切换 https://docs.unrealengine.com/5.3/zh-CN/travelling-in-multiplayer-in-unreal-engine/
材质函数需要参数1:WindDirection 风的方向 类型为向量4 默认值 0,1,0,0
材质函数需要参数1:WindIntensity 风的强度 类型为标量 默认值 1
输出值用于材质的 全局位置偏移
WindDirection :0,1,0,0 切记,A通道不能为1 WindIntensity :1
分组-Wind
例如导入花瓣透明png 导入图片为 纹理 T_Flower
材质-混合模式-半透明 着色模型-双面植物 双面-启用 【否则背向摄像机的花瓣面将不显示,导致花瓣忽隐忽现】
使用 Particle Color 节点制作材质,可在粒子系统中更换颜色。 Fraction 为饱和度。
右键-Niagara系统-创建空白系统
此时将 NS_FallingFlower 拖出场景,可以看到基本的飘散粒子效果
Blowing Particles - 渲染-Sprite渲染器: 精灵渲染-材质-MI_Flower
Blowing Particles-粒子生成: initialize particles-color 需要 Particle Color 材质节点配合生效。
Blowing Particles-粒子生成: Sprote Attributes-Sprite Size Mode-Uniform Sprite Size Min 最小数量 -5 Sprote Attributes-Sprite Size Mode-Uniform Sprite Size Max 最大数量 -15
Blowing Particles-粒子更新: Aerodynamic Drag 空气阻力-
Blowing Particles-粒子更新: Wind Force-Wind Speed 控制风吹的方向和风速-xyz 200,0,0 表示吹向镜头
默认花瓣平面较薄,。
如果花瓣具由弯曲,且有一定厚度,粒子效果更加。
Blowing Particles-渲染-Sprite 渲染器-取消
Blowing Particles-渲染-加号-网格体渲染器
点击 修复问题,自动修复粒子
网格体-使用网格体版本的花瓣。 可以添加多各不同的花瓣网格体。 这样花瓣飘落后将会堆积在地面。
Blowing Particles- 粒子生成-Mesh Attributes-Mesh Render Arrar visibility mode-random
Blowing Particles- 粒子生成-Mesh Attributes-Mesh Render Arrar visibility mode-Mesh Render info-网格体渲染器-网格体渲染器
Blowing Particles- 粒子生成-Mesh Attributes-Mesh Scale mode-Random Uniform
Blowing Particles- 粒子更新-Align Particles with collision plane: allow alignment on X -取消 【不与地面x方向对齐,防止在x方向约束粒子】 allow alignment on Z - 启用
Blowing Particles- 粒子生成-shape location: shape- 在半径300的球体内生成粒子
Blowing Particles-spawn rate:
它们通常属于本地化,但它们并不相同。
本地化是适应的过程 例如:在游戏中翻译文本为特定地区或语言。
国际化是设计软件的过程,以便于应用程序翻译到其他语言以适应其他地区,且不需要修改工程。
虚幻通过 本地化控制板 进行本地化
工具-本地化控制板
游戏目标是将要本地化的游戏内容的部分
可以新建游戏目标,例如为游戏DLC新建游戏目标
game 目标使用固定或游戏 游戏启动后将自动加载翻译。
DLC 目标使用永不
引擎的本地化 一般不需要
更加便捷
例如:收集UI资产,从中找到要翻译的文本 包括路径通配符-添加路径 Content/Ro2ea/Blueprints/UI/* 表示收集UI目录下的资产,包含控件等资产
默认只有英语。 添加新语言,例如中文(简体)
例如:中文 语言,无效
例如:中文(简体) 语言,有效
默认的语言,基于此开始翻译。
建议使用英语作为本地语言,因为代码中更多为字母,方便翻译。 更改本地语言将会丢失之前的翻译。且不能撤销操作。
例如 :控件文本 点击空间文本旁边的旗帜标志,显示翻译选项 本地化-启用 表示可翻译,可以被本地化控制板收集
对固定展示的数字,关闭其本地化,防止被本地化控制板收集。 例如角色等级的具体值:99 不被收集的文本将显示警告标志
例如用户名,密码,用户输入的内容 修改后需重新收集文本。
点击 收集文本,开始收集本地语言的已标记为需要翻译的文本数据
找到248个可翻译的文本
当前英语为本地语言,所以需要将英语翻译为中文简体等其他语言。
点击 中文简体 右侧的 编辑此语言的翻译
未翻译为 70 处
点击 中文简体 右侧编辑此语言的翻译
右侧输入对应英文【已设置为本地系统语言】的中文翻译
翻译完成过后,继续点击 收集文本 已翻译的中文简体语言显示翻译进度
需要编译收集的文本使引擎感知新的文本被翻译。 语系-计算字数
语系-编译文本
语系-选择翻译好的语言 中文简体-右侧 编译此语言的翻译 或 编译文本
编辑器偏好设置-通用-区域和语言-预览游戏语言
切换为中文简体【英语为本地系统时】
如果在编辑器中预览翻译,需要将 加载政策临时改为 游戏/固定/编辑器
控件中也可以直接预览翻译
en
zh-Hans
如果预览翻译不生效,请检查: 语系必须为具体项。中文(简体) 可以。 中文 不可以。 可能需要重启编辑器。 加载政策临时改为 游戏/固定/编辑器。
Unreal Engine Source Code Localization
翻译源代码文件(C++或蓝图)中的文本。我们需要在蓝图中使用文本变量Text,在C++中使用FText。
蓝图控件需要使用 文本类控件和变量
蓝图变量 需要文本类型
引擎将收集C++中的 NSLOCTEXT 或 LOCTEXT
NSLOCTEXT
是一个宏,用于在 Unreal Engine 项目中定义命名空间化的本地化文本。这个宏允许你创建在不同语言环境下可以被适当翻译的字符串。使用 NSLOCTEXT
时,你需要指定三个参数:一个命名空间,一个键,和默认的文本字符串。这样就为每个特定的字符串指定了一个唯一的上下文和标识符,有助于在后续的本地化过程中进行准确翻译。
以下是详解 NSLOCTEXT
宏的各个部分:
命名空间(Namespace): 命名空间用于对相关的本地化文本进行分组。这有助于组织和区分项目中的不同部分或不同模块的文本。例如,你可能会有一个用于UI元素的命名空间和一个用于游戏逻辑的命名空间。
键(Key): 键必须项目中唯一。否则本地化控制板会显示检测到冲突。
键是在给定命名空间内唯一标识一段文本的字符串。在本地化过程中,翻译人员通常会看到这个键和默认文本,以便提供正确的翻译。键的选择应当反映文本内容的用途或内容,以方便理解和翻译。
默认文本(Default Text): 默认文本是在源语言(通常是英语)下提供的文本字符串。这是在游戏运行时如果没有找到适当的翻译或者在开发过程中默认显示的文本。
以下是如何使用 NSLOCTEXT
宏定义本地化文本的示例:
FText MyText = NSLOCTEXT("Dialogues", "Greeting", "Hello, player!");
在这个例子中:
"Dialogues"
是命名空间,用于分组可能出现在游戏对话框中的文本。"Greeting"
是这段文本的唯一键,表明这段文本用于问候。"Hello, player!"
是如果游戏以开发语言(比如英语)运行时显示的默认文本。使用 NSLOCTEXT
定义的本地化文本,可以在之后的本地化流程中被翻译到不同语言,并且可以通过Unreal Engine的本地化系统根据玩家的语言偏好自动选择和显示正确的文本版本。这使得游戏或应用能够支持多语言,并为玩家提供更佳的体验。
FText WarnMessage = NSLOCTEXT("UserMessage", "WarnMessage", "name is wrong!!");
#define LOCTEXT_NAMESPACE "UserMessage"
FText WarnMessage2 = LOCTEXT("WarnMessage", "name is to short!!");
#undef LOCTEXT_NAMESPACE
本地化控制板-收集文本-从文本文件收集 搜索目录-C++目录 Source 文件扩展名 -常用扩展名 h cpp ini 等
从包收集-包括路径通配符 选择包含蓝图资产的目录例如 Content/Ro2ea/*
语系-收集文本
中文(简体) 编辑此语言的翻译 计算字数 编译文本
类似变量用法。 Unreal Engine Localization String Tables 本地化字符串表可以避免翻译重复的单词或短语(这在游戏UI或蓝图中很常见)
新建目录 例如 Localization,收集翻译文本时必须包含该目录的本地化字符串表。 可以放置到相关文本使用的目录下。
右键-其他-字符串表格
添加 文本 添加键值对:start_game - start game
找到文本翻译按钮-引用文本-字符串表格-ST_UICommon-start_game
start game 有变动,需要再次翻译。 收集文本,翻译,编译文本。
Unreal Engine Localization Format Text 正确使用文本格式来组合以后可以本地化的文本。我们可以根据性别、复数、数字、日期、货币等定制翻译
蓝图中使用 Append 等操作FSting的函数节点,无法本地化。 需要使用 工具-文本-Format Text 格式化文本函数节点来操作文本,才可以被本地化收集。
Date:{Date}
Date:
为可本地化的文本,大括号内Date
为捕获的日期变量
Date:{Date}
翻译前面 Date:
部分
{Date}
需要保留,但可以更换位置
计算字数,编译文本。
Unreal Engine External Localization Tools | poedit
外部本地化工具,例如 POEDIT 或任何支持 PO 文件的本地化工具。这将使我们能够在不打开引擎的情况下进行翻译、获取建议、使用低端机器等。
本地化控制板-语系-导出文本 或 本地化控制板-中文简体-导出此语言的翻译
Game.po
为需要外部打开翻译的文件
https://poedit.net/ https://github.com/vslavik/poedit
打开 Content\Localization\Game\zh-Hans\Game.po
中文翻译。
编辑右侧文本即可。
翻译完成后,保存po文件
本地化控制板-语系-导入文本 选择目录 E:\Unreal Projects 532\Ro2ea\Content\Localization\Game 导入全部语系的po翻译文件
编译文本。
Unreal Engine Asset Localization
不仅需要翻译文本,还需要翻译其他类型的资产,例如纹理、材质等。
对于打包的游戏,需要完全重启可执行文件才能使本地化资产正常工作。在“设置当前区域性”节点中,如果展开高级选项,则会出现“保存到配置”复选框,该复选框将保留语言选择与保存游戏对象一起:https://dev.epicgames.com/community/snippets/W5E/unreal-engine-persist-culture-to-config-files-in-set-current-culture
纹理-右键-资产本地化-新建本地化资产-中文(简体)
这将新建中文简体版本的同名纹理
Ro2ea/Content/L10N/zh-Hans/Ro2ea/Image/gravityfes_logo.uasset
中文简体版本的同名纹理-右键-资产操作-导出 导出需要的格式例如 PNG,TGA
在外部软件中修改导出的文件。
打开 需要本地化的 中文简体版本的同名纹理 Ro2ea/Content/L10N/zh-Hans/Ro2ea/Image/gravityfes_logo.uasset
文件路径-源文件 选择修改后的文件以更新到当前文件。
如果游戏运行中使用命令行切换语言,本地化资产例如纹理将不生效。 这是由于纹理是加载到内存中的。
需要重新加载纹理,只需要切换关卡即可。
Unreal Engine Dialogue Localization
待补充
Unreal Engine Localization Language Switching
编辑器偏好设置-通用-区域和语言-国际化-预览游戏语言
这是为了在使用命令行切换语言时,只对游戏生效。 不会切换引擎和编辑器的语言。
独立进程游戏 运行时按波浪键 ~ 打开控制台。
输入切换语言命令 culture=en
切换为英语
输入切换语言命令 culture=zh-hans
切换为中文(简体)
注意,纹理等资产需要通过切换关卡重新加载使本地化生效。
工具集-国际化-get current culture 获取当前操作系统的语言
set current culture 设置语言 这同时会修改编辑器语言,除非使用独立进程游戏 模式运行。
项目设置-项目-打包-高级-要打包的本地化-显示本地化文本 启用-英语 启用-中文(简体)
平台-windows-打包项目
[Internationalization] culture=en
两个配置都可以设置默认语言 Game.ini 的设置将会覆盖 Engine.ini
为打包后的游戏执行文件 exe 创建快捷方式,
在 路径末尾添加 -culture=en
例如D:\ro2\System\RAGII.EXE -culture=en
这回覆盖配置文件。
``
UFUNCTION(BlueprintCallable, Category = "RoLibrary|zh")
static void ChangeGameLanguage(const FString& NewLanguageCode);
void URoLibrary::ChangeGameLanguage(const FString& NewLanguageCode)
{
// 实例化一个文化对象,例如"fr"代表法语
FCulturePtr NewCulture = FInternationalization::Get().GetCulture(NewLanguageCode);
if (NewCulture.IsValid())
{
// 设置新的语言和地区
FInternationalization::Get().SetCurrentCulture(NewLanguageCode);
// 你还可以分别设置显示语言和音频语言
FInternationalization::Get().SetCurrentLanguageAndLocale(NewLanguageCode);
// 输出当前语言以确认更改
//UE_LOG(LogTemp, Log, TEXT("Language changed to: %s"), *FInternationalization::Get().GetCurrentLanguage()->GetName());
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Invalid or unsupported language code: %s"), *NewLanguageCode);
}
//ChangeGameLanguage(TEXT("zh-Hans"));
}
使用
ChangeGameLanguage(TEXT("zh-Hans"));
Unreal Engine Localization Packaging Settings
项目设置-项目-打包-高级-要打包的本地化-显示本地化文本 启用-英语 启用-中文(简体)
项目设置-项目-打包-高级-国际化支持
靠前的选项打包后文件更小[可以忽略,仅1-5MB差距],但支持的显示更差
中文需要选择 EFIJSCJK 15MB,在获取本地语言时可以显示对应语言的文字而非英语表示的中文(简体)
不同平台的配置文件也可以修改
https://docs.unrealengine.com/5.3/zh-CN/how-to-import-and-use-paper-2d-sprites-in-unreal-engine/
选择多张Sprites 纹理-右键-创建纹理阵列 T_loading_run_Array Sprites 纹理 loading_run_01-loading_run_012
纹理2D数组 T_loading_run_Array
材质域-用户界面 混合模式-已遮罩
TextureCoordinate
向量项-AppendVector
Time Constant 1 默认65 转换为参数 FPS Multiply
Constant 1 默认65 转换为参数 NumberOfTextures 值为纹理数量 Fmod
使用改材质即可
https://docs.unrealengine.com/5.3/zh-CN/creating-drag-and-drop-ui-in-unreal-engine/
类型:用户控件 对象引用
选中 实例可编辑(Instance Editable) 和 生成时公开(Expose on Spawn)。 这将用于存放我们想要在屏幕上四处拖动的UMG控件。
类型:vector2D /向量2D 选中 实例可编辑(Instance Editable) 和 生成时公开(Expose on Spawn)。 这会使位置从我们开始拖放控件的位置偏移。
类型:用户控件 对象引用 选中 实例可编辑(Instance Editable) 和 生成时公开(Expose on Spawn)
注意,只有最外部的控件【当前为尺寸框控件】设置为:行为-已启用,可视性-可视。 内部控件都不可以设置为可视,否则拖动失效。
这一步使我们能够确定玩家是否在拖动鼠标左键。
在 事件图表 中,添加 OnMouseButtonDown 和 OnDragDetected 覆盖。这样会为事件图表中的每个覆盖创建选项卡。 调用自定义脚本需要置换几个函数。鼠标键按下时将进行一些检查,还将检查出现控件拖动时发生的状况。
选择 OnMouseButtonDown 选项卡。从 OnMouseButtonDown 节点上 我的几何结构(My Geometry) 引脚拖出引线并添加 绝对到局部(Absolute to Local) 节点。
从 鼠标事件(Mouse Event) 引脚拖出引线,添加 获取屏幕空间位置(Get Screen Space Position) 节点,并将返回值连接到 绝对坐标(Absolute Coordinate) 引脚。
此操作会将生命值条控件的绝对坐标转换为局部空间,原理是 获取鼠标按钮注册按下鼠标键的屏幕位置。这样会将位置存储为变量,以便我们确定玩家实际点击控件的位置以及放下控件的位置。
右键单击 绝对到局部(Absolute to Local) 节点的 返回值(Return Value),并选择 提升为变量(Promote to Variable)。将变量命名为 拖拽偏移(Drag Offset)。
在图中单击右键,并添加 按下后检测拖拽(Detect Drag if Pressed) 节点。将 拖拽键(Drag Key) 设置为 鼠标左键(Left Mouse Button)。
完成其余引脚的连接。
将 鼠标事件(Mouse Event) 连接到 指针事件(Pointer Event)。
将 按下后检测拖拽(Detect Drag if Pressed) 的 返回值(Return Value) 引脚连接到 返回节点
将四个节点的 执行(Exec) 引脚连接起来。
在这步中,我们将决定玩家实际在屏幕上拖动HealthBar时发生的状况。
选择 OnDragDetected 选项卡。在 OnDragDetected 节点上单击右键并添加 创建控件(Create Widget) 节点。将 类(Class) 设置为 拖拽控件(WBP_Draggable)。
从 控件引用(Widget Reference) 引脚连接 Self 节点。将返回值 提升 为变量,命名为 已拖拽控件(Dragged Widget) 并连接引脚。
现在,当我们创建拖拽控件时,它将引用现有的HealthBar控件。我们还会将虚拟拖拽控件提升为变量,以便稍后访问它,并在选择放下控件时从显示画面中将它移除。
单击右键并创建 Drag & Drop Operation 节点。将 类(Class) 设置为 控件拖拽(BP_WidgetDrag),并将 枢轴(Pivot) 设为 鼠标按下(Mouse Down)。
如果相对于指针拖拽,枢轴将确定在执行拖拽操作时拖拽控件显示(Drag Widget Visual)应出现的位置。
将以下节点连接到 DragAndDropOperation 节点引脚。
从 被拖拽控件设置(Dragged Widget Set) 到 返回节点 的 执行 线
Self 到 控件引用(Widget Reference)
被拖拽控件(Dragged Widget) 到 默认拖拽显示(Default Drag Visual)
拖拽偏移(Drag Offset) 到 拖拽偏移(Drag Offset)
前文中我们说明了哪个控件蓝图是引用,拖动可视应该是什么,并提供了一个开始拖动的偏移。默认情况下,节点上有一个偏移引脚;但我们使用自己的计算来确定按下鼠标按钮时要开始偏移的位置。
编译 并 保存 HealthBar 蓝图。
接下来需要确定玩家按下鼠标左键时应该发生的操作并执行OnDrop函数。
这里,我们设置主 HUD 控件蓝图,并覆盖我们执行 OnDrop 函数时要发生的操作。
打开 WBP_Main 控件蓝图。在 画布面板 的 细节(Details) 面板中,将 可视性(Visibility) 设为 可见(Visible)。
我们在HealthBar控件内部编写了拖拽检测脚本;但松开鼠标左键时,我们希望将生命值条放到HUD控件蓝图中。为了让HUD接收到命中检测,需要让面板可见。
在 调色板(Palette) 窗口中,将 HealthBar 控件添加到画布。
在 OnDrop 节点上 运算(Operation) 拖出引线,并添加 转换为控件拖拽(Cast to BP_WidgetDrag) 节点。然后,添加 获取控件引用(Get Widget Reference) 并将 作为控件拖拽(As Widget Drag) 引脚连接到 控件引用(Widget Reference) 和 拖拽偏移(Drag Offset) 节点。
此操作将检查哪类操作正作为 OnDrop 函数的部分在执行。如果是 控件拖拽(Widget Drag),我们会获得 WidgetReference(作为被拖拽的控件传递)以及 DragOffset(或开始拖拽的位置)。
从 我的几何结构(My Geometry) 引脚,添加 绝对到局部(Absolute to Local) 节点。从 指针事件(Pointer Event) 引脚,添加 GetScreenSpacePosition 节点。 这将告诉我们在2D空间中松开鼠标左键放置控件的位置。我们将用这个值减去 DragOffset,确定应该在什么位置放下控件。
添加 Vector2D - Vector 2D 节点,从 绝对到局部(Absolute to Local) 的 返回值 减去 DragOffset。
单击右键并添加 从父项移除(Remove from Parent)、添加到视口(Add to Viewport) 和 设置视口中的位置(Set Position in Viewport) 节点。按照以上所列的顺序将所有3个节点的 执行(Exec) 引脚连接起来,并将 设置视口中的位置(Set Position in Viewport) 节点连接到 返回节点。
进行以下连接和调整:
控件引用(Widget Reference) 引脚连接到所有三个节点上的 目标(Target) 引脚。
Vector2D - Vector 2D 节点的 返回值 引脚连接到 位置(Position) 引脚。
取消选中 移除DPIScale(Remove DPIScale)
选中 返回值(Return Value)
取消勾选 移除DPIScale(Remove DPIScale) 并选中 返回值,因为无需移除DPI缩放。我们已经处理了这个函数,因此返回为true。我们首先通过此脚本移除现有的体力条控件,然后将其重新添加到相对于Drag Offset的新位置中的画面。
编译 并 保存 HUD 控件蓝图。
我们已设置HUD处理拖拽控件的放置,它还将显示体力条。接下来将设置被拖拽控件模拟体力条的外形,并对角色蓝图发出指令将 HUD 添加到视口。
在这一步中,配置 DragWidget,这是我们将拖到视口中的可视控件。
打开 DragWidget 控件蓝图,并将 画布面板 替换为拥有子 边框 的 缩放框。
将 缩放框 重命名为 WidgetSize,并将 isVariable 设为 true。选中 宽度覆盖(Width Override) 和 高度覆盖(Height Override)。
我们将对缩放框的宽度和高度进行设置,使其成为体力条控件的尺寸。
选择 边框,并将 笔刷颜色(Brush Color) 设为 黑色(Black),Alpha 值为 0.5,以呈现一定的透明度。
在本示例中,我们的生命值条轮廓为拖拽显示,同时在同一个位置保留实际的生命值条。
在 事件图表 中,从 事件构造 拖出引线,添加 转换为生命值条(Cast to WBP_HealthBar) 节点。从 控件引用(Widget Reference) 连出引线,并将它连接到 对象(Object) 引脚。
从 作为生命值条(As Health Bar) 引脚,添加 获取所需大小(Get Desired Size) 节点。将返回值连接到 中断矢量2D(Break Vector 2D) 节点。
这样就获得了生命值条的大小,并可以将缩放框设置为相同大小。我们可以手动输入覆盖;但如果要更改生命值条的大小,也必须在此处更改。
单击右键并添加 设置高度覆盖(Set Height Override) 和 设置控件覆盖(Set Widget Override) 节点,并将它们分别连接到 转换为生命值条(Cast to HealthBar) 节点。然后拖入 控件大小(Widget Size) 节点。
连接以下引脚:
控件大小(Widget Size) 到两个 目标(Target) 引脚
中断矢量2D X 到 输入高度覆盖(In Height Override)
中断矢量2D Y 到 输入宽度覆盖(In Width Override)
编译 并 保存 DragWidget 蓝图。
最后,需要将 HUD 控件蓝图 WBP_Main 添加到 角色 蓝图中的视口并启用鼠标光标,以便能够看到拖拽位置。
在 内容浏览器 中的 Content/ThirdPersonBP/Blueprints 下,打开 ThirdPersonCharacter 蓝图。
从 事件开始播放(Event Begin Play) 节点拖出引线,添加 创建控件(Create Widget) 节点并将 类(Class) 设置为 WBP_Main。创建 添加到视口(Add to Viewport) 节点并将它连接到 设置显示鼠标光标(SET Show Mouse Cursor)。添加 获取玩家控制器(Get Player Controller) 节点,并将 返回值 连接到 设置目标(SET Target)。
编译、保存 并单击 运行(Play) 按钮,以运行拖拽控件。
最终结果 在编辑器中运行时,可以单击左键,并将生命值条拖到屏幕上,然后将它放到新位置。
这只是开始拖放流程的一个元素范例。可能需要进行额外检查,确保玩家不会将控件拖至安全区外,或放在其他控件之上。
4个静态网格体组件添加简单碰撞
静态网格体组件 生成重叠事件,启用碰撞 不启用模拟物理
模拟物理-启用 质量-启用 10公斤 启用重力-启用
碰撞-生成重叠事件 启用碰撞 查询和物理 阻挡适当的物体
虚幻引擎5 之旅 Unreal Engine 5 Tutorials