Repository: thejinchao/ue5-style-guide
Branch: main
Commit: fd0c8b99d4b4
Files: 14
Total size: 174.0 KB
Directory structure:
gitextract_lc07u93b/
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── README_PTBR.md
├── docs/
│ ├── gettingstarted.md
│ ├── howitworks.md
│ ├── index.md
│ ├── style.md
│ ├── todo.md
│ └── unrealguidelines.md
├── marketplace-compatibility.md
├── mkdocs.yml
└── readthedocs.yml
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# If you would like to directly support the maintenance of this repo and the pursuit of better things, please become a GitHub Sponsor or reach out to sponsor by other means.
github: ALLAR
================================================
FILE: .gitignore
================================================
docs/build
================================================
FILE: LICENSE
================================================
The MIT License
Copyright (c) 2016 Gamemakin LLC. https://gamemak.in
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# [Gamemakin](https://gamemak.in) UE4 Style Guide() {
*最合理的UE4规范*
灵感来源于Airbnb的JS规范 [Airbnb Javascript Style Guide](https://github.com/airbnb/javascript).
## 关于本工程的声明
当前工程的地址为 https://github.com/thejinchao/ue5-style-guide. 原英文工程地址为 https://github.com/Allar/ue5-style-guide. 缺省分支名已经改为 `main`.
## 关于Linter和规范的文档
更多关于Linter和工程规范的文档可以参考[这个页面](https://ue4-style-guide.readthedocs.io/en/latest/)
## 讨论该规范
Gamemakin LLC 有一个公开的讨论板块,地址是 http://discord.gamemak.in ,其中还包含了#linter聊天区,如果你有关于本套规范或者插件的任何想法,欢迎来讨论。
## 链接到本文档
本文的任何章节都有数字超链接地址,你可以直接通过本文的短地址 http://ue-cn.style 再加上章节编号,直接链接到本文的任意位置。
例如,如果你想把本文的第一节发送给其他人,在地址后面加上`#0.1`即可,也就是使用地址 http://ue-cn.style#0.1
## 目录
- [重要术语](#important-terminology)
- [关卡/地图](#terms-level-map)
- [标识符](#terms-identifiers)
- [大小写](#terms-cases)
- [变量 / 属性](#terms-var-prop)
- [属性](#terms-property)
- [变量](#terms-variable)
- [0. 原则](#0)
- [0.1 如果你的项目已经存在现有规范,那么请继续遵守规范](#0.1)
- [0.2 不管团队中有多少人,工程中所有的数据结构、资源、代码风格应该统一,如同是同一个人的作品](#0.2)
- [0.3 真正的好朋友不会让对方写烂代码](#0.3)
- [0.4 谨慎加入没有规范的团队](#0.4)
- [0.5 请遵守法律条款](#0.5)
- [00. 需要强制执行的全局规范](#00)
- [00.1 禁止使用的字符](#00.1)
- [标识符](#identifiers)
- [1. 资源命名约定](#anc)
- [1.1 基本命名规则 - `Prefix_BaseAssetName_Variant_Suffix`](#base-asset-name)
- [1.1 范例](#1.1-examples)
- [1.2 资源类型表](#asset-name-modifiers)
- [1.2.1 通用类型(Most Common)](#anc-common)
- [1.2.2 动作(Animations)](#anc-animations)
- [1.2.3 人工智能(Artificial Intelligence)](#anc-ai)
- [1.2.4 蓝图(Blueprints)](#anc-bp)
- [1.2.5 材质(Materials)](#anc-materials)
- [1.2.6 纹理(Textures)](#anc-textures)
- [1.2.6.1 多重纹理(Texture Packing)](#anc-textures-packing)
- [1.2.7 杂项(Miscellaneous)](#anc-misc)
- [1.2.8 Paper 2D](#anc-paper2d)
- [1.2.9 物理(Physics)](#anc-physics)
- [1.2.10 声音(Sounds)](#anc-sounds)
- [1.2.11 界面(User Interface)](#anc-ui)
- [1.2.12 特效(Effects)](#anc-effects)
- [2. `Content`的目录结构](#structure)
- [2e1 目录结构示例](#2e1)
- [2.1 文件夹命名](#structure-folder-names)
- [2.1.1 使用大驼峰规范(PascalCase)](#2.1.1)
- [2.1.2 不要使用空格](#2.1.2)
- [2.1.3 不要使用奇怪的符号 ](#2.1.3)
- [2.2 使用一个顶级目录来保存所有工程资源 ](#structure-top-level)
- [2.2.1 避免全局资源](#2.2.1)
- [2.2.2 减少资源迁移时的冲突](#2.2.2)
- [2.2.2e1 举例:基础材质的麻烦](#2.2.2e1)
- [2.2.3 官方提供的范例、模板和商城中的资产是安全的](#2.2.3)
- [2.2.4 使得DLC、子工程、以及补丁包容易维护](#2.2.4)
- [2.3 使用开发者目录(`Developer`)做本地测试](#structure-developers)
- [2.4 所有场景* 文件应该保存在一个名为'Maps'的目录中 ](#structure-maps)
- [2.5 使用`Core`目录存储系统蓝图资源以及其他系统资源 ](#structure-core)
- [2.6 不要创建名为`Assets` 或者 `AssetTypes`的目录](#structure-assettypes)
- [2.6.1 创建一个名为`Assets`的目录是多余的](#2.6.1)
- [2.6.2 创建名为`Meshes`、 `Textures`或者`Materials`的目录是多余的](#2.6.2)
- [2.7 超大资源要有自己的目录结构 ](#structure-large-sets)
- [2.8 材质库`MaterialLibrary`](#structure-material-library)
- [2.9 避免空目录存在](#structure-no-empty-folders)
- [3. 蓝图(Blueprint)](#bp)
- [3.1 编译(Compiling)](#bp-compiling)
- [3.2 变量(Variables)](#bp-vars)
- [3.2.1 命名(Naming)](#bp-var-naming)
- [3.2.1.1 使用名词](#bp-var-naming-nouns)
- [3.2.1.2 PascalCase](#bp-var-naming-case)
- [3.2.1.2e 范例](#3.2.1.2e)
- [3.2.1.3 布尔变量 `b` 前缀](#bp-var-bool-prefix)
- [3.2.1.4 布尔类型变量命名规则](#bp-var-bool-names)
- [3.2.1.4.1 孤立存在的状态信息](#3.2.1.4.1)
- [3.2.1.4.2 避免表达复杂状态](#3.2.1.4.2)
- [3.2.1.5 考虑上下文](#bp-vars-naming-context)
- [3.2.1.5e 范例](#3.2.1.5e)
- [3.2.1.6 __不要__ 在变量中包含变量类型名称](#bp-vars-naming-atomic)
- [3.2.1.7 非原生类型的变量,需要包含变量类型名](#bp-vars-naming-complex)
- [3.2.1.8 数组](#bp-vars-naming-arrays)
- [3.2.2 可编辑变量](#bp-vars-editable)
- [3.2.2.1 Tooltips](#bp-vars-editable-tooltips)
- [3.2.2.2 滑动条(Slider)以及取值范围](#bp-vars-editable-ranges)
- [3.2.3 分类](#bp-vars-categories)
- [3.2.4 变量的访问权限](#bp-vars-access)
- [3.2.4.1 私有变量](#bp-vars-access-private)
- [3.2.5 高级显示](#bp-vars-advanced)
- [3.2.6 Transient变量](#bp-vars-transient)
- [3.2.8 Config变量](#bp-vars-config)
- [3.3 函数、事件以及事件派发器](#bp-functions)
- [3.3.1 函数命名](#bp-funcs-naming)
- [3.3.1.1 所有函数的命名都应该是动词](#bp-funcs-naming-verbs)
- [3.3.1.2 属性的状态变化响应函数应该命名为`OnRep_Variable`](#bp-funcs-naming-onrep)
- [3.3.1.3 返回布尔变量的信息查询函数应该是问询函数](#bp-funcs-naming-bool)
- [3.3.1.4 E事件的响应函数和派发函数都应该以`On`开头](#bp-funcs-naming-eventhandlers)
- [3.3.1.5 远程调用函数应该用目标作为前缀](#bp-funcs-naming-rpcs)
- [3.3.2 所有函数都应该有返回节点](#bp-funcs-return)
- [3.3.3 蓝图函数中节点数不应该超过50个](#bp-graphs-funcs-node-limit)
- [3.3.4 所有Public函数都应该有功能描述](#bp-graphs-funcs-description)
- [3.3.5 插件中可以在蓝图中调用的自定义函数都应该放在以插件名命名的类别中](#bp-graphs-funcs-plugin-category)
- [3.4 蓝图节点](#bp-graphs)
- [3.4.1 不要画‘意面’](#bp-graphs-spaghetti)
- [3.4.2 保持连线对齐,而不是节点](#bp-graphs-align-wires)
- [3.4.3 白色的可执行线优先级最高](#bp-graphs-exec-first-class)
- [3.4.4 节点应该有合理的注释](#bp-graphs-block-comments)
- [3.4.5 蓝图中需要在适当的地方处理类型转换错误](#bp-graphs-cast-error-handling)
- [3.4.6 避免出现空悬节点和死节点](#bp-graphs-dangling-nodes)
- [4. 静态模型](#4)
- [4.1 静态模型的UV](#s-uvs)
- [4.1.1 静态模型需要包含UV](#s-uvs-no-missing)
- [4.1.2 静态模型的UV须要避免互相覆盖](#s-uvs-no-overlapping)
- [4.2 正确的设置LOD](#s-lods)
- [4.3 不带插槽的模块化的模型需要严格对齐网格](#s-modular-snapping)
- [4.4 所有模型需要有碰撞体](#s-collision)
- [4.5 所有模型资源需要正确的缩放系数](#s-scaled)
- [5. Niagara](#Niagara)
- [5.1 永远不要有空格](#ng-rules)
- [6. 关卡/ 地图](#levels)
- [6.1 解决掉错误和警告](#levels-no-errors-or-warnings)
- [6.2 记得构建光照](#levels-lighting-should-be-built)
- [6.3 不要让玩家看到Z Fighting](#levels-no-visible-z-fighting)
- [6.4 商城需要遵守的规范](#levels-mp-rules)
- [6.4.1 预览场景](#levels-mp-rules-overview)
- [6.4.2 演示场景](#levels-mp-rules-demo)
- [7. 纹理](#textures)
- [7.1 纹理大小需要是2的幂](#textures-dimensions)
- [7.2 纹理图案密度应该保持一致](#textures-density)
- [7.3 纹理大小不要超过8192](#textures-max-size)
- [7.4 正确对纹理进行分组](#textures-group)
## 重要术语
##### 关卡/地图
“map”(地图)这个词通常也会被称为“level”(关卡),两者的含义是等同的,在[这里](https://en.wikipedia.org/wiki/Level_(video_gaming)) 可以查看这个词的历史
##### 标识符(Identifier)
“标识符”(`Identifier`)是指所有类似于“名称”或起到“名称”作用的东西。 例如,资源的名称,或材质的名称,蓝图属性、变量名或文件夹名,或数据表行名称等......
##### 大小写(Case)
对于大小写的规范有数种,以下是几种常见的几种
> ###### 大驼峰式(PascalCase)
>
> 每个单词的首字母都是大写,单词之间没有其他字符,例如 :`DesertEagle`, `StyleGuide`, `ASeriesOfWords`.
>
> ###### 小驼峰式(camelCase)
>
> 第一个单词的首字母小写,后面的单词的首字母大写,例如:`desertEagle`, `styleGuide`, `aSeriesOfWords`.
>
> ###### 蛇式(Snake_case)
>
> 单词之间用下划线链接,单词的首字母可以大写也可以小写,例如:`desert_Eagle`, `Style_Guide`, `a_Series_of_Words`.
##### 变量/属性(Variables / Properties)
'变量'和'属性'两个词在很多情况下是可以互相通用的。但如果他们同时出现在一个环境时,含义有一些不同:
###### 属性(Property)
'属性'通常定义在一个类的内部。例如,如果一个类`BP_Barrel`有一个内部成员`bExploded`,那么`bExploded`可以是做是`BP_Barrel`的一个属性
当'属性'用在类的内部时,通常用来获取已经定义好的数据
###### 变量(Variable)
'变量'通常用在给函数传递参数,或者用在函数内的局部变量
当'变量'用在类的内部时,通常是用来定义什么或者用来保存某些数据的。
## 0. 基本原则
以下改编自[idomatic.js代码规范](https://github.com/rwaldron/idiomatic.js/).
### 0.1 如果你的项目已经存在现有规范,那么请继续遵守规范
如果你工作的项目或你的团队已经有一套自己的规范,那么请尊重它。如果现有规范和本套规范发生冲突,请继续遵守原规范.
好的项目规范应该是不断进步的,当你发现有好的更改可以适合所有用户时,你应该建议去更改现有规范.
> #### "对规范优劣的争论是没有意义的,有规范就该去遵守。"
> [_Rebecca Murphey_](https://rmurphey.com)
### 0.2 不管团队中有多少人,工程中所有的数据结构、资源、代码风格应该统一,如同是同一个人的作品
把资源从一个工程迁移到另一个工程不应该产生新的学习成本,所有资源应该符合项目规范,消除不必要的歧义和不确定性.
遵守规范可以促进对于项目的生产和维护效率,因为团队成员不用去考虑规范问题,只需要去遵守。本套规范根据诸多优秀经验编写,遵守它意味着可以少走很多弯路.
### 0.3 真正的好朋友不会让对方写烂代码
如果你发现同事不遵守规范,该去纠正他们.
当在团队中工作时,或者在社区提问时(例如[Unreal Slackers](http://join.unrealslackers.org/)) ,你会发现如果大家都遵守同一套规范会容易的多,没有人愿意在面对一堆乱糟糟的蓝图或者莫名其妙的代码时帮你解决问题.
如果你要帮助的人使用另一套不同但很健全的规范,你应该去适应它,如果他们没有遵守任何规范,那么带他们来这儿.
### 0.4 谨慎加入没有规范的团队
当你要加入一个新的UE团队时,你应该首先问他们有没有项目规范,如果没有的话,你该怀疑他们是否有能力像一个真正的团队那样工作.
### 0.5 请遵守法律条款
Gamemakin 团队不是专业的律师,但请不要在项目中涉及违反法律的行为,包括但不限于:
* 请勿传播您无权传播的内容.
* 不得侵犯他人的版权或商标.
* 请勿窃取工程资产.
* 遵守资产的许可协议,例如当需要注明资产原创作者时,一定要注明.
## 00. 需要强制执行的全局规范
@TODO: Make this section 1 and update this document accordingly. Or maybe we don't?
### 00.1 禁止使用的字符
#### 标识符
对于标识符类型的命名,除非必要,**绝对不要**使用以下字符:
* 空格或者其他类似的空白字符
* 反斜杠 `\`
* 各种符号,例如 `#!@$%`
* 任何Unicode字符集
标识符应该只包含以下字符(用正则表达式表示就是`[A-Za-z0-9_]+`)
* ABCDEFGHIJKLMNOPQRSTUVWXYZ
* abcdefghijklmnopqrstuvwxyz
* 1234567890
* _ (下划线)
这样做的原因是,尽可能确保跨平台和工具链的兼容性。并有也有助于防止那些不是你控制的程序处理你的工程资产时,因为这些程序中的字符处理错误而导致的意外故障。
## 1. 资源命名约定
对于资源的命名的规范应该像法律一样被遵守。一个项目如果有好的命名规范,那么在资源管理、查找、解析、维护时,都会有极大的便利性。
大多数资源的命名都应该有前缀,前缀一般是资源类型的缩写,然后使用下划线和资源名链接。
### 1.1 基本命名规则 - `Prefix_BaseAssetName_Variant_Suffix`
所有资源都应该有一个 _BaseAssetName_ (基本资源名)。所谓基本资源名表明该资源在逻辑关系上属于那种资源,任何属于该逻辑组的资源都应该遵守同样的命名规范 `Prefix_BaseAssetName_Variant_Suffix`.
时刻谨记这个命名规范`Prefix_BaseAssetName_Variant_Suffix`,只要遵守它,大部分情况下都可以让命名规范。下面是详细的解释.
`Prefix`(前缀) 和 `Suffix`(后缀)由资源类型确定,请参照下面的[资源类型表](#asset-name-modifiers).
`BaseAssetName`(基本资源名)应该使用简短而便于识别的词汇,例如,如果你有一个角色名字叫做Bob,那么所有和Bob相关的资源的`BaseAssetName`都应该叫做`Bob`.
`Varient`(扩展名)用来保证资源的唯一性,同样,扩展名也应该是简短而容易理解的短词,以说明该资源在所属的资源逻辑组中的子集。例如,如果Bob有多套皮肤,那么这些皮肤资源都应该使用Bob作为基本资源名同时包含扩展名,例如'Evil'类型的皮肤资源,名字应该是`Bob_Evil`,而Retro类型的皮肤应该是用`Bob_Retro`.
一般来说,如果仅仅是为了保证资源的唯一性,`Varient`可以使用从`01`开始的两位数字来表示。例如,如果你要制作一堆环境中使用的石头资源,那么他们应该命名为`Rock_01`, `Rock_02`, `Rock_03`等等。除非特殊需要,不要让数字超过三位数,如果你真的需要超过100个的资源序列,那么你应该考虑使用多个基础资源名.
基于你所制作的资源扩展属性,你可以把多个扩展名串联起来。例如,如果你在制作一套地板所使用的资源,那么你的资源除了使用`Flooring`作为基本名,扩展名可以使用多个,例如`Flooring_Marble_01`, `Flooring_Maple_01`, `Flooring_Tile_Squares_01`.
#### 1.1 范例
##### 1.1e1 Bob
| 资源类型 | 资源名 |
| ----------------------- | ---------------------------------------------------------- |
| Skeletal Mesh | SK_Bob |
| Material | M_Bob |
| Texture (Diffuse/Albedo)| T_Bob_D |
| Texture (Normal) | T_Bob_N |
| Texture (Evil Diffuse) | T_Bob_Evil_D |
##### 1.1e2 Rocks
| 资源类型 | 资源名 |
| ----------------------- | ---------------------------------------------------------- |
| Static Mesh (01) | S_Rock_01 |
| Static Mesh (02) | S_Rock_02 |
| Static Mesh (03) | S_Rock_03 |
| Material | M_Rock |
| Material Instance (Snow)| MI_Rock_Snow |
### 1.2 资源类型表
当给一个资源命名的时候,请参照以下表格来决定在[基本命名](#base-asset-name)中所使用的前缀和后缀
#### 1.2.1 通用类型(Most Common)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Level / Map | | | [所有地图应该放在Maps目录下](#2.4) |
| Level (持久关卡) | | _P | |
| Level (音效关卡) | | _Audio | |
| Level (光照) | | _Lighting | |
| Level (几何体) | | _Geo | |
| Level (Gameplay) | | _Gameplay | |
| Blueprint | BP_ | | |
| Material | M_ | | |
| Static Mesh | S_ | | 很多人使用 SM_. 但我们建议用 S_. |
| Skeletal Mesh | SK_ | | |
| Texture | T_ | _? | 参照[纹理](#anc-textures) |
| Particle System | PS_ | | |
| Widget Blueprint | WBP_ | | |
#### 1.2.2 动作(Animations)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Aim Offset | AO_ | | |
| Aim Offset 1D | AO_ | | |
| Animation Blueprint | ABP_ | | |
| Animation Composite | AC_ | | |
| Animation Montage | AM_ | | |
| Animation Sequence | A_ | | |
| Blend Space | BS_ | | |
| Blend Space 1D | BS_ | | |
| Level Sequence | LS_ | | |
| Morph Target | MT_ | | |
| Paper Flipbook | PFB_ | | |
| Rig | Rig_ | | |
| Skeletal Mesh | SK_ | | |
| Skeleton | SKEL_ | | |
### 1.2.3 人工智能(Artificial Intelligence)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| AI Controller | AIC_ | | |
| Behavior Tree | BT_ | | |
| Blackboard | BB_ | | |
| Decorator | BTDecorator_ | | |
| Service | BTService_ | | |
| Task | BTTask_ | | |
| Environment Query | EQS_ | | |
| EnvQueryContext | EQS_ | Context | |
### 1.2.4 蓝图(Blueprints)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------------- | ---------- | ---------- | -------------------------------- |
| Blueprint | BP_ | | |
| Blueprint Component | BP_ | Component | 例如 BP_InventoryComponent |
| Blueprint Function Library | BPFL_ | | |
| Blueprint Interface | BPI_ | | |
| Blueprint Macro Library | BPML_ | | 可能的话尽量不要使用蓝图宏. |
| Enumeration | E | | 没有下划线. |
| Structure | F or S | | 没有下划线. |
| Tutorial Blueprint | TBP_ | | |
| Widget Blueprint | WBP_ | | |
### 1.2.5 材质(Materials)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------------- | ---------- | ---------- | -------------------------------- |
| Material | M_ | | |
| Material (Post Process) | PP_ | | |
| Material Function | MF_ | | |
| Material Instance | MI_ | | |
| Material Parameter Collection | MPC_ | | |
| Subsurface Profile | SP_ | | |
| Physical Materials | PM_ | | |
| Decal | M_, MI_ | _Decal | |
### 1.2.6 纹理(Textures)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------------- | ---------- | ---------- | -------------------------------- |
| Texture | T_ | | |
| Texture (Diffuse/Albedo/Base Color)| T_ | _D | |
| Texture (Normal) | T_ | _N | |
| Texture (Roughness) | T_ | _R | |
| Texture (Alpha/Opacity) | T_ | _A | |
| Texture (Ambient Occlusion) | T_ | _O | |
| Texture (Bump) | T_ | _B | |
| Texture (Emissive) | T_ | _E | |
| Texture (Mask) | T_ | _M | |
| Texture (Specular) | T_ | _S | |
| Texture (Metallic) | T_ | _M | |
| Texture (Packed) | T_ | _* | 参照下面的[多重纹理](#anc-textures-packing). |
| Texture Cube | TC_ | | |
| Media Texture | MT_ | | |
| Render Target | RT_ | | |
| Cube Render Target | RTC_ | | |
| Texture Light Profile | TLP | | |
#### 1.2.6.1 多重纹理(Texture Packing)
把多张纹理存于一个纹理文件中是很常见的方法,比如通常可以把自发光(Emissive), 粗糙度(Roughness), 环境光(Ambient Occlusion)以RGB通道的形式保存在纹理中,然后在文件的后缀中,注明这些信息,例如`_EGO`
> 一般来说,在纹理的Diffuse信息中附带Alpha/Opacity信息是很常见的,这时在`_D`后缀中可以加入`A`也可以不用加
不推荐同时把RGBA四个通道的信息保存在一张纹理中,这是由于带有Alpha通道的纹理要比不带的占用更多的资源,除非Alpha信息是以蒙版(Mask)的形式保存在Diffuse/Albedo通道中。
### 1.2.7 杂项(Miscellaneous)
| 资源类型 | 前缀 | 后缀 | 备注 |
| -------------------------- | ---------- | ---------- | -------------------------------- |
| Animated Vector Field | VFA_ | | |
| Camera Anim | CA_ | | |
| Color Curve | Curve_ | _Color | |
| Curve Table | Curve_ | _Table | |
| Data Asset | *_ | | 前缀取决于何种类型资源. |
| Data Table | DT_ | | |
| Float Curve | Curve_ | _Float | |
| Foliage Type | FT_ | | |
| Force Feedback Effect | FFE_ | | |
| Landscape Grass Type | LG_ | | |
| Landscape Layer | LL_ | | |
| Matinee Data | Matinee_ | | |
| Media Player | MP_ | | |
| File Media Source | FMS_ | | |
| Object Library | OL_ | | |
| Redirector | | | (暂时空缺,尽快解决). |
| Sprite Sheet | SS_ | | |
| Static Vector Field | VF_ | | |
| Substance Graph Instance | SGI_ | | |
| Substance Instance Factory | SIF_ | | |
| Touch Interface Setup | TI_ | | |
| Vector Curve | Curve_ | _Vector | |
### 1.2.8 Paper 2D
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Paper Flipbook | PFB_ | | |
| Sprite | SPR_ | | |
| Sprite Atlas Group | SPRG_ | | |
| Tile Map | TM_ | | |
| Tile Set | TS_ | | |
### 1.2.9 物理(Physics)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Physical Material | PM_ | | |
| Physics Asset | PHYS_ | | |
| Destructible Mesh | DM_ | | |
### 1.2.10 声音(Sounds)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Dialogue Voice | DV_ | | |
| Dialogue Wave | DW_ | | |
| Media Sound Wave | MSW_ | | |
| Reverb Effect | Reverb_ | | |
| Sound Attenuation | ATT_ | | |
| Sound Class | | | 没有前缀和后缀,这些资源应该放在SoundClasses目录中 |
| Sound Concurrency | | _SC | 在SoundClass之后命名 |
| Sound Cue | A_ | _Cue | |
| Sound Mix | Mix_ | | |
| Sound Wave | A_ | | |
### 1.2.11 界面(User Interface)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Font | Font_ | | |
| Slate Brush | Brush_ | | |
| Slate Widget Style | Style_ | | |
| Widget Blueprint | WBP_ | | |
### 1.2.12 特效(Effects)
| 资源类型 | 前缀 | 后缀 | 备注 |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Particle System | PS_ | | |
| Material (Post Process) | PP_ | | |
**[⬆ 返回顶层](#table-of-contents)**
## 2. `Content`的目录结构
对资源目录的规范管理和资源文件同等重要,都应该像法律一样被严格遵守。不规范的目录结构会导致严重的混乱。
有多种不同管理UE资源目录的方法,在本套规范中,我们尽量利用了UE的资源浏览器的过滤和搜索功能来查找资源,而不是按照资源类型来划分目录结构。
> 如果你正确遵守了前面使用前缀的资源[命名规范](#1.2),那么就没有必要按照资源类型创建类似于`Meshes`, `Textures`, 和 `Materials`这样的目录结构,因为你可以在过滤器中通过前缀来找到特定类型的资源
### 2e1 目录结构示例
|-- Content
|-- GenericShooter
|-- Art
| |-- Industrial
| | |-- Ambient
| | |-- Machinery
| | |-- Pipes
| |-- Nature
| | |-- Ambient
| | |-- Foliage
| | |-- Rocks
| | |-- Trees
| |-- Office
|-- Characters
| |-- Bob
| |-- Common
| | |-- Animations
| | |-- Audio
| |-- Jack
| |-- Steve
| |-- Zoe
|-- Core
| |-- Characters
| |-- Engine
| |-- GameModes
| |-- Interactables
| |-- Pickups
| |-- Weapons
|-- Effects
| |-- Electrical
| |-- Fire
| |-- Weather
|-- Maps
| |-- Campaign1
| |-- Campaign2
|-- MaterialLibrary
| |-- Debug
| |-- Metal
| |-- Paint
| |-- Utility
| |-- Weathering
|-- Placeables
| |-- Pickups
|-- Weapons
|-- Common
|-- Pistols
| |-- DesertEagle
| |-- RocketPistol
|-- Rifles
在以下章节中,将会解释使用这种目录结构的原因
### 2.1 文件夹命名
关于文件夹的命名,有一些通用的规范.
#### 2.1.1 使用大驼峰规范(PascalCase)[*](#terms-cases)
大驼峰规范也叫PascalCase规范,也就是所有单词的首字母大写,并且中间没有任何连接符。例如`DesertEagle`, `RocketPistol`, and `ASeriesOfWords`.
参照[大小写规范](#terms-cases).
#### 2.1.2 不要包含空格
作为对[2.1.1](#2.1.1)的补充,绝对不要在目录名中使用空格。空格会导致引擎以及其他命令行工具出现错误,同样,也不要把你的工程放在包含有空格的目录下面,应该放在类似于`D:\Project`这样的目录里,而不是`C:\Users\My Name\My Documents\Unreal Projects`这样的目录。
#### 2.1.3 不要使用奇怪的符号
如果你游戏中的角色的名字叫做`Zoë`,那么文件夹要其名为`Zoe`。在目录名中使用这样的Unicode字符的后果甚至比使用空格还严重,因为某些引擎工具在设计时压根就没有考虑这种情况。
顺便说一句,如果你的工程碰到了类似于[这篇帖子](https://answers.unrealengine.com/questions/101207/undefined.html) 中的情况,并且当前使用的系统用户名中包含有Unicode字符(比如 `Zoë`),那么只要把工程从`My Documents`目录移到类似于`D:\Project`这种简单的目录里就可以解决了。
记住永远在目录名中只使用`a-z`, `A-Z`, 和 `0-9`这些安全的字符,如果你使用了类似于`@`, `-`, `_`, `,`, `*`, 或者 `#`这样的字符,难免会碰到一些操作系统、源码管理工具或者一些弱智的工具让你吃个大亏。
### 2.2 使用一个顶级目录来保存所有工程资源
所有的工程资源都应该保存在一个以工程名命名的目录中。例如你有一个工程叫做'Generic Shooter',那么 _所有_ 该工程的资源都应该保存在`Content/GenericShooter`目录中.
> 开发者目录`Developers`不用受此限制,因为开发者资源是跨工程使用的,参照下面的[开发者目录](#2.3)中的详细说明.
使用顶级目录的原因有很多,下面是详细的解释.
#### 2.2.1 避免全局资源
通常在代码规范中会警告你不要使用全局变量以避免污染全局命名空间。基于同样的道理,在工程目录之外保存的资源对于资源管理会造成不必要的干扰。
每个资源都应该有它存在的意义,不然它就不应该出现在工程目录中。那些仅仅是为了测试而使用的临时资源,应该放在[`Developer`](#2.3)目录中。
#### 2.2.2 减少资源迁移时的冲突
当一个团队有多个项目时,从一个项目中把资源拷贝到另一个项目会非常频繁,这时最方便的方法就是使用引擎的资源浏览器提供的Migrate功能,因为这个功能会把资源的依赖项一起拷贝到目标项目中.
这些依赖项经常造成麻烦。如果两个工程没有遵守项目顶级目录规则,那么这些依赖项很容易就会被拷贝过来的同名资源覆盖掉,从而造成意外的更改。
这也是为什么EPIC会强制要求商城中出售的资源要遵守同样的规定的原因
执行完Migrate资源拷贝后,安全的资源合并方法是使用资源浏览器中的'替换引用'(Replace References)工具,把不属于工程目录中的资源引用替换掉。一旦资源资源完成完整的合并流程,工程目录中不应该存在另一个工程的顶级目录。这种方法可以_100%_保证资源合并的安全性。
##### 2.2.2e1 举例:基础材质的麻烦
举个例子,你在第一个工程中创建了一种基础材质,然后你把这个材质迁移到了另一个目标工程中使用。如果你的资源结构中没有顶级目录的设计,那么这个基础材质可能放在`Content/MaterialLibrary/M_Master`这样的目录中,如果目标工程原本没有这个材质,那么很幸运暂时不会有麻烦。
随着两个工程的推进,有可能这个基础材质因为两个工程的需求不同而发生了不同的修改。
于是问题出现了,其中一个项目的美术制作了一个非常不错的模型资源,另一个项目的美术想拿过来用。而这个资源使用了`Content/MaterialLibrary/M_Master`这个材质,那么当迁移这个模型时,`Content/MaterialLibrary/M_Master`这个资源就会出现冲突。
这种冲突难以解决也难以预测,迁移资源的人可能压根就不熟悉工程所依赖的材质是同一个人开发的,也不清楚所依赖的资源已经发生了冲突,迁移资源必须同时拷贝资源依赖项,所以`Content/MaterialLibrary/M_Master`就被莫名其妙覆盖了。
和这种情况类似,任何资源的依赖项的不兼容都会让资源在迁移中被破坏掉,如果没有资源顶级目录,资源迁移就会变成一场非常让人恶心的任务。
#### 2.2.3 官方提供的范例、模板和商城中的资产是安全的
正如上面[2.2.2](#2.2.2)所讲,如果一个团队想把官方提供的范例、模板以及商城中购买的资源放到自己的工程中,那么这些资源都是可以保证不会干扰现有工程的,除非你购买的资源工程和你的工程同名。
当然也不能完全信任商城上的资源能够完全遵守[顶级目录规则](#2.2)。的确有一些商城资源,尽管大部分资源放在了顶级目录下面,但仍然留下了部分资源污染了`Content`目录
如果坚持这个原则[2.2](#2.2),最糟糕的情况就是购买了两个不同的商场资源,结果发现他们使用了相同的EPIC的示例资源。但只要你坚持把自己的资源放在自己的工程目录中,并且把使用的EPIC示例资源也放在自己的目录中,那么自己工程也不会受到影响。
#### 2.2.4 使得DLC、子工程、以及补丁包容易维护
如果你的工程打算开发DLC或者子工程,那么这些子工程所需要的资源应该迁移出来放在另一个顶级目录中,这样的结构使得编译这些版本时可以区别对待子工程中的资源。子工程中的资源的迁入和迁出代价也更小。如果你想在子项目中修改一些原有工程中的资源,那么可以把这些资源迁移到子工程目录中,这样不会破坏原有工程。
### 2.3 使用开发者目录(`Developer`)做本地测试
在一个项目的开发期间,团队成员经常会有一个'沙箱'目录用来做测试而不会影响到工程本身。因为工作是连续的,所以即使这些'沙箱'目录也需要上传到源码服务器上保存。但并不是所有团队成员都需要这种开发者目录的,但使用开发者目录的成员来说,一旦这些目录是在服务器上管理的,总会需要一些麻烦事。
首先团队成员极容易使用这些尚未准备好的资源,这些资源一旦被删除就会引发问题。例如一个做模型的美术正在调整一个模型资源,这时一个做场景编辑的美术如果在场景中使用了这个模型,那么很可能会导致莫名其妙的问题,进而造成大量的工作浪费。
但如果这些模型放在开发者目录中,那么场景美术人员就没有任何理由使用这些资源。资源浏览器的缺省设置会自动过滤掉这个目录,从而保证正常情况下不可能出现被误用的情况。
一旦这些资源真正准备好,那么美术人员应该把它们移到正式的工程目录中并修复引用关系,这实际上是让资源从实验阶段'推进'到了生产阶段。
### 2.4 所有场景*文件应该保存在一个名为'Maps'的目录中
地图文件非常特殊,几乎所有工程都有自己的一套关于地图的命名规则,尤其是使用了sub-levels或者streaming levels技术时。但不管你如何组织自己的命名规则,都应该把所有地图保存在`/Content/Project/Maps`
记住,尽量使用不浪费大家的时间的方法去解释你的地图如何打开。比如通过子目录的方法去组织地图资源,例如建立 `Maps/Campaign1/` 或 `Maps/Arenas`,但最重要的是一定要都放在`/Content/Project/Maps`
这也有助于产品的打版本工作,如果工程里的地图保存的到处都是,版本工程师还要到处去找,就让人很恼火了,而把地图放在一个地方,做版本时就很难漏掉某个地图,对于烘培光照贴图或者质量检查都有利。
### 2.5 使用`Core`目录存储系统蓝图资源以及其他系统资源
使用`/Content/Project/Core`这个目录用来保存一个工程中最为核心的资源。例如,非常基础的`GameMode`, `Character`, `PlayerController`, `GameState`, `PlayerState`,以及与此相关的一些资源也应该放在这里。
这个目录非常明显的告诉其他团队成员:"不要碰我!"。非引擎程序员很少有理由去碰这个目录,如果工程目录结构合理,那么游戏设计师只需要使用子类提供的功能就可以工作,负责场景编辑的员工只需要使用专用的的蓝图就可以,而不用碰到这些基础类。
例如,如果项目需要设计一种可以放置在场景中并且可以被捡起的物体,那么应该首先设计一个具有被捡起功能的基类放在`Core/Pickups`目录中,而各种具体的可以被捡起的物体诸如药瓶、子弹这样的物体,应该放在`/Content/Project/Placeables/Pickups/`这样的目录中。游戏设计师可以在这些目录中定义和设计这些物体,所以他们不应该去碰`Core/Pickups`目录下的代码,要不然可能无意中破坏工程中的其他功能
### 2.6 不要创建名为`Assets` 或者 `AssetTypes`的目录
#### 2.6.1 创建名为`Assets`的目录是多余的
因为本来所有目录就是用来保存资产(`Assets`)的
#### 2.6.2 创建名为`Meshes`、 `Textures`或者`Materials`的目录是多余的
资源的文件名本身已经提供了资源类型信息,所以在目录名中再提供资源类型信息就是多余了,而且使用资源浏览器的过滤功能,可以非常便利的提供相同的功能。
比如想查看`Environment/Rocks/`目录下所有的静态Mesh资源?只要打开静态Mesh过滤器就可以了,如果所有资源的文件名已经正确命名,这些文件还会按照文件名和前缀正确排序,如果想查看所有静态Mesh和带有骨骼的Mesh资源,只要打开这两个过滤器就可以了,这种方法要比通过打开关闭文件夹省事多了。
> 这种方法也能够节省路径长度,因为用前缀`S_`只有两个字符,要比使用`Meshes/`七个字符短多了。
这么其实也能防止有人把Mesh或者纹理放在`Materials`目录这种愚蠢行为。
### 2.7 超大资源要有自己的目录结构
这节可以视为针对[2.6](#2.6)的补充
有一些资源类型通常文件数量巨大,而且每个作用都不同。典型的例子是动画资源和声音资源。如果你发现有15个以上的资源属于同一个逻辑类型,那么它们应该被放在一起。
举例来说,角色共用的动画资源应该放在`Characters/Common/Animations`目录中,并且其中应该还有诸如`Locomotion` 或者`Cinematic`的子目录
> 这并不适用与纹理和材质。比如`Rocks`目录通常会包含数量非常多的纹理,但每个纹理都都是属于特定的石头的,它们应该被正确命名就足够了。即使这些纹理属于[材质库](#2.8)
### 2.8 材质库`MaterialLibrary`
如果你的工程中使用了任何基础材质、分层材质,或者任何被重复使用而不属于特定模型的材质和纹理,这些资源应该放在材质库目录`Content/Project/MaterialLibrary`。
这样可以很容易管理这些'全局'材质
> 这也使得'只是用材质实例'这个原则得以执行的比较容易。如果所有的美术人员都只是用材质实例,那么所有的原始材质都应该保存在这个目录中。你可以通过搜索所有不在`MaterialLibrary`中的基础材质来验证这一点。
`MaterialLibrary`这个目录并不是仅能保存材质资源,一些共用的工具纹理、材质函数以及其他具有类似属性的资源都应该放在这个目录或子目录中。例如,噪声纹理应该保存在`MaterialLibrary/Utility`目录中。
任何用来测试或调试的材质应该保存在`MaterialLibrary/Debug`中,这样当工程正式发布时,可以很容易把这些材质从删除,因为这些材质如果不删除,可能在最终产品中非常扎眼。
### 2.9 避免空目录存在
很简单,不要有空的目录存在,会干扰资源浏览器的工作。
如果你发现无法删除一个空目录,尝试以下步骤
1. 首先确保正确使用了版本仓库
1. 针对工程运行文件夹引用修复功能(`Fix Up Redirectors`)
1. 从磁盘上打开对应的目录,删除其中的所有文件
1. 关闭编辑器
1. 确保版本仓库的状态是同步后的(例如如果正在使用的是Perforce,那么在Content目录运行"Reconcile Offline Work"功能)
1. 重新打开编辑器,确认所有的功能是否正常。如果出现异常,需要回退修改,然后找到问题所在重新尝试
1. 确保空文件已经被删除
1. 提交修改到版本仓库中
**[⬆ 返回顶层](#table-of-contents)**
## 3. 蓝图(Blueprint)
这一章会专注于蓝图和蓝图的实现。本规则会尽可能和[Epic官方提供的标准](https://docs.unrealengine.com/latest/INT/Programming/Development/CodingStandard) 一致。
要牢记: Blueprinting badly bears blunders, beware! (出自[KorkuVeren](http://github.com/KorkuVeren))
(译者: 视蓝图如同看到熊出没,一定要当心!)
### 3.1 编译(Compiling)
需要保证所有蓝图在编译时0警告和0错误。你应该尽快修复所有警告和异常,以免它们造成可怕的麻烦。
*绝对不要*提交那些断开的蓝图,如果你需要通过源码服务器保存,那么必须暂时搁置它们
断开的蓝图有巨大的破坏力,而且会影响到蓝图之外,比如造成引用失效,未定义的行为,烘培失败,或者频繁的重新编译。一个断开的蓝图可能会毁掉整个项目。
### 3.2 变量(Variables)
变量(`variable`)和属性(`property`)这两个词经常是可以互换的。
#### 3.2.1 命名(Naming)
##### 3.2.1.1 使用名词
所有非布尔类型的变量必须使用简短、清晰并且意义明确的**名词**作为变量名。
##### 3.2.1.2 大驼峰规范(PascalCase)
所有非布尔类型的变量的大小写需要遵守[大驼峰规范(PascalCase)](#terms-cases)规范。
###### 3.2.1.2e 范例
* `Score`
* `Kills`
* `TargetPlayer`
* `Range`
* `CrosshairColor`
* `AbilityID`
##### 3.2.1.3 布尔变量 `b` 前缀
所有布尔类型变量需要遵守[大驼峰规范](#terms-cases)规范,同时前面需要增加小写的`b`做前缀。
例如: 用 `bDead` 和 `bEvil`, **不要** 使用`Dead` 和 `Evil`.
UE的蓝图编辑器在显示变量名称时,会自动把前缀`b`去掉
##### 3.2.1.4 布尔类型变量命名规则
###### 3.2.1.4.1 孤立存在的状态信息
布尔类型变量如果用来表示一般的孤立存在状态,名字应该使用描述性的单词,且不要包含具有提问含义的词汇,比如`Is`,这个词是保留单词。
例如:使用`bDead` and `bHostile`,**不要**使用`bIsDead` and `bIsHostile`。
也不要使用类似于`bRunning`这样的动词,动词会让布尔变量的含义变得复杂。
###### 3.2.1.4.2 避免表达复杂状态
不要使用布尔变量保存复杂的,或者需要依赖其他属性的状态信息,这会让状态变得复杂和难以理解,如果需要尽量使用枚举来代替。
例如:当定义一个武器时,**不要**使用`bReloading` 和 `bEquipping`这样的变量,因为一把武器不可能即在reloading状态又在equipping状态,所以应该使用定义一个叫做`EWeaponState`的枚举,然后用一个枚举变量`WeaponState`来代替,这也使得以后增加新的状态更加容易。
例如:**不要**使用`bRunning`这样的变量,因为你以后有可能还会增加`bWalking` 或者 `bSprinting`,这也应该使用一个枚举来非常清晰的定义状态。
##### 3.2.1.5 考虑上下文
蓝图中的变量命名时需要考虑上下文环境,避免重复不必要的定义。
###### 3.2.1.5e Examples
假设有一个蓝图名为 `BP_PlayerCharacter`.
**不好的命名**
* `PlayerScore`
* `PlayerKills`
* `MyTargetPlayer`
* `MyCharacterName`
* `CharacterSkills`
* `ChosenCharacterSkin`
这些变量的命名都很臃肿。因为这些变量都是属于一个角色蓝图`BP_PlayerCharacter`的,没必要在变量中再重复这一点。
**好的命名**
* `Score`
* `Kills`
* `TargetPlayer`
* `Name`
* `Skills`
* `Skin`
##### 3.2.1.6 **不要**在变量中包含原生变量类型名
所谓原生变量是指那些最简单的保存数据的变量类型,比如布尔类型、整数、浮点数以及枚举。
String和vectors在蓝图中也属于原生变量类型,即使技术上严格来讲它们其实不是。
> 由三个浮点数组成的vector经常被视为一个整体数据类型,比如旋转向量。
> 文本类型变量(Text)不属于原生类型,因为它们内部还包含有国际化信息。原生类型的字符串变量类型是`String` , 而不是`Text`。
原生类型的变量名中不应该包含变量类型名。
例如:使用`Score`, `Kills`, 以及 `Description`,**不要**使用`ScoreFloat`, `FloatKills`, `DescriptionString`。
但也有例外情况,当变量的含义包含了"多少个"这样的信息,**并且**仅用一个名字无法清晰的表达出这个含义时。
比如:游戏中一个围墙生成器,需要有一个变量保存在X轴上的生成数量,那么需要使用`NumPosts` 或者 `PostsCount`这样的变量,因为仅仅使用`Posts`可能被误解为某个保存Post的数组
##### 3.2.1.7 非原生类型的变量,需要包含变量类型名
非原生类型的变量是指那些通过数据结构保存一批原生类型的复杂变量类型,比如Structs、Classes、Interface,还有一些有类似行为的原生变量比如`Text` 和 `Name`也属于此列。
> 如果仅仅是原生变量组成的数组,那么这个数组仍然属于原生类型
这些变量的名字应该包含数据类型名,但同时要考虑不要重复上下文。
如果一个类中包拥有一个复杂变量的实例,比如一个`BP_PlayerCharacter`中有另一个变量`BP_Hat`,那么这个变量的名字就不需要包含变量类型了。
例如: 使用 `Hat`、`Flag`以及 `Ability`,**不要**使用`MyHat`、`MyFlag` 和 `PlayerAbility`
但是,如果一个类并不拥有这个属性,那么就需要在这个属性的名字中包含有类型的名字了
例如:一个蓝图类`BP_Turret`用来表示一个炮塔,它拥有瞄准`BP_PlayerCharacter`作为目标的能力,那么它内部会保存一个变量作为目标,名字应该是`TargetPlayer`,这个名字非常清楚的指明了这个变量的数据类型是`Player`。
##### 3.2.1.8 数组
数组的命名规则通常和所包含的元素的规则一样,但注意要用复数。
例如:用`Targets`、`Hats`以及 `EnemyPlayers`,**不要**使用`TargetList`、`HatArray` 或者 `EnemyPlayerArray`
#### 3.2.2 可编辑变量
所有为了配置蓝图行为,可以安全的更改数据内容的变量都需要被标记为`Editable`
相反,那些不能更改或者不能暴露给设计师的变量,都**不能**标上可编辑标志,除非因为引擎的原因,这些变量需要被标为`Expose On Spawn`
总之不要滥用`Editable`标记
##### 3.2.2.1 Tooltips
对于所有标记为`Editable`的变量,包括被标记为 `Expose On Spawn`的变量,都应该在其`Tooltip`内填写关于如何改变变量值,以及会产生何种效果的说明。
##### 3.2.2.2 滑动条(Slider)以及取值范围
对于可编辑的变量,如果不适合直接输入具体数值,那么应该通过一个滑动条(Slider)并且加上取值范围来让设计师输入。
举例:一个产生围墙的蓝图,拥有一个`PostsCount`的变量,那么-1显然适合不合理的输入,所以需要设上取值范围注明0是最小值
如果在构造脚本中需要一个可编辑变量,那么一定要首先定义一个合理的取值范围,要不然可能会有人设上一个非常大的值造成编辑器崩溃。
一个变量的取值范围只有当明确知道其范围时才需要定义,因为滑块的取值范围的确能够阻止用户输入危险数值,但用户仍然能够通过手动输入的方式输入一个超出滑块范围的值给变量,如果变量的取值范围未定义,那么这个值就会变得'很危险'而且仍然会生效。
#### 3.2.3 分类
如果一个类的变量很少,那么没有必要使用分类
如果一个类的变量规模达到中等(5-10),那么所有`可编辑`的变量应该自己的分类,而不应该放在缺省分类中,通常叫做 `Config`
如果类中的变量的数量非常大,那么所有可编辑的变量都应该放在`Config`分类的子分类下,所有不可编辑的变量应该根据它们的用途建立相关分类保存
> 可以通过在分类名中添加字符`|`,直接建立子分类,比如`Config | Animations`
举例:一个武器的类中的变量分类目录大致如下:
|-- Config
| |-- Animations
| |-- Effects
| |-- Audio
| |-- Recoil
| |-- Timings
|-- Animations
|-- State
|-- Visuals
#### 3.2.4 变量的访问权限
在C++中,变量的访问类型由类成员的属性决定,Public类型的表示其他类都可以访问,Protetced类型的成员表示子类可以访问,Private类型变量表示只有类内部函数可以访问此变量。
蓝图并没有类似的权限访问设计。
可以视可编辑(`Editable`)类型的变量作为Public类型变量,视不可编辑的变量作为Protected类型变量。
##### 3.2.4.1 私有变量
尽量不要把变量声明为private类型,除非一开始就打算这个变量永远只能被类内部访问,并且类本身也没打算被继承。尽量用`protected`,只有当你有非常清楚的理由要去限制子类的能力时,再使用private类型。
#### 3.2.5 高级显示
如果一个变量可以被编辑,但通常不会有人碰到,那么就把它标记为高级显示`Advanced Display`。这些变量在蓝图中会缺省隐藏,除非点击节点上的高级显示箭头。
有意思的是,`Advanced Display`这个选项本身,在编辑器的变量属性中也是一个高级显示类型的。
#### 3.2.6 Transient变量
Transient类型的变量是指那些不需要被序列化(保存或者加载),并且初始值为0或者null的变量。一般在引用其他对象时会使用,它们的值只有在运行时才确定。这样做能防止编辑器在磁盘上多存储一份多余的数据,以加快蓝图的存盘和加载速度。
因此,所有Transient类型变量都应该被初始化成0或者null。如果是其他值会增加调试bug的难度。
#### 3.2.8 Config变量
不要使用`Config Variable`标记,这会让设计师在控制蓝图行为上更加困难。这个标记一般用在C++中,用来标记那些极少被改变的变量,你可以认为它们是那些被标上`Advanced Advanced Display`的变量
### 3.3 函数、事件以及事件派发器
这一节用来解释应该如何管理函数、事件以及事件派发器。除非特殊说明,所有适用于函数的规则,同样适用于事件。
#### 3.3.1 函数命名
对于函数、事件以及事件派发器的命名极其重要,仅仅从一个名字本身,就有很多条件要考虑,比如说:
* 是纯虚函数吗?
* 是状态查询函数吗?
* 是事件响应函数吗?
* 是远程调用函数吗?
* 函数的目的是什么?
如果命名得当,这些问题甚至更多问题的答案会在名字中体现出来。
#### 3.3.1.1 所有函数的命名都应该是动词
所有函数和事件执行者都是需要做一些动作,可能是去获取信息,也可能是数据计算,或者搞点什么事情。因此,所有函数都应该用动词开始,并且用一般现代时态,并且有上下文来表明它们究竟在做什么
`OnRep` 这样的响应函数,事件具柄和事件派发器的命名不遵守这个规则。
好的例子:
* `Fire` - 如果类是一个角色或者武器,那么这是一个好命名,如果是木桶,玻璃,那这个函数就会让人困惑了。
* `Jump` - 如果类是一个角色,那么这是个好名字,如果不是,那么需要一些上下文来解释这个函数的含义
* `Explode`
* `ReceiveMessage`
* `SortPlayerArray`
* `GetArmOffset`
* `GetCoordinates`
* `UpdateTransforms`
* `EnableBigHeadMode`
* `IsEnemy` - ["Is" 是个动词](http://writingexplained.org/is-is-a-verb)
不好的例子:
* `Dead` - 是已经死了?还是死的动作?
* `Rock`
* `ProcessData` - 无意义,这个名字等于没说.
* `PlayerState` - 不能用名词
* `Color` - 如果是动词,那么缺少上下文,如果是名词,也不行.
#### 3.3.1.2 属性的状态变化响应函数应该命名为`OnRep_Variable`
所有用来响应状态变化的函数应该用`OnRep_Variable`的形式,这是由蓝图编辑器强制规定的,如果你在C++中写`OnRep`函数,应该同样遵守这个规则。
#### 3.3.1.3 返回布尔变量的信息查询函数应该是问询函数
如果一个函数不改变类的状态,并且只是返回信息、状态或者计算返回给调用者yes/no,这应该是一个问询函数。同样遵守[动词规则](#bp-funcs-naming-verbs)。
非常重要的是,应该假定这样的函数其实就是执行某种动作,并且返回动作是否执行成功。
好的例子:
* `IsDead`
* `IsOnFire`
* `IsAlive`
* `IsSpeaking`
* `IsHavingAnExistentialCrisis`
* `IsVisible`
* `HasWeapon` - ["Has" 是动词.](http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html)
* `WasCharging` - ["Was" 是动词"be"的过去式](http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html) 用 "was"表示查询以前的状态
* `CanReload` - ["Can"是动词](http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html)
坏的例子:
* `Fire` - 是查询正在开火?还是查询能不能开火?
* `OnFire` - 有可能和事件派发器函数混淆
* `Dead` - 是查询已经死亡?还是查询会不会死亡?
* `Visibility` - 是查询可见状态?还是设置可见状态?
#### 3.3.1.4 事件的响应函数和派发函数都应该以`On`开头
事件的响应函数和派发函数都应该以`On`开头,然后遵守[动词规则](#bp-funcs-naming-verbs),如果是过去式,那么动词应该移到最后以方便阅读
在遵守动词规则的时候,需要优先考虑英语中的[固定句式](http://dictionary.cambridge.org/us/grammar/british-grammar/about-words-clauses-and-sentences/collocation)
有一些系统用`Handle`来表示事件响应,但在'Unreal'用的是`On`而不是`Handle`,
好的例子:
* `OnDeath` - Common collocation in games
* `OnPickup`
* `OnReceiveMessage`
* `OnMessageRecieved`
* `OnTargetChanged`
* `OnClick`
* `OnLeave`
坏的例子:
* `OnData`
* `OnTarget`
* `HandleMessage`
* `HandleDeath`
#### 3.3.1.5 远程调用函数应该用目标作为前缀
Any time an RPC is created, it should be prefixed with either `Server`, `Client`, or `Multicast`. No exceptions.
After the prefix, follow all other rules regarding function naming.
Good examples:
任何时候创建RPC函数,都应该把目标作为前缀放在前面,例如`Server`、 `Client`或者 `Multicast`,没有例外。
前缀之后的部分,遵守上面的其他规则。
好的例子:
* `ServerFireWeapon`
* `ClientNotifyDeath`
* `MulticastSpawnTracerEffect`
坏的例子:
* `FireWeapon` - 没有使用目标前缀
* `ServerClientBroadcast` - 混乱
* `AllNotifyDeath` - 用 `Multicast`, 不要用 `All`.
* `ClientWeapon` - 没有用动词, 让人困惑.
#### 3.3.2 所有函数都应该有返回节点
所有函数都应该有返回节点,没有例外。
返回节点明确标注了蓝图到此执行完毕。蓝图中的结构有可能有并行结构`Sequence`、循环结构`ForLoopWithBreak`或者逆向的回流节点组成,明确结束节点使蓝图易于阅读维护和调试。
如果启用了返回节点,当你的蓝图中有分支没有正常返回,或者流程有问题,蓝图的编译器会提出警告。
比如说,有程序员在并行序列中添加了一个新的分支,或者在循环体外添加逻辑但没有考虑到循环中的意外返回,那么这些情况都会造成蓝图的执行序列出现意外。蓝图编译器会立即给这些情况提出警告。
#### 3.3.3 蓝图函数中节点数不应该超过50个
简单来说,蓝图函数中的节点数应该小于50个,如果函数过于复杂,应该把它分割成几个小一点的函数,以便更好的阅读和维护。
在蓝图中添加以下节点不用计算个数,因为它们并不会增加蓝图的复杂度:
* Comment - 注释
* Route - 路由节点
* Cast - 类型转换节点
* Getting a Variable - 获取变量
* Breaking a Struct - 结构分解节点
* Function Entry - 函数入口
* Self - 自身节点
#### 3.3.4 所有Public函数都应该有功能描述
此规则更适用于公开或在市场出售的蓝图,以便其他人可以更轻松地浏览和使用您的蓝图。
简而言之,任何具有 Public 访问权限的函数都应该填写其描述。
#### 3.3.5 插件中可以在蓝图中调用的自定义函数都应该放在以插件名命名的类别中
如果你的工程包含插件,插件中定义了一些静态的可以被蓝图调用的函数,那么这些函数(`Category`)的类别应该被设置成插件的名称。
例如,`Zed Camera Interface` 或者 `Zed Camera Interface | Image Capturing`.
### 3.4 蓝图图形
本节包含了关于蓝图图形的内容
#### 3.4.1 不要画‘意面’
蓝图中所有连线都应该有清晰的开始点和结束点。你的蓝图不应该让阅读者在一堆乱糟糟的线中翻来翻去。以下内容可以帮你避免‘意大利面’样式的蓝图产生。
#### 3.4.2 保持连线对齐,而不是节点
不要试图让节点对齐,对齐的应该是连线。你无法控制一个节点的大小和上面连接点的位置,但你能通过控制节点的位置来控制连线。笔直的连线让整个蓝图清晰美观,歪歪扭扭的连线会让蓝图丑陋不堪。可以通过蓝图编辑器提供的功能直接让连线变直,方法是选择好节点,用快捷键Q
好的例子: 所有上面的节点的执行线都保持为直线。

不好的例子: 右上角节点的执行线歪了

可接受的例子: 有些节点无论你怎么用对齐工具都无法对齐,这种情况下,就尽量缩短它们之间连线的长度。

#### 3.4.3 白色的可执行线优先级最高
如果发现白色执行线和其他数据线无法同时对齐,白色执行线的优先级更高。
#### 3.4.4 蓝图需要有合理的注释
要善用蓝图的注释块,把相关的节点包含在注释块中,并在注释中描述这些功能节点的行为。虽然每个函数都应该被正确命名,以便每个单独的节点都易于理解,但仍然需要在注释中描述出为某个整体功能做出贡献的节点组的具体作用。如果一个函数没有很多节点块,并且很明显这些节点在函数目标中服务于最终目的,则不需要再对它们进行注释,函数名称和其描述中包含的信息就足够了。
#### 3.4.5 蓝图中需要在适当的地方处理类型转换错误
如果在函数或者蓝图事件处理过程中,总是假定类型转换应该是成功的,那么一旦出现类型转换失败,那应该及时报错,这使得其他模块得到通知,一件“应该正确工作”的函数没有正确工作。函数还应该在类型转换失败后,正确的恢复工作。
但这并不是强制要求所有的类型转换节点都要处理失败的情况,在很多情景中,尤其是类似于处理物理碰撞这样的事件中,处理类型转换失败就是悄悄结束而已就够了。
#### 3.4.6 避免出现空悬节点和死节点
所有蓝图中的节点都应该有其存在的意义,不要把空悬的节点,不会被执行的节点放在蓝图中
**[⬆ 返回顶层](#table-of-contents)**
## 4. 静态模型
这一节关注的是静态模型以及相关资源
### 4.1 静态模型的UV
使用Linter工具扫描工程报告错误和UV相关的错误时,如果您似乎无法追踪它,请打开项目的“Saved/Logs”文件夹中生成的“.log”文件,以获取有关失败原因的确切详细信息。 我希望将来能够将这些消息包含在Linter报告中。
#### 4.1.1 静态模型需要包含UV
很简单,所有的静态模型资源,不管他们要被怎么使用,都不应该不包含UV数据。
#### 4.1.2 静态模型的UV须要避免互相覆盖
同样很简单,所有的静态模型资源,不管他们要被怎么使用,都应该有正确的不互相覆盖的UV数据。
### 4.2 正确的设置LOD
这是一项工程级别的偏主观的检查,作为一条广为人知的规则,所有在玩家视野中会出现的物体,都应该正确的设置LOD数据。
### 4.3 不带插槽的模块化的模型需要严格对齐网格
这是一项针对每个具体资产的偏主观检查,模块化模型如何能够正确的对齐是基于工程设置中的和网格相关的设置。
模块对齐大小是2的幂还是10的倍数也是取决于项目设置,不过如果你想把你的资产在商城中出售,Epic的规定是对齐网格大小是10个单位或者更大。
### 4.4 所有模型需要有碰撞体
无论模型是否将会在关卡中产生物理碰撞,都应定义正确物理碰撞体数据。 这有助于引擎进行绑定盒计算、遮挡和照明等工作。 资产的碰撞体也需要良好的定义。
### 4.5 所有模型资源需要正确的缩放系数
这是一项工程级别的偏主观的检查,所有模型都应根据其项目设置正确的大小。 关卡设计师或蓝图作者大部分情况下都不必在使用模型时,再去调整模型的放缩系数。 在引擎中的缩放模型应被视为一种调整,而不是校正。
**[⬆ 返回顶层](#table-of-contents)**
## 5. Niagara
这一小节关注的是Niagara和相关资产。
### 5.1 永远都不要用空格
正如[禁止使用的字符](#00.1) 中提到的,标识符中严禁使用空格和所有空白字符。 对于 Niagara系统尤其如此,因为在Niagara中使用HLSL或其他脚本,当这些脚本尝试引用带空格的标识符时,会使事情变得更加困难。
(该条款贡献者为[@dunenkoff](https://github.com/Allar/ue5-style-guide/issues/58))
**[⬆ 返回顶层](#table-of-contents)**
## 6. 关卡 / 地图
[请参照术语中](#terms-level-map) 对 "关卡" 和 "地图"的解释
本小节关注的是关卡及其相关资产
### 6.1 解决掉错误和警告
所有关卡的加载对错误和警告都应为零容忍的。如果关卡加载时出现任何错误或警告,应立即修复它们以防止连锁问题。
您可以在控制台使用命令“map check”在编辑器中运行地图检查工具。
请注意:Linter对关卡的检查比编辑器更加严格,并且会捕获那些编辑器自行解决的错误。
### 6.2 记得构建光照
在项目开发过程中,偶尔没有构建照明是正常的。 然而在进行测试/内测/正式版构建时,或任何可能会分发的构建时,都应始终构建光照。
### 6.3 不要让玩家看到Z Fighting
不要让玩家在关卡中任何可见区域中发现[z-fighting](https://en.wikipedia.org/wiki/Z-fighting)。
### 6.4 商城需要遵守的规范
如果是需要上架UE商城的资源工程,需要额外遵守以下规范。
#### 6.4.1 预览场景
如果您的项目有可视的美术资产,则您的项目中必须有一个名称中带有“Overview”的地图。
而这张预览地图,应该遵守[Epic的规范](http://help.epicgames.com/customer/en/portal/articles/2592186-marketplace-submission-guidelines-preparing-your-assets#Required%20Levels%20and%20Maps).
例如, `InteractionComponent_Overview`.
#### 6.4.2 演示场景
如果您的项目中包含用于演示或者教学的资产,那么工程中有还需要一个名称中带有“Demo”的地图。 此地图应带有某种形式的文档,说明如何使用您的项目。 请参阅 Epic 提供的的"Content Examples project",了解如何执行此操作的好范例。
如果您的项目主要是关于GamePlay或其他内容的,而不是美术资产,那么演示场景可以与预览场景是同一个场景。
例如, `InteractionComponent_Overview_Demo`, `ExplosionKit_Demo`.
**[⬆ 返回顶层](#table-of-contents)**
## 7. 纹理
本小节关注的是纹理及其相关资产
### 7.1 纹理尺寸必须是2的幂
所有纹理,尤其是UI纹理,纹理的尺寸必须是2的幂,但并不一定是正方形的。
例如, `128x512`, `1024x1024`, `2048x1024`, `1024x2048`, `1x512`.
### 7.2 纹理图案密度应该保持一致
所有纹理的大小都应适合项目的标准用例。 每个项目中定义的纹理密度各不相同,但同一个项目中的纹理应具有一致的密度。
例如,如果项目的纹理密度为每1单位8像素,那么用于渲染100x100单位的立方体所使用的纹理应为1024x1024,因为这是与项目纹理密度最接近且是2的幂的纹理尺寸了。
### 7.3 纹理大小不要超过8192
不应该使用超过8K的纹理,除非你有强烈的理由使用它。通常用大纹理只是再浪费资源
### 7.4 正确对纹理进行分组
每个纹理都应该属于一个正确的纹理组,用于做LOD计算,应根据纹理的用途正确设置。 例如,所有UI纹理都应属于UI纹理组
**[⬆ 返回顶层](#table-of-contents)**
## 主要贡献者
* [Michael Allar](http://allarsblog.com): [GitHub](https://github.com/Allar), [Twitter](https://twitter.com/michaelallar)
* [CosmoMyzrailGorynych](https://github.com/CosmoMyzrailGorynych)
* [billymcguffin](https://github.com/billymcguffin)
* [akenatsu](https://github.com/akenatsu)
## 版权声明
Copyright (c) 2016 Gamemakin LLC
See [LICENSE](/LICENSE)
**[⬆ 返回顶层](#table-of-contents)**
## 修正
我们鼓励您fork本规范并更根据团队的实际情况对本规范进行修改。但是建议您把所作的修改列在后面,这使您可以定期更新该规范,而不必处理合并冲突。
# };
================================================
FILE: README_PTBR.md
================================================
# [Gamemakin](https://gamemak.in) UE4 - Guia de Estilo() {
*Uma abordagem bastante razoável para Unreal Engine 4*
Inspirado pelo [Guia de Estilo Airbnb Javascript](https://github.com/airbnb/javascript).
[](#)
## Nota de tradução
Foram mantidos os nomes e expressões em inglês comumente usadas na Unreal Engine e.x. "texture", "material", "asset", etc.
## Aviso de Repo
O repo original agora está localizado em https://github.com/Allar/ue5-style-guide. O branch padrão deste repositório foi renomeado `main`.
## Atualmente, é para UE4.
## Documentação do Guia de Estilo e Linter
Mais documentação técnicas sobre o Linter e o Guia de Estilo pode ser encontrada na página: [LeiaOsDocumentos](https://ue4-style-guide.readthedocs.io/en/latest/).
## Debata este guia de estilo
Gamemakin LLC tem um canal Discord público em http://discord.gamemak.in com um canal #linter se você gostaria de debater sobre o Guia de Estilo e o plugin Linter.
## Link para este documento
Cada seção deste Guia de Estilo é numerada para facilitar a referência e o link. Você pode vincular a qualquer seção diretamente acrescentando uma hashtag e o número da seção ao final de http://ue4.style
Por exemplo, se você deseja enviar a alguém o primeiro princípio deste Guia de Estilo, você deve colocar `#0.1`, resultando em http://ue4.style#0.1.
## Forks e Traduções
Se você fez um fork ou tradução que não é adequada para uma solicitação pull neste repo, envie uma solicitação pull para adicionar sua fork ou tradução aqui.
* [Tradução para Coreano](https://github.com/ymkim50/ue4-style-guide/blob/master/README_Kor.md) por ymkim50
* [Tradução para Russo](https://github.com/CosmoMyzrailGorynych/ue4-style-guide-rus/blob/master/README.md) por CosmoMyzrailGorynych
* [Tradução para Japonês](https://github.com/akenatsu/ue4-style-guide/blob/master/README.jp.md) por akenatsu
* [Tradução para Chinês](https://github.com/skylens-inc/ue4-style-guide/blob/master/README.md) por Beijing Skylens Tech.
* [Tradução para Português do Brasil](https://github.com/danlvr/ue5-style-guide/blob/main/README_PTBR.md) por danlvr.
## Terminologia Importante
##### Levels/Maps
A palavra 'map' geralmente se refere ao que a pessoa chama de 'level' e pode ser usado indistintamente. Veja a história deste termo [aqui](https://en.wikipedia.org/wiki/Level_(video_gaming)).
##### Identifiers
Um `Identifier` é qualquer coisa que se pareça ou sirva como um "nome". Por exemplo, o nome de um "asset", ou o nome de um "material", ou a propriedade de um "blueprint", uma variável, ou um nome de pasta, ou para um nome de uma linha de tabela de dados, etc...
##### Caixa Alta e Caixa Baixa
Existem algumas maneiras diferentes de você `NomearComCaixaAltaOuCaixaBaixa`. Aqui estão alguns tipos mais comuns:
> ###### PascalCase
>
> Capitalize cada palavra e remova todos os espaços, e.x. `DesertEagle`, `GuiaDeEstilos`, `UmaSerieDePalavras`.
>
> ###### camelCase
>
> A primeira letra é sempre minúscula mas todas as palavras seguintes começam com maiúsculas, e.x. `desertEagle`, `guiaDeEstilos`, `umaSerieDePalavras`.
>
> ###### Snake_case
>
> As palavras podem começar arbitrariamente com letras maiúsculas ou minúsculas, mas as palavras são separadas por um sublinhado, e.g. `desert_Eagle`, `Guia_de_Estilos`, `uma_Serie_de_Palavras`.
##### Variáveis / Propriedades
As palavras 'variável' e 'propriedade' na maioria dos contextos são intercambiáveis. No entanto, se ambas forem usados juntos no mesmo contexto considere:
###### Propriedade
Normalmente se refere a uma variável definida em uma classe. Por exemplo, se `BP_Barril` tinha uma variável `bExplodiu`, `bExplodiu` pode ser referido como uma propriedade de `BP_Barril`.
Quando no contexto de uma classe, muitas vezes é usado para implicar o acesso a dados previamente definidos.
###### Variável
Normalmente se refere a uma variável definida como um argumento de função ou uma variável local dentro de uma função.
Quando no contexto de uma classe, é freqüentemente usado para transmitir um debate sobre sua definição e o que ela conterá.
## 0. Princípios
Esses princípios foram adaptados de [guida de estilo idomatic.js](https://github.com/rwaldron/idiomatic.js/).
### 0.1 Se o seu projeto UE4 já tem um Guia de Estilo, você deve segui-lo.
Se você estiver trabalhando em um projeto ou com uma equipe que possui um guia de estilo pré-existente, ele deve ser respeitado. Qualquer inconsistência entre um guia de estilo existente e este guia, deve-se seguir o existente.
Os guias de estilo devem ser documentos vivos. Você deve propor alterações de guia de estilo a um guia de estilo existente, bem como a este guia, se achar que a alteração beneficia todos os seus usos.
> #### "Discussões sobre o estilo são desnecessárias. Deve sempre haver um Guia de Estilo e você deve segui-lo."
> [_Rebecca Murphey_](https://rmurphey.com)
### 0.2 Toda estrutura, assets e código em qualquer projeto Unreal Engine 4 devem parecer que foram criados por uma única pessoa, não importa quantas pessoas contribuíram.
Mudar de um projeto para outro não deve causar uma reaprendizagem de estilo e estrutura. A conformidade com um Guia de Estilo remove suposições e ambigüidades desnecessárias.
Também permite uma criação e manutenção mais produtivas, pois não é necessário pensar no estilo. Simplesmente siga as instruções. Este guia de estilo foi escrito com as práticas recomendadas em mente, o que significa que, ao seguir este guia de estilo, você também minimizará problemas difíceis de rastrear.
### 0.3 Amigos não deixam amigos terem estilo ruim.
Se você vir alguém trabalhando contra um guia de estilo ou sem nenhum guia de estilo, tente corrigi-lo.
Ao trabalhar em uma equipe ou discutir em uma comunidade, como a [Unreal Slackers](http://join.unrealslackers.org/), é muito mais fácil ajudar e pedir ajuda quando as pessoas são consistentes. Ninguém gosta de ajudar a desemaranhar o "espaguete" do Blueprint de alguém ou lidar com assets que tenham nomes que eles não conseguem entender.
Se você está ajudando alguém cujo trabalho segue um Guia de Estilo diferente, mas consistente e lógico, você deve ser capaz de se adaptar a ele. Se eles não estiverem de acordo com nenhum Guia de Estilo, indique-os aqui.
### 0.4 Uma equipe sem um Guia de Estilo não é a minha equipe.
Ao ingressar em uma equipe Unreal Engine 4, uma de suas primeiras perguntas deve ser "Você tem um Guia de Estilo?". Se a resposta for não, você deve duvidar da capacidade deles de trabalhar em equipe.
### 0.5 Não quebre a lei
A Gamemakin LLC não é composta por advogados, mas não introduza ações e comportamentos ilegais em um projeto, incluindo, mas não se limitando a:
* Não distribua conteúdo para o qual você não tem os direitos de distribuição
* Não infrinja o material protegido por direitos autorais ou marca registrada de outra pessoa
* Não roube conteúdo
* Siga as restrições de licenciamento de conteúdo, por exemplo atributo quando as atribuições são necessárias
## 00. Opiniões Globalmente Impostas
@TODO: Faça esta a Seção 1 e atualize este documento de acordo. Ou talvez não?
### 00.1 Caracteres Proibidos
#### Identifiers
Em qualquer `Identifier` de qualquer tipo, **nunca** use o seguinte, a menos que seja obrigado:
* Espaço em branco de qualquer tipo
* Barras invertidas `\`
* Símbolos e.x. `#!@$%`
* Qualquer caractere Unicode
Um `Identifier` deve ter apenas os seguintes caracteres, quando possível (expressão regular `[A-Za-z0-9_]+`)
* ABCDEFGHIJKLMNOPQRSTUVWXYZ
* abcdefghijklmnopqrstuvwxyz
* 1234567890
* _ (moderadamente)
O motivo para isso é que garantirá a maior compatibilidade de todos os dados em todas as plataformas em todas as ferramentas e ajudará a evitar o tempo de inatividade devido ao tratamento potencialmente incorreto de caracteres para identificadores em códigos que você não controla.
## Índice
> 1. [Convenções de nomenclatura de assets](#anc)
> 1. [Estrutura de Diretório](#structure)
> 1. [Blueprints](#bp)
> 1. [Static Meshes](#s)
> 1. [Particle Systems](#ps)
> 1. [Levels / Maps](#levels)
> 1. [Textures](#textures)
## 1. Convenções de Nomenclatura de Assets
As convenções de nomenclatura devem ser tratadas como lei. Um projeto que está em conformidade com uma convenção de nomenclatura pode ter seus assets gerenciados, pesquisados, analisados e mantidos com uma facilidade incrível.
Geralmente são prefixadas com um acrônimo do tipo de asset seguido por um sublinhado (_).
### 1.1 Nome Base do Asset - `Prefixo_NomeBaseDoAsset_Variante_Sufixo`
Todos os assets devem ter um _Nome Base do Asset_. Um nome de asset básico representa um agrupamento lógico de assets relacionados. Qualquer asset que faça parte deste grupo lógico deve seguir o padrão de `Prefixo_NomeBaseDoAsset_Variante_Sufixo`.
Mantendo o padrão `Prefixo_NomeBaseDoAsset_Variante_Sufixo` em mente e usar o bom senso geralmente é suficiente para garantir bons nomes de assets. Aqui estão algumas regras detalhadas sobre cada elemento.
`Prefixo` e `Sufixo` devem ser determinados pelo tipo de asset por meio do seguinte tabelas de [Modificador do Nome do Asset](#asset-name-modifiers).
`NomeBaseDoAsset` deve ser determinado por um nome curto e facilmente reconhecível relacionado ao contexto desse grupo de assets. Por exemplo, se você tivesse um personagem chamado Bob, todos os assets de Bob teriam o `NomeBaseDoAsset` de `Bob`.
Para variações únicas e específicas de assets, `Variante` é um nome curto e facilmente reconhecível que representa o agrupamento lógico de assets que são um subconjunto do nome de base de um asset. Por exemplo, se Bob tinha várias skins, essas skins ainda deveriam usar `Bob` assim como `NomeBaseDoAsset` mas inclua um reconhecível `Variante`. Uma skin 'Evil' seria referida como `Bob_Evil` e uma skin 'Retro' seria referida como `Bob_Retro`.
Para variações únicas, mas genéricas de assets, `Variante` é um número de dois dígitos começando em `01`. Por exemplo, se você tem um Ambient Designer gerando rochas indefinidas, eles seriam nomeadas `Rocha_01`, `Rocha_02`, `Rocha_03`, etc. Exceto em raras exceções, você nunca deve exigir um número de variante de três dígitos. Se você tiver mais de 100 assets, deve considerar organizá-los com nomes de base diferentes ou usando vários nomes de variantes.
Dependendo de como suas variantes de assets são feitas, você pode encadear nomes de variantes. Por exemplo, se você estiver criando assets de piso para um projeto Arch Viz, você deve usar o nome de base `Piso` com variantes em cadeia, como `Piso_Marmore_01`, `Piso_Bordo_01`, `Piso_Tile_Quadrados_01`.
#### 1.1 Exemplos
##### 1.1e1 Bob
| Tipo de Asset | Nome do Asset |
| ----------------------- | ---------------------------------------------------------- |
| Skeletal Mesh | SK_Bob |
| Material | M_Bob |
| Texture (Diffuse/Albedo)| T_Bob_D |
| Texture (Normal) | T_Bob_N |
| Texture (Evil Diffuse) | T_Bob_Evil_D |
##### 1.1e2 Rocha
| Tipo de Asset | Nome do Asset |
| ----------------------- | ---------------------------------------------------------- |
| Static Mesh (01) | S_Rocha_01 |
| Static Mesh (02) | S_Rocha_02 |
| Static Mesh (03) | S_Rocha_03 |
| Material | M_Rocha |
| Material Instance (Neve)| MI_Rocha_Neve |
### 1.2 Modificadores de Nome de Asset
Ao nomear um asset, use essas tabelas para determinar o prefixo e sufixo a ser usado com ele [Nome Base do Asset](#base-asset-name).
#### Sections
> 1.2.1 [Mais comum](#anc-common)
> 1.2.2 [Animações](#anc-animations)
> 1.2.3 [Inteligência Artificial](#anc-ai)
> 1.2.4 [Blueprints](#anc-bp)
> 1.2.5 [Materials](#anc-materials)
> 1.2.6 [Textures](#anc-textures)
> 1.2.7 [Miscelâneas](#anc-misc)
> 1.2.8 [Paper 2D](#anc-paper2d)
> 1.2.9 [Física](#anc-physics)
> 1.2.10 [Som](#anc-sounds)
> 1.2.11 [Interface de Usuário](#anc-ui)
> 1.2.12 [Efeitos](#anc-effects)
#### 1.2.1 Mais comum
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Level / Mapas | | | [Deve estar em uma pasta chamada Maps.](#2.4) |
| Level (Persistente) | | _P | |
| Level (Audio) | | _Audio | |
| Level (Iluminação) | | _Lighting | |
| Level (Geometria) | | _Geo | |
| Level (Gameplay) | | _Gameplay | |
| Blueprint | BP_ | | |
| Material | M_ | | |
| Static Mesh | S_ | | Muitos usam SM_. Usamos S_. |
| Skeletal Mesh | SK_ | | |
| Texture | T_ | _? | Veja [Textures](#anc-textures) |
| Particle System | PS_ | | |
| Widget Blueprint | WBP_ | | |
#### 1.2.2 Animações
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Aim Offset | AO_ | | |
| Aim Offset 1D | AO_ | | |
| Animation Blueprint | ABP_ | | |
| Animation Composite | AC_ | | |
| Animation Montage | AM_ | | |
| Animation Sequence | A_ | | |
| Blend Space | BS_ | | |
| Blend Space 1D | BS_ | | |
| Level Sequence | LS_ | | |
| Morph Target | MT_ | | |
| Paper Flipbook | PFB_ | | |
| Rig | Rig_ | | |
| Skeletal Mesh | SK_ | | |
| Skeleton | SKEL_ | | |
### 1.2.3 Inteligência Artificial
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| AI Controller | AIC_ | | |
| Behavior Tree | BT_ | | |
| Blackboard | BB_ | | |
| Decorator | BTDecorator_ | | |
| Service | BTService_ | | |
| Task | BTTask_ | | |
| Environment Query | EQS_ | | |
| EnvQueryContext | EQS_ | Contexto | |
### 1.2.4 Blueprints
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Blueprint | BP_ | | |
| Blueprint Component | BP_ | Component | E.x. BP_InventoryComponent |
| Blueprint Function Library | BPFL_ | | |
| Blueprint Interface | BPI_ | | |
| Blueprint Macro Library | BPML_ | | Não use bibliotecas de macro, se possível. |
| Enumeration | E | | Sem sublinhado. |
| Structure | F or S | | Sem sublinhado. |
| Tutorial Blueprint | TBP_ | | |
| Widget Blueprint | WBP_ | | |
### 1.2.5 Materials
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------------- | ---------- | ---------- | -------------------------------- |
| Material | M_ | | |
| Material (Post Process) | PP_ | | |
| Material Function | MF_ | | |
| Material Instance | MI_ | | |
| Material Parameter Collection | MPC_ | | |
| Subsurface Profile | SP_ | | |
| Physical Materials | PM_ | | |
| Decal | M_, MI_ | _Decal | |
### 1.2.6 Textures
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Texture | T_ | | |
| Texture (Diffuse/Albedo/Base Color)| T_ | _D | |
| Texture (Normal) | T_ | _N | |
| Texture (Roughness) | T_ | _R | |
| Texture (Alpha/Opacity) | T_ | _A | |
| Texture (Ambient Occlusion) | T_ | _O | |
| Texture (Bump) | T_ | _B | |
| Texture (Emissive) | T_ | _E | |
| Texture (Mask) | T_ | _M | |
| Texture (Specular) | T_ | _S | |
| Texture (Metallic) | T_ | _M | |
| Texture (Packed) | T_ | _* | Veja as notas abaixo sobre [pacotes](#anc-textures-packing). |
| Texture Cube | TC_ | | |
| Media Texture | MT_ | | |
| Render Target | RT_ | | |
| Cube Render Target | RTC_ | | |
| Texture Light Profile | TLP | | |
#### 1.2.6.1 Pacote de textura
É uma prática comum compactar várias camadas de dados de textura em uma única textura. Um exemplo disso é agregar "Emissive", "Roughness", "Ambient Occlusion" juntos como os canais Vermelho, Verde e Azul de uma textura, respectivamente. Para determinar o sufixo, basta empilhar as letras de sufixo fornecidas de cima, e.g. `_ERO`.
> É geralmente aceitável incluir uma camada Alfa/Opacidade no canal Alfa de Difusão/Albedo e, como essa é uma prática comum, adicionar `A` ao sufixo` _D` é opcional.
Englobar 4 canais de dados em uma textura (RGBA) não é recomendado, exceto para uma máscara Alfa/Opacidade no canal Alfa de Difusão/Albedo, pois uma textura com um canal alfa incorre em mais sobrecarga do que uma sem.
### 1.2.7 Miscelâneas
| Tipo de Asset | Prefixo | Suffixo | Notas |
| -------------------------- | ---------- | ---------- | -------------------------------- |
| Animated Vector Field | VFA_ | | |
| Camera Anim | CA_ | | |
| Color Curve | Curve_ | _Color | |
| Curve Table | Curve_ | _Table | |
| Data Asset | *_ | | O prefixo deve ser baseado na classe. |
| Data Table | DT_ | | |
| Float Curve | Curve_ | _Float | |
| Foliage Type | FT_ | | |
| Force Feedback Effect | FFE_ | | |
| Landscape Grass Type | LG_ | | |
| Landscape Layer | LL_ | | |
| Matinee Data | Matinee_ | | |
| Media Player | MP_ | | |
| Object Library | OL_ | | |
| Redirector | | | Estes devem ser consertados o mais rápido possível. |
| Sprite Sheet | SS_ | | |
| Static Vector Field | VF_ | | |
| Substance Graph Instance | SGI_ | | |
| Substance Instance Factory | SIF_ | | |
| Touch Interface Setup | TI_ | | |
| Vector Curve | Curve_ | _Vector | |
### 1.2.8 Paper 2D
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Paper Flipbook | PFB_ | | |
| Sprite | SPR_ | | |
| Sprite Atlas Group | SPRG_ | | |
| Tile Map | TM_ | | |
| Tile Set | TS_ | | |
### 1.2.9 Física
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Physical Material | PM_ | | |
| Physics Asset | PHYS_ | | |
| Destructible Mesh | DM_ | | |
### 1.2.10 Som
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Dialogue Voice | DV_ | | |
| Dialogue Wave | DW_ | | |
| Media Sound Wave | MSW_ | | |
| Reverb Effect | Reverb_ | | |
| Sound Attenuation | ATT_ | | |
| Sound Class | | | Sem prefixo/sufixo. Deve ser colocado em uma pasta chamada SoundClasses |
| Sound Concurrency | | _SC | Deve ter o nome de uma SoundClass |
| Sound Cue | A_ | _Cue | |
| Sound Mix | Mix_ | | |
| Sound Wave | A_ | | |
### 1.2.11 Interface de Usuário
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Font | Font_ | | |
| Slate Brush | Brush_ | | |
| Slate Widget Style | Style_ | | |
| Widget Blueprint | WBP_ | | |
### 1.2.12 Efeitos
| Tipo de Asset | Prefixo | Suffixo | Notas |
| ----------------------- | ---------- | ---------- | -------------------------------- |
| Particle System | PS_ | | |
| Material (Post Process) | PP_ | | |
**[⬆ Voltar ao topo](#table-of-contents)**
## 2. Estrutura do Diretório de Conteúdo
Tão importante quanto os nomes de assets, o estilo da estrutura de diretório de um projeto deve ser considerado lei. As convenções de nomenclatura de assets e a estrutura do diretório de conteúdo andam de mãos dadas, e a violação de qualquer uma delas causa um caos desnecessário.
Existem várias maneiras de definir o conteúdo de um projeto UE4. Nesse estilo, usaremos uma estrutura que depende mais dos recursos de filtragem e pesquisa do Navegador de Conteúdo para aqueles que trabalham com assets para encontrar assets de um tipo específico, em vez de outra estrutura comum que agrupa tipos de assets com pastas.
> Se você estiver usando o prefixo [convenção de nomenclatura] (# 1.2) acima, usar pastas para conter assets de tipos semelhantes, como `Meshes`,` Textures` e `Materials` é uma prática redundante, pois os tipos de assets já são classificados por prefixo, bem como podem ser filtrado no Navegador de Conteúdo.
### 2e1 Exemplo de Estrutura de Conteúdo do Projeto
|-- Content
|-- GenericShooter
|-- Art
| |-- Industrial
| | |-- Ambient
| | |-- Machinery
| | |-- Pipes
| |-- Nature
| | |-- Ambient
| | |-- Foliage
| | |-- Rocks
| | |-- Trees
| |-- Office
|-- Characters
| |-- Bob
| |-- Common
| | |-- Animations
| | |-- Audio
| |-- Jack
| |-- Steve
| |-- Zoe
|-- Core
| |-- Characters
| |-- Engine
| |-- GameModes
| |-- Interactables
| |-- Pickups
| |-- Weapons
|-- Effects
| |-- Electrical
| |-- Fire
| |-- Weather
|-- Maps
| |-- Campaign1
| |-- Campaign2
|-- MaterialLibrary
| |-- Debug
| |-- Metal
| |-- Paint
| |-- Utility
| |-- Weathering
|-- Placeables
| |-- Pickups
|-- Weapons
|-- Common
|-- Pistols
| |-- DesertEagle
| |-- RocketPistol
|-- Rifles
Os motivos para essa estrutura estão listados nas subseções a seguir.
### Seções
> 2.1 [Nomes de pasta](#structure-folder-names)
> 2.2 [Pasta de Nível Superior](#structure-top-level)
> 2.3 [Pastas de desenvolvedor](#structure-developers)
> 2.4 [Maps](#structure-maps)
> 2.5 [Core](#structure-core)
> 2.6 [`Assets` e `AssetTypes`](#structure-assettypes)
> 2.7 [Conjuntos Grandes](#structure-large-sets)
> 2.8 [Biblioteca de Materiais](#structure-material-library)
### 2.1 Nomes de pasta
Essas são regras comuns para nomear qualquer pasta na estrutura de conteúdo.
#### 2.1.1 Sempre use PascalCase[*](#terms-cases)
PascalCase refere-se a iniciar um nome com uma letra maiúscula e, em vez de usar espaços, todas as palavras seguintes também começam com uma letra maiúscula. Por exemplo, `DesertEagle`, `RocketPistol`, e `UmaSerieDePalavras`.
Veja [Casos](#terms-cases).
#### 2.1.2 Nunca Use Espaços
Reforçando [2.1.1](#2.1.1), nunca use espaços. Os espaços podem fazer com que várias ferramentas de engenharia e processos em lote falhem. Idealmente, a raiz do seu projeto também não deve contém espaços e está localizada em algum lugar como `D:\Project` em vez de `C:\Users\My Name\My Documents\Unreal Projects`.
#### 2.1.3 Nunca Use Caracteres Unicode e Outros Símbolos
Se um dos personagens do jogo se chama 'Zoë', o nome da pasta deve ser `Zoe`. Caracteres Unicode podem ser piores do que [Espaços](#2.1.2) para a ferramenta de engenharia e algumas partes do UE4 que também não oferecem suporte a caracteres Unicode em caminhos.
Relacionado a isso, se o seu projeto tiver [problemas inexplicáveis](https://answers.unrealengine.com/questions/101207/undefined.html) e o nome de usuário do seu computador tem um caractere Unicode (ou seja, seu nome é `Zoë`), qualquer projeto localizado na pasta `My Documents` sofrerá com esse problema. Freqüentemente, mover seu projeto para outra pasta como `D:\Project` corrigirá esses problemas.
Usando outros caracteres fora `a-z`, `A-Z`, e `0-9` como `@`, `-`, `_`, `,`, `*`, e `#` também pode levar a problemas inesperados e difíceis de rastrear em outras plataformas, source controls e ferramentas de engenharia mais fracas.
### 2.2 Use Uma Pasta de Nível Superior Para Assets Específicos do Projeto
Todos os assets de um projeto devem existir em uma pasta com o nome do projeto. Por exemplo, se o nome do seu projeto for 'Generic Shooter', _todo_ todo o seu conteúdo deve existir em `Content/GenericShooter`.
> A pasta `Developers` não é para assets dos quais seu projeto depende e, portanto, não é específica do projeto. Consulte [Pastas de desenvolvedor] (# 2.3) para obter detalhes sobre isso.
Existem várias razões para esta abordagem.
#### 2.2.1 Sem Assets Globais
Freqüentemente, nos guias de estilo de código está escrito que você não deve poluir o namespace global e isso segue o mesmo princípio. Quando assets podem existir fora de uma pasta de projeto, geralmente se torna muito mais difícil impor um layout de estrutura estrito, pois assets que não estão em uma pasta encorajam o mau comportamento de não ter que organiza-los.
Todo asset deve ter um propósito, caso contrário, ele não pertence a um projeto. Se um asset é um teste experimental e não deve ser usado pelo projeto, deve ser colocado em uma pasta [`Developer`](#2.3).
#### 2.2.2 Reduza Conflitos de Migração
Ao trabalhar em vários projetos, é comum que uma equipe copie assets de um projeto para outro, caso tenham feito algo útil para ambos. Quando isso ocorre, a maneira mais fácil de realizar a cópia é usar a funcionalidade Migrar do navegador de conteúdo, pois ela copiará não apenas o asset selecionado, mas todas as suas dependências.
Essas dependências podem facilmente causar problemas. Se os assets de dois projetos não tiverem uma pasta de nível superior e acontecerem de terem assets nomeados de forma semelhante ou já migrados anteriormente, uma nova migração pode apagar acidentalmente quaisquer alterações nos assets existentes.
Esse também é o principal motivo pelo qual a equipe do Marketplace da Epic aplica a mesma política para assets enviados.
Após uma migração, a fusão segura de assets pode ser feita usando a ferramenta 'Substituir referências' no navegador de conteúdo com a clareza adicional de assets não pertencentes à pasta de nível superior de um projeto e claramente aguardando uma fusão. Depois que os assets são mesclados e totalmente migrados, não deve haver outra pasta de nível superior em sua árvore de conteúdo. Este método é _100% _ garantido para tornar todas as migrações que ocorrerem completamente seguras.
##### 2.2.2e1 Exemplo de Master Material
Por exemplo, digamos que você criou um Master Material em um projeto que gostaria de usar em outro projeto, então migrou esse asset. Se este asset não estiver em uma pasta de nível superior, pode ter um nome como `Content/MaterialLibrary/M_Master`. Se o projeto de destino ainda não tiver um Master Material, isso deve funcionar sem problemas.
Conforme o trabalho em um ou ambos os projetos progride, seus respectivos Master Material podem ser alterados para serem adaptados para seus projetos específicos devido ao curso de desenvolvimento normal.
O problema surge quando, por exemplo, um artista para um projeto criou um bom conjunto modular genérico de static meshes e alguém deseja incluir esse conjunto de static meshes no segundo projeto. Se o artista que criou os recursos usou Material Instances com base em `Content/MaterialLibrary/M_Master` conforme são instruídos, quando uma migração é realizada, há uma grande chance de conflito para o asset migrado anteriormente `Content/MaterialLibrary/M_Master`.
Esse problema pode ser difícil de prever e de explicar. A pessoa que migra as static meshes pode não ser a mesma pessoa que está familiarizada com o desenvolvimento de ambos os Master Material do projeto e pode nem mesmo estar ciente de que as static meshes em questão dependem de Material Instances que, então, dependem do Master Material. A ferramenta Migrar requer que toda a cadeia de dependências funcione, no entanto, será obrigada a pegar `Content/MaterialLibrary/M_Master` quando ela copia esses assets para o outro projeto e sobrescrever o asset existente.
É neste ponto que se os Master Materials para ambos os projetos forem incompatíveis de _qualquer maneira_, você corre o risco de quebrar possivelmente toda a biblioteca de Materials de um projeto, bem como quaisquer outras dependências que já possam ter sido migradas, simplesmente porque os assets não foram armazenados em uma pasta de nível superior. A simples migração de static meshes agora se torna uma tarefa muito ruim.
#### 2.2.3 Amostras, Modelos e Conteúdos do Marketplace Estão Livres de Riscos
Uma extensão para [2.2.2](#2.2.2), se um membro da equipe decidir adicionar conteúdo de amostra, arquivos de modelo ou assets que comprou no Marketplace, é garantido, desde que a pasta de nível superior do seu projeto tenha um nome exclusivo, que esses novos assets não interferirão em seu projeto.
Você não pode confiar que o conteúdo do marketplace está em total conformidade com a [regra de pasta de nível superior] (# 2.2). Existem muitos assets que têm a maior parte de seu conteúdo em uma pasta de nível superior, mas também possuem Conteúdo de Amostra da Epic possivelmente modificados, bem como arquivos de nível poluindo a pasta global `Content`.
Ao aderir a [2.2](#2.2), o pior conflito de marketplace que você pode ter é se dois assets de marketplace tiverem o mesmo Conteúdo de Amostra da Epic. Se todos os seus assets estiverem em uma pasta específica do projeto, incluindo conteúdo de amostra que você pode ter movido para a sua pasta, seu projeto nunca será quebrado.
#### 2.2.4 DLC, Subprojetos e Patches São Facilmente Mantidos
Se o seu projeto planeja lançar DLC ou tem vários subprojetos associados a ele que podem ser migrados ou simplesmente não preparados em uma construção, os assets relacionados a esses projetos devem ter sua própria pasta de conteúdo de nível superior separada. Isso torna muito mais fácil cozinhar DLC separados do conteúdo do projeto principal. Os subprojetos também podem ser migrados para dentro e para fora com o mínimo de esforço. Se você precisar alterar um material de um assets ou adicionar algum comportamento de substituição de asset muito específico em um patch, você pode facilmente colocar essas alterações em uma pasta de patch e trabalhar com segurança sem a chance de quebrar o projeto principal.
### 2.3 Use a Pasta Developers Para Testes Locais
Durante o desenvolvimento de um projeto, é muito comum que os membros da equipe tenham uma espécie de 'sandbox' onde podem experimentar livremente sem arriscar o projeto principal. Como esse trabalho pode estar em andamento, esses membros da equipe podem querer colocar seus assets em um servidor de source control do projeto. Nem todas as equipes exigem o uso de pastas Developers, mas aquelas que as usam costumam ter um problema comum com assets enviados ao source control.
É muito fácil para um membro da equipe usar acidentalmente assets que não estão prontos para uso, o que causará problemas quando esses assets forem removidos. Por exemplo, um artista pode estar iterando em um conjunto modular de static meshes e ainda trabalhando para obter o tamanho e o encaixe da grade corretos. Se um world designer ver esses assets na pasta principal do projeto, ele pode usá-los em um nível sem saber que podem estar sujeitos a mudanças e/ou remoções. Isso causa uma grande quantidade de retrabalho para todos na equipe resolverem.
Se esses assets modulares fossem colocados em uma pasta de desenvolvedor, o world designer nunca deveria ter tido um motivo para usá-los e todo o problema nunca aconteceria. O navegador de conteúdo tem opções de exibição específicas que ocultam as pastas do desenvolvedor (elas ficam ocultas por padrão), tornando impossível o uso acidental de assets do desenvolvedor em uso normal.
Assim que os recursos estiverem prontos para uso, o artista simplesmente precisa mover os recursos para a pasta específica do projeto e corrigir os redirecionadores. Isso é essencialmente 'promover' os assets do experimental para a produção.
### 2.4 Todo Arquivo de Mapa[*](#terms-level-map) Pertence a Uma Pasta Chamada Maps
Os arquivos de mapa são incrivelmente especiais e é comum que cada projeto tenha seu próprio sistema de nomenclatura de mapa, especialmente se eles trabalharem com subníveis ou níveis de streaming. Não importa qual sistema de organização de mapas está em vigor para o projeto específico, todos os níveis devem pertencer a `/Content/Project/Maps`.
Ser capaz de dizer a alguém para abrir um mapa específico sem ter que explicar onde ele está economiza muito tempo e melhora a 'qualidade de vida' em geral. É comum que os níveis estejam dentro de subpastas de `Maps`, tal como `Maps/Campaign1/` ou `Maps/Arenas`, mas o mais importante aqui é que todos eles existem dentro `/Content/Project/Maps`.
Isso também simplifica o trabalho de cozinhar para os engenheiros. Combinar os níveis de um processo de compilação pode ser extremamente frustrante se eles tiverem que vasculhar pastas arbitrárias. Se os mapas de uma equipe estão todos em um só lugar, é muito mais difícil acidentalmente não preparar um mapa em uma construção. Ele também simplifica os scripts de construção de iluminação, bem como os processos de controle de qualidade.
### 2.5 Use uma Pasta `Core` Para Blueprints Críticos e Outros Assets
Use a pasta`/Content/Project/Core` para assets que são absolutamente fundamentais para o funcionamento de um projeto. Por exemplo, `GameMode`, `Character`, `PlayerController`, `GameState`, `PlayerState`, base e os Blueprints relacionados devem residir aqui.
Isso cria uma mensagem muito clara "não toque nestes" para os outros membros da equipe. Os que não são engenheiros devem ter muito poucos motivos para entrar na pasta `Core`. Seguindo um bom estilo de estrutura de código, os designers devem fazer seus ajustes de jogabilidade em classes filhas que expõem a funcionalidade. Os world designers devem usar Blueprints pré-fabricados em pastas designadas em vez de abusar potencialmente das classes base.
Por exemplo, se o seu projeto requer "pickups" que podem ser colocados em um nível, deve existir uma classe de "pickup" base em `Core/Pickups` que define o comportamento básico para uma "pickup". Coletas específicas, como Health ou Ammo, devem existir em uma pasta como `/Content/Project/Placeables/Pickups/`. Os designers de jogos podem definir e ajustar opções nesta pasta da maneira que quiserem, mas não devem tocar `Core/Pickups` pois eles podem interromper involuntariamente "pickups" em todo o projeto.
### 2.6 Não Crie Pastas Chamadas `Assets` ou `AssetTypes`
#### 2.6.1 Criar uma pasta chamada `Assets` é redundante.
Todos assets são assets.
#### 2.6.2 Criar uma pasta chamada `Meshes`, `Textures`, ou `Materials` é redundante.
Todos os nomes de assets são nomeados com seu tipo de asset em mente. Essas pastas oferecem apenas informações redundantes e o uso dessas pastas pode ser facilmente substituído pelo sistema de filtragem robusto e fácil de usar que o Navegador de Conteúdo oferece.
Quer apenas ver static mesh em `Environment/Rocks/`? Basta ativar o filtro Static Mesh. Se todos os assets forem nomeados corretamente, eles também serão classificados em ordem alfabética, independentemente dos prefixos. Quer visualizar static meshes e skeletal meshes? Basta ligar os dois filtros. Isso elimina a necessidade de selecionar duas pastas com `Control-Click` na visualização em árvore do navegador de conteúdo.
> Isso também estende o nome do caminho completo de um asset para muito poucos benefícios. O prefixo `S_` para uma static mesh tem apenas dois caracteres, enquanto `Meshes/`tem sete caracteres.
Não fazer isso também previne de alguém colocar uma static mesh ou uma textura em uma pasta `Materials`.
### 2.7 Conjunto de Assets Muito Grandes Tem Seu Próprio Layout de Pasta
Isso pode ser visto como uma pseudo-exceção para [2.6](#2.6).
Existem certos tipos de assets que possuem um grande volume de arquivos relacionados, onde cada asset tem uma finalidade única. Os dois mais comuns são assets de animação e áudio. Se você tiver mais de 15 desses assets que pertencem um ao outro, eles devem estar juntos.
Por exemplo, as animações que são compartilhadas por vários personagens devem estar em `Characters/Common/Animations` e pode ter subpastas como `Locomotion` ou `Cinematic`.
> Isso não se aplica a assets como texturas e materiais. É comum que uma pasta `Rochas` tenha uma grande quantidade de texturas se houver uma grande quantidade de pedras, no entanto, essas texturas geralmente estão relacionadas apenas a algumas pedras específicas e devem ser nomeadas apropriadamente. Mesmo que essas texturas sejam parte de uma [Biblioteca de Materials](#2.8).
### 2.8 `Biblioteca de Materials`
Se o seu projeto faz uso de master materials, layered materials, ou qualquer forma de materiais reutilizáveis ou texturas que não pertençam a nenhum subconjunto de assets, esses assets devem estar localizados em `Content/Project/MaterialLibrary`.
Desta forma materials 'global' têm um lugar e são facilmente localizados.
> Isso também torna incrivelmente fácil aplicar uma política de 'use material instances only' dentro de um projeto. Se todos os artistas e assets deveriam estar usando instâncias de material, então os únicos assets materials regulares que deveriam existir estão dentro desta pasta. Você pode verificar isso facilmente procurando por base materials em qualquer pasta que não seja o `MaterialLibrary`.
A `MaterialLibrary` não precisa consistir puramente em materials. Texturas de utilitários compartilhados, funções materiais e outras coisas dessa natureza devem ser armazenadas aqui também em pastas que indicam sua finalidade. Por exemplo, texturas de ruído genéricas devem estar localizadas em `MaterialLibrary/Utility`.
Qualquer material de teste ou depuração deve estar dentro de `MaterialLibrary/Debug`. Isso permite que os materiais de depuração sejam facilmente retirados de um projeto antes do envio e torna incrivelmente aparente se os assets de produção os estão usando se forem mostrados erros de referência.
### 2.9 Sem Pastas Vazias
Simplesmente não deve haver pastas vazias. Eles confundem o navegador de conteúdo.
Se você descobrir que o navegador de conteúdo tem uma pasta vazia que não pode ser excluída, faça o seguinte:
1. Certifique-se de usar o controle de origem.
1. Execute imediatamente Fix Up Redirectors em seu projeto.
1. Navegue até a pasta no disco e exclua os assets dentro dela.
1. Feche o editor.
1. Certifique-se de que seu estado de source control está sincronizado (ou seja, se estiver usando Perforce, execute um Reconcile Offline Work em seu diretório de conteúdo)
1. Abra o editor. Confirme se tudo ainda está funcionando conforme o esperado. Caso contrário, reverta, descubra o que deu errado e tente novamente.
1. Certifique-se de que a pasta já foi removida.
1. Envie as alterações para o source control.
**[⬆ Voltar ao topo](#table-of-contents)**
## 3. Blueprints
Esta seção se concentrará nas classes do Blueprint e em seus aspectos internos. Quando possível, as regras de estilo estão em conformidade com [Epic's Coding Standard](https://docs.unrealengine.com/latest/INT/Programming/Development/CodingStandard).
Lembre-se: Blueprinting comporta mal os erros, cuidado! (Frase por [KorkuVeren](http://github.com/KorkuVeren))
### Sections
> 3.1 [Compilando](#bp-compiling)
> 3.2 [Variáveis](#bp-vars)
> 3.3 [Funções](#bp-functions)
> 3.4 [Gráficos](#bp-graphs)
### 3.1 Compilando
Todos os blueprints devem ser compilados com nenhum aviso e nenhum erro. Você deve corrigir os avisos e erros do blueprint imediatamente, pois eles podem rapidamente se transformar em um comportamento inesperado muito assustador.
*Não* envie projetos corrompidos ao source control. Se você deve armazená-los no source control, arquive-os.
Projetos corrompidos podem causar problemas que se manifestam de outras maneiras, como referências quebradas, comportamento inesperado, falhas de cozimento e recompilação desnecessária frequente. Um projeto quebrado tem o poder de quebrar todo o seu jogo.
### 3.2 Variáveis
As palavras `variable` e `property` podem ser usadas alternadamente.
#### Seções
> 3.2.1 [Nomeação](#bp-vars)
> 3.2.2 [Editável](#bp-vars-editable)
> 3.2.3 [Categorias](#bp-vars-categories)
> 3.2.4 [Acesso](#bp-vars-access)
> 3.2.5 [Avançado](#bp-vars-advanced)
> 3.2.6 [Transiente](#bp-vars-transient)
> 3.2.7 [Config](#bp-vars-config)
#### 3.2.1 Nomenclatura
##### 3.2.1.1 Substantivos
Todos os nomes de variáveis que não são booleans devem ser substantivos claros, não ambíguos e descritivos.
##### 3.2.1.2 PascalCase
Todas as variáveis não booleanas devem estar na forma de [PascalCase](#terms-cases).
###### 3.2.1.2e Exemplos:
* `Score`
* `Kills`
* `TargetPlayer`
* `Range`
* `CrosshairColor`
* `AbilityID`
##### 3.2.1.3 Prefix `b` Para Boolean
Todos os booleans devem ser nomeados em PascalCase, mas prefixados com uma minúscula `b`.
Exemplo: Use `bDead` e `bEvil`, **não use** `Dead` ou `Evil`.
Editores Blueprint UE4 sabem não colocar o `b` em exibições user-friendly da variável.
##### 3.2.1.4 Nomes de Booleans
###### 3.2.1.4.1 Informações Gerais e Condições Independentes
Todos os booleans devem ser nomeados como adjetivos descritivos, quando possível, se representarem informações gerais. Não inclua palavras que expressem a variável como uma pergunta, como `Is`. Isso é reservado para funções.
Exemplo: Use `bDead` e `bHostile` **não use** `bIsDead` ou `bIsHostile`.
Tente não usar verbos como `bRunning`. Os verbos tendem a levar a estados complexos.
###### 3.2.1.4.2 Condições Complexas
Não use booleans para representar condições complexas e/ou dependentes. Isso torna a adição e remoção das condições complexas mais difíceis de ler. Em vez disso, use uma enumeração.
Exemplo: Ao definir uma arma, **não** use `bReloading` e `bEquipping` se uma arma não pode recarregar e ser equipada. Defina uma enumeração chamada `EWeaponState` e usar uma variável com este tipo chamada `WeaponState` em vez disso. Isso torna muito mais fácil adicionar novos estados às armas.
Exemplo: **Não** use `bRunning` se você também precisa de `bWalking` ou `bSprinting`. Isso deve ser definido como uma enumeração com nomes de estado claramente definidos.
##### 3.2.1.5 Contexto Deve Ser Considerado
Todos os nomes de variáveis não devem ser redundantes com seu contexto, pois todas as referências de variáveis no Blueprint sempre terão contexto.
###### 3.2.1.5e Exemplos:
Considere um Blueprint chamado `BP_PlayerCharacter`.
**Ruim**
* `PlayerScore`
* `PlayerKills`
* `MyTargetPlayer`
* `MyCharacterName`
* `CharacterSkills`
* `ChosenCharacterSkin`
Todas essas variáveis são nomeadas de forma redundante. Está implícito que a variável pertence ao `BP_PlayerCharacter` porque é o `BP_PlayerCharacter` que está definindo essas variáveis.
**Bom**
* `Score`
* `Kills`
* `TargetPlayer`
* `Name`
* `Skills`
* `Skin`
##### 3.2.1.6 _Não_ Inclua Nomes de Tipo Atômico
Variáveis atômicas ou primitivas são variáveis que representam dados em sua forma mais simples, como booleans, integers, floats e enumerações.
Strings e vectors são considerados atômicos em termos de estilo ao trabalhar com Blueprints, no entanto, eles não são tecnicamente atômicos.
> Enquanto vectors consiste de três floats, vectors muitas vezes podem ser manipulados como um todo, assim como rotators.
> _Não_ considere Text Variables como atômicas, elas estão escondendo a funcionalidade de localização. O tipo atômico de uma string de caracteres é `String`, não `Text`.
Variáveis atômicas não devem ter seu nome de tipo em seu nome.
Exemplo: Use `Score`, `Kills`, e `Description` **não use** `ScoreFloat`, `FloatKills`, `DescriptionString`.
A única exceção a esta regra é quando uma variável representa 'um número de' algo a ser contado _e_ quando usar um nome difícil de ler sem um tipo de variável.
Exemplo: Um gerador de cerca precisa gerar um número X de postes. Armazene X em `NumPosts` ou `PostsCount` em vez de `Posts` como `Posts` pode potencialmente ser lido como um Array de um tipo de variável chamado `Post`.
##### 3.2.1.7 Inclua Nomes de Tipo Não Atômico
Variáveis não atômicas ou complexas são variáveis que representam dados como uma coleção de variáveis atômicas. Structs, Classes, Interfaces, e primitivas with com comportamento oculto, como `Text` e `Name` todos se qualificam sob esta regra.
> Enquanto um Array de um tipo de variável atômica é uma lista de variáveis, Arrays não altera a 'atomicidade' de um tipo de variável.
Essas variáveis devem incluir seu nome de tipo, ainda considerando seu contexto.
Se uma classe possui uma instância de uma variável complexa, e.x. se um `BP_PlayerCharacter` possui um `BP_Hat`, deve ser armazenado como o tipo de variável, sem nenhuma modificação de nome.
Exemplo: Use `Hat`, `Flag`, e `Ability` **não use** `MyHat`, `MyFlag`, e `PlayerAbility`.
Se uma classe não possui o valor que uma variável complexa representa, você deve usar um substantivo junto com o tipo de variável.
Exemplo: Se um `BP_Turret` tem a capacidade de mirar um `BP_PlayerCharacter`, deve armazenar seu alvo como `TargetPlayer` como quando no contexto de `BP_Turret` deve ficar claro que é uma referência a outro tipo de variável complexa que não possui.
##### 3.2.1.8 Arrays
Arrays segue as mesmas regras de nomenclatura acima, mas deve ser nomeado como um substantivo no plural.
Exemplo: Use `Targets`, `Hats`, e `EnemyPlayers`, **não use** `TargetList`, `HatArray`, `EnemyPlayerArray`.
#### 3.2.2 Variáveis Editáveis
Todas as variáveis que são seguras para alterar o valor de para configurar o comportamento de um blueprint devem ser marcadas como `Editable`.
Por outro lado, todas as variáveis que não são seguras para alteração ou não devem ser expostas aos designers _não_ devem ser marcadas como editáveis, a menos que por razões de engenharia a variável deva ser marcada como `Expose On Spawn`.
Não marque variáveis arbitrariamente como `Editable`.
##### 3.2.2.1 Tooltips
Todas variáveis `Editable`, incluindo aqueles marcados como editáveis, apenas para que possam ser marcados como `Expose On Spawn`, deve ter uma descrição em seus campos de `Tooltip` que explique como a alteração desse valor afeta o comportamento do blueprint.
##### 3.2.2.2 Sliders e Intervalos de Valor
Todas variáveis `Editable` deve fazer uso de um slider e um intervalo de valor se houver um valor para o qual uma variável _não_ deve ser definida.
Exemplo: Um blueprint que gera postes de cerca pode ter uma variável editável chamada `PostsCount` e um valor de -1 não faria nenhum sentido. Use os campos de intervalo para marcar 0 como o mínimo.
Se uma variável editável é usada em um Construction Script, deve ter um "Slider Range" razoável definido para que alguém não possa acidentalmente atribuir a ele um grande valor que poderia travar o editor.
Um "Value Range" só precisa ser definido se os limites de um valor forem conhecidos. Enquanto um "Slider Range" evita entradas acidentais de um grande número, um indefinido "Value Range" permite que um usuário especifique um valor fora do "Slider Range" que pode ser considerado 'perigoso', mas ainda válido.
#### 3.2.3 Categorias
Se uma classe tem apenas um pequeno número de variáveis, as categorias não são obrigatórias.
Se uma class tem uma quantidade moderada de variáveis (5-10), todas variáveis `Editable` deve ter uma categoria não padrão atribuída. Uma categoria comum é `Config`.
Se uma class tem uma grande quantidade de variáveis, todas variáveis `Editable` deve ser categorizado em subcategorias usando a categoria `Config` como a categoria base. Variáveis não editáveis devem ser categorizadas em categorias descritivas que descrevem seu uso.
> Você pode definir subcategorias usando a barra vertical `|`, e.x. `Config | Animations`.
Exemplo: Um conjunto de variáveis de classe de arma pode ser organizado como:
|-- Config
| |-- Animations
| |-- Effects
| |-- Audio
| |-- Recoil
| |-- Timings
|-- Animations
|-- State
|-- Visuals
#### 3.2.4 Nível de acesso variável
Em C ++, as variáveis têm um conceito de nível de acesso. Público significa que qualquer código fora da classe pode acessar a variável. Protegido significa que apenas a classe e quaisquer classes filhas podem acessar essa variável internamente. Privado significa que apenas esta classe e nenhuma classe filha pode acessar esta variável.
Blueprints atualmente não tem um conceito definido de acesso protegido.
Trate a variável `Editable` como variáveis públicas. Trate as variáveis não editáveis como variáveis protegidas.
##### 3.2.4.1 Variáveis Privadas
A menos que se saiba que uma variável só deve ser acessada dentro da classe em que está definida e nunca em uma classe filha, não marque as variáveis como privadas. Até que as variáveis possam ser marcadas `protected`, reserve particular para quando você tiver certeza absoluta de que deseja restringir o uso de classes filhas.
#### 3.2.5 Display Avançado
Se uma variável deve ser editável, mas muitas vezes intocada, marque-a como `Advanced Display`. Isso torna a variável oculta, a menos que a seta de exibição avançada seja clicada.
Para encontrar a opção `Advanced Display`, ela é listada como uma variável avançada exibida na lista de detalhes da variável.
#### 3.2.6 Variáveis Transientes
Variáveis transientes são variáveis que não precisam ter seu valor salvo e carregado, e possuem um valor inicial igual a zero ou nulo. Isso é útil para referências a outros objetos e atores cujo valor não é conhecido até o tempo de execução. Isso evita que o editor salve uma referência a ele e acelera o salvamento e o carregamento da classe de blueprint.
Por causa disso, todas as variáveis transientes sempre devem ser inicializadas como zero ou nulas. Fazer o contrário resultaria em erros difíceis de depurar.
#### 3.2.8 Variáveis de configuração
Não use a flag `Config Variable`. Isso torna mais difícil para os designers controlar o comportamento do blueprint. Variáveis de configuração só devem ser usadas em C ++ para variáveis raramente alteradas. Pense neles como variáveis `Advanced Advanced Display`.
### 3.3 Functions, Events, e Event Dispatchers
Esta seção descreve como você deve criar functions, events, e event dispatchers. Tudo o que se aplica a funções também se aplica a events, salvo indicação contrária.
#### 3.3.1 Nomenclatura de função
A nomenclatura de functions, events, e event dispatchers são extremamente importante. Com base apenas no nome, certas suposições podem ser feitas sobre as funções. Por exemplo:
* É uma função "pure"?
* Está buscando informações de estado?
* É um handler?
* É um RPC?
* Qual é seu propósito?
Essas perguntas e muito mais podem ser respondidas quando as funções são nomeadas apropriadamente.
#### 3.3.1.1 Todas as Funções Devem Ser Verbos
Todas as funções e events realizam alguma forma de ação, seja para obter informações, calcular dados ou fazer algo explodir. Portanto, todas as funções devem começar com verbos. Eles devem ser redigidos no tempo presente sempre que possível. Eles também devem ter algum contexto sobre o que estão fazendo.
Funções `OnRep`, event handlers, e event dispatchers são uma exceção a esta regra.
Bons exemplos:
* `Fire` - Bom exemplo se estiver em uma classe de Personagem/Arma, pois tem contexto. Ruim se estiver em um Barril / Gramado / qualquer classe ambígua.
* `Jump` - Bom exemplo se em uma classe de Personagem, caso contrário, precisa de contexto.
* `Explode`
* `ReceiveMessage`
* `SortPlayerArray`
* `GetArmOffset`
* `GetCoordinates`
* `UpdateTransforms`
* `EnableBigHeadMode`
* `IsEnemy` - ["Is" é um verbo.](http://writingexplained.org/is-is-a-verb)
Maus exemplos:
* `Dead` - Está morto? Vai morrer?
* `Rock`
* `ProcessData` - Ambíguas, essas palavras não significam nada.
* `PlayerState` - Os substantivos são ambíguos.
* `Color` - Verbo sem contexto ou substantivo ambíguo.
#### 3.3.1.2 Funções Com Propriedade "RepNotify" Sempre `OnRep_Variable`
Todas as funções replicadas com variáveis de notificação devem ter o formato `OnRep_Variable`. Isso é forçado pelo editor Blueprint. Se você está escrevendo um C ++ `OnRep` no entanto, ele também deve seguir esta convenção ao expô-lo para Blueprints.
#### 3.3.1.3 Funções de Informação Que Retornam Bool Devem Fazer Perguntas
Ao escrever uma função que não altera o estado ou modifica qualquer objeto e é puramente para: obter informações, estado ou calcular um valor sim/não. Ela deve fazer uma pergunta. Isso também deve seguir [a regra do verbo](#bp-funcs-naming-verbs).
Isso é extremamente importante, pois se uma pergunta não for feita, pode-se presumir que a função executa uma ação e está retornando se essa ação foi bem-sucedida.
Bons exemplos:
* `IsDead`
* `IsOnFire`
* `IsAlive`
* `IsSpeaking`
* `IsHavingAnExistentialCrisis`
* `IsVisible`
* `HasWeapon` - ["Has" é um verbo.](http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html)
* `WasCharging` - ["Was" é pretérito de "be".](http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html) Use "was" quando se refere a 'quadro anterior' ou 'estado anterior'.
* `CanReload` - ["Can" é um verbo.](http://grammar.yourdictionary.com/parts-of-speech/verbs/Helping-Verbs.html)
Maus exemplos:
* `Fire` - Está em chamas? Vai atirar? Atire?
* `OnFire` - Pode ser confundido com o event dispatcher para disparo.
* `Dead` - Está morto? Vai morrer?
* `Visibility` - É visível? Definir visibilidade? Uma descrição das condições de vôo?
#### 3.3.1.4 Event Handlers e Dispatchers Deve Começar Com `On`
Qualquer função que lida com um event ou despacha um event deve começar com `On` e continue a seguir [a regra do verbo](#bp-funcs-naming-verbs). O verbo pode mover-se para o final, no entanto, se o tempo passado for melhor lido.
[Colocações](http://dictionary.cambridge.org/us/grammar/british-grammar/about-words-clauses-and-sentences/collocation) da palavra `On` estão isentos de seguir a regra do verbo.
`Handle` não é permitido. É 'irreal' usar `On` ao invés de `Handle`, enquanto outras estruturas podem preferir usar `Handle` ao invés de `On`.
Bons exemplos:
* `OnDeath` - Colocação comum em jogos
* `OnPickup`
* `OnReceiveMessage`
* `OnMessageRecieved`
* `OnTargetChanged`
* `OnClick`
* `OnLeave`
Maus exemplos:
* `OnData`
* `OnTarget`
* `HandleMessage`
* `HandleDeath`
#### 3.3.1.5 Chamadas de Procedimento Remoto (RPC) Devem Ser Prefixadas com Destino
Sempre que um RPC é criado, deve ser prefixado com um `Server`, `Client`, ou `Multicast`. Sem exceções.
Após o prefixo, siga todas as outras regras relacionadas à nomenclatura de funções.
Bons exemplos:
* `ServerFireWeapon`
* `ClientNotifyDeath`
* `MulticastSpawnTracerEffect`
Maus exemplos:
* `FireWeapon` - Não indica que seja algum tipo de RPC.
* `ServerClientBroadcast` - Confuso.
* `AllNotifyDeath` - Use `Multicast`, nunca `All`.
* `ClientWeapon` - Sem verb, ambíguo.
#### 3.3.2 Todas as Funções Devem Ter "Return Nodes"
Todas as funções devem ter return nodes, sem exceções.
Return nodes significam que uma função concluiu sua execução. Como os projetos podem ser preenchidos com `Sequence`, `ForLoopWithBreak`, e reroute nodes reversos, fluxo de execução explícito é importante para leitura, manutenção e depuração mais fáceis dos mesmos.
O compilador Blueprint é capaz de seguir o fluxo de execução e irá avisá-lo se houver um branch de seu código com um retorno não tratado ou fluxo incorreto se você usar return nodes.
Em situações como quando um programador pode adicionar um alfinete a um Sequence node ou adicionar lógica após a conclusão de um "loop for", mas a iteração do loop pode retornar mais cedo, o que geralmente pode resultar em um erro acidental no fluxo de código. Os avisos do compilador Blueprint alertarão a todos sobre esses problemas imediatamente.
#### 3.3.3 Nenhuma Função Deve Ter Mais de 50 Nós
Simplesmente, nenhuma função deve ter mais de 50 nós. Qualquer função desse tamanho deve ser dividida em funções menores para facilitar a leitura e manutenção.
Os seguintes nós não são contados, pois são considerados como não aumentando a complexidade da função:
* Comentários
* Route
* Cast
* Obtendo uma Variable
* Quebrando um Struct
* Funções Entry
* Self
#### 3.3.4 Todas As Funções Públicas Devem Ter Uma Descrição
Esta regra se aplica mais a blueprints públicas ou do marketplace, para que outras pessoas possam navegar e consumir sua API de blueprint com mais facilidade.
Simplesmente, qualquer função que tenha um especificador de acesso de Public deve ter sua descrição preenchida.
#### 3.3.5 Todas Funções de Plugin 'Static' e `BlueprintCallable` Personalizadas Deve Ser Categorizado Pelo Nome do Plugin
Se o seu projeto inclui um plugin que define funções `static` `BlueprintCallable`, ele devem ter sua categoria definida para o nome do plugin ou uma categoria de subconjunto do nome do plugin.
Por exemplo, `Zed Camera Interface` ou `Zed Camera Interface | Image Capturing`.
### 3.4 Gráficos Blueprint
Esta seção cobre coisas que se aplicam a todos os gráficos do Blueprint.
#### 3.4.1 Sem "Espaguete"
Os fios devem ter começo e fim claros. Você nunca deve ter que desembaraçar mentalmente os fios para dar sentido a um gráfico. Muitas das seções a seguir são dedicadas à redução do "espaguete".
#### 3.4.2 Alinhe Fios, Não Nodes
Sempre alinhe os fios, não os nodes. Você nem sempre pode controlar o tamanho e a localização do pino em um node, mas você sempre pode controlar a localização de um node e, assim, controlar os fios. Fios retos fornecem fluxo linear claro. Fios ondulados desgastam muito a mente. Você pode endireitar os fios usando o comando "Straighten Connections" com os nodes BP selecionados. Atalho: Q
Bom exemplo: os topos dos nodes são escalonados para manter uma linha executiva branca perfeitamente reta.

Mau exemplo: Os topos dos nodes são alinhados, criando uma linha executiva branca ondulada.

Exemplo aceitável: Certos nodes podem não cooperar, não importa como você usa as ferramentas de alinhamento. Nessa situação, tente minimizar a oscilação trazendo o node para mais perto.

#### 3.4.3 Linhas de Execução Branca São De Alta Prioridade
Se você alguma vez tiver que decidir entre endireitar uma linha executiva branca linear ou endireitar linhas de dados de algum tipo, sempre endireite a linha executiva branca.
#### 3.4.4 Os Gráficos Devem Ser Comentadas Razoavelmente
Os blocos de nodes devem ser incluídos em comentários que descrevam seu comportamento de nível superior. Embora cada função deva ser bem nomeada para que cada node individual seja facilmente legível e compreensível, grupos de nodes que contribuem para um propósito devem ter seu propósito descrito em um bloco de comentário. Se uma função não tiver muitos blocos de nodes e ficar claro que os nodes estão servindo a um propósito direto no objetivo da função, eles não precisam ser comentados, pois o nome e a descrição da função devem ser suficientes.
#### 3.4.5 Os Gráficos Devem Lidar Com Error de Casting Onde Apropriado
Se uma função ou evento presumir que uma conversão sempre é bem-sucedida, ele deve relatar apropriadamente uma falha na lógica se o casting falhar. Isso permite que outras pessoas saibam por que algo que "deveria funcionar" não funciona. Uma função também deve tentar uma recuperação normal após um cast com falha se for conhecido que a referência que está sendo lançada pode falhar durante o cast.
Isso não significa que cada node de cast deve ter sua falha tratada. Em muitos casos, especialmente eventos relacionados a coisas como colisões, espera-se que o fluxo de execução termine silenciosamente em um cast com falha.
#### 3.4.6 Os Gráficos Não Devem Ter Nodes Pendentes / Soltos / Mortos
Todos os nodes em todos os gráficos do blueprint devem ter um propósito. Você não deve deixar nodes de blueprint pendurados por aí que não têm propósito ou não são executados.
**[⬆ Voltar ao topo](#table-of-contents)**
## 4. Static Meshes
Esta seção se concentrará em assets Static Mesh e seus internos.
### Seções
> 4.1 [UVs](#s-uvs)
> 4.2 [LODs](#s-lods)
> 4.3 [Encaixe Modular Sem Socket](#s-modular-snapping)
> 4.4 [Deve Ter Colisão](#s-collision)
> 4.5 [Escala Correta](#s-scaled)
### 4.1 UVs Static Mesh
Se o Linter está reportando maus UVs e você não consegue rastreá-los, abra o arquivo resultante `.log` no seu projeto `Saved/Logs` para obter detalhes exatos sobre o motivo da falha. Espero que incluam essas mensagens no relatório Lint no futuro.
#### 4.1.1 Todos Meshes Devem Ter UVs
Bem simples. Todos os meshes, independentemente de como devem ser usadas, não devem ter UVs faltando.
#### 4.1.2 Todos Meshes Não deve ter sobreposição UVs de Lightmaps
Bem simples. Todas os meshes, independentemente de como devem ser usadas, devem ter UVs válidos sem sobreposição.
### 4.2 LODs Devem Ser Configurados Corretamente
Esta é uma verificação subjetiva por projeto, mas como regra geral, qualquer meshe que pode ser vista em distâncias variáveis deve ter LODs adequados.
### 4.3 Assests Modulares Sem Soquete Devem Se Encaixar na Grade de Forma Limpa
Esta é uma verificação subjetiva por asset, no entanto, quaisquer assets modulares sem soquete devem se encaixar perfeitamente com base nas configurações de grade do projeto.
Fica a critério do projeto se encaixar com base em uma grade de 2 ou em uma grade de base 10. No entanto, se você estiver criando assets modulares sem soquete para o marketplace, o requisito da Epic é que eles se encaixem perfeitamente quando a grade for configurada para 10 unidades ou mais.
### 4.4 Todos Meshes Devem Ter Colisão
Independentemente de um assets ser usado para colisão em um level, todos os meshes devem ter a colisão adequada definida. Isso ajuda o mecanismo com coisas como cálculos de limites, oclusão e iluminação. A colisão também deve ser bem formada para o asset.
### 4.5 Todos Meshes Deve Ser Dimensionado Corretamente
Esta é uma verificação subjetiva por projeto; no entanto, todos os assets devem ser dimensionados corretamente para o projeto. Os level designers ou autores de blueprint não devem ter que ajustar a escala dos meshes para que sejam confirmadas no editor. Redimencionar meshes na engine deve se tratadas como uma substituição de escala, não uma correção de escala.
**[⬆ Voltar ao topo](#table-of-contents)**
## 5. Niagara
Esta seção se concentrará em assets Niagara e seus internos.
### Seções
> 5.1 [Regras de Nomenclatura](#ng-rules)
### 5.1 Sem Espaços, Nunca
Conforme mencionado em [00.1 Identificadores Proibidos](#00), espaços e todos os caracteres de espaço em branco são proibidos em identificadores. Isso é especialmente verdadeiro para os sistemas Niagara, pois torna o trabalho com as coisas significativamente mais difícil, senão impossível, ao trabalhar com HLSL ou outros meios de script dentro do Niagara e ao tentar fazer referência a um identificador.
(Contribuição original por [@dunenkoff](https://github.com/Allar/ue5-style-guide/issues/58))
**[⬆ Voltar ao topo](#table-of-contents)**
## 6. Levels / Maps
[Veja a Nota de Terminologia](#terms-level-map) sobre "levels" vs "maps".
Esta seção se concentrará em assets de Level e seus internos.
### Seções
> 6.1 [Sem Erros ou Avisos](#levels-no-errors-or-warnings)
> 6.2 [A Iluminação Deve Ser Construída](#levels-lighting-should-be-built)
> 6.3 [Nenhum "Z Fighting" Visível ao Jogador](#evels-no-visible-z-fighting)
> 6.4 [Regras Específicas de Marketplace](#evels-levels-mp-rules)
### 6.1 Sem Erros ou Avisos
Todos os levels devem carregar sem erros ou avisos. Se um level for carregado com erros ou avisos, eles devem ser corrigidos imediatamente para evitar problemas em cascata.
Você pode executar uma verificação de mapa em um level aberto no editor usando o comando de console "map check".
Observação: o Linter é ainda mais rígido nisso do que o editor atualmente, e detectará erros de carregamento que o editor resolverá sozinho.
### 6.2 A Iluminação Deve Ser Construída
É normal que, durante o desenvolvimento, os levels ocasionalmente não tenham iluminação. Ao fazer um teste/building interna/de envio ou qualquer building a ser distribuída, no entanto, a iluminação deve sempre ser construída.
### 6.3 No Player Visible Z Fighting
Nenhum level deve ter [z-fighting](https://en.wikipedia.org/wiki/Z-fighting) em todas as áreas visíveis ao jogador.
### 6.4 Regras Específicas de Marketplace
Se um projeto for vendido no Marketplace UE4, deve seguir essas regras.
### 6.4.1 Level de Overview
Se o seu projeto contém assets que devem ser visualizados ou demonstrados, você deve ter um mapa dentro do seu projeto que contém o nome "Overview".
Esse mapa overview, se estiver visualizando assets, deve ser configurado de acordo com [As Diretrizes da Epic](http://help.epicgames.com/customer/en/portal/articles/2592186-marketplace-submission-guidelines-preparing-your-assets#Required%20Levels%20and%20Maps).
Por exemplo, `InteractionComponent_Overview`.
### 6.4.2 Level Demo
Se o seu projeto contém assets que devem ser demonstrados ou vêm com algum tipo de tutorial, você deve ter um mapa dentro do projeto que contém o nome "Demo". Este nível também deve conter documentação de alguma forma que ilustre como usar seu projeto. Veja o projeto Exemplos de Conteúdo da Epic para bons exemplos de como fazer isso.
Se o seu projeto for uma mecânica de jogo ou outra forma de sistema em oposição a um pacote de arte, isso pode ser o mesmo que seu mapa "Overview".
Por exemplo, `InteractionComponent_Overview_Demo`, `ExplosionKit_Demo`.
**[⬆ Voltar ao topo](#table-of-contents)**
## 7. Texturas
Esta seção se concentrará em assets de textura e suas propriedades.
### Seções
> 7.1 [Dimensões são poderes de 2](#textures-dimension)
> 7.2 [A densidade da textura deve ser uniforme](#textures-dimension)
> 7.3 [As texturas não devem ser maiores que 8192](#textures-max-size)
> 7.4 [Grupos de textura corretos](#textures-textures-group)
### 7.1 Dimensões são poderes de 2
Todas as texturas, exceto as texturas de IU, devem ter suas dimensões em múltiplos de potências de 2. As texturas não precisam ser quadradas.
Por exemplo, `128x512`,` 1024x1024`, `2048x1024`,` 1024x2048`, `1x512`.
### 7.2 A densidade da textura deve ser uniforme
Todas as texturas devem ter um tamanho apropriado para seu caso de uso padrão. A densidade de textura apropriada varia de projeto para projeto, mas todas as texturas dentro desse projeto devem ter uma densidade consistente.
Por exemplo, se a densidade da textura de um projeto é de 8 pixels por 1 unidade, uma textura que deve ser aplicada a um cubo de 100x100 unidades deve ser 1024x1024, pois é a potência mais próxima de 2 que corresponde à densidade da textura do projeto.
### 7.3 As texturas não devem ser maiores que 8192
Nenhuma textura deve ter uma dimensão que exceda 8192 em tamanho, a menos que você tenha um motivo muito explícito para fazer isso. Freqüentemente, usar uma textura tão grande é simplesmente um desperdício de recursos.
### 7.4 As texturas devem ser agrupadas corretamente
Cada textura possui uma propriedade "Texture Group" usada para LOADing, e isso deve ser definido corretamente com base em seu uso. Por exemplo, todas as texturas da IU devem pertencer ao grupo de textura da IU.
**[⬆ Voltar ao topo](#table-of-contents)**
## Principais Contribuintes
* [Michael Allar](http://allarsblog.com): [GitHub](https://github.com/Allar), [Twitter](https://twitter.com/michaelallar)
* [CosmoMyzrailGorynych](https://github.com/CosmoMyzrailGorynych)
* [billymcguffin](https://github.com/billymcguffin)
* [akenatsu](https://github.com/akenatsu)
## Licença
Copyright (c) 2016 Gamemakin LLC
Veja [LICENSE](/LICENSE)
**[⬆ Voltar ao topo](#table-of-contents)**
## Emendas
Recomendamos que você crie um fork deste guia e altere as regras para se adequar ao Guia de Estilo de sua equipe. Abaixo, você pode listar algumas alterações ao Guia de Estilo. Isso permite que você atualize periodicamente seu guia de estilo sem ter que lidar com conflitos de mesclagem.
# };
================================================
FILE: docs/gettingstarted.md
================================================
# Getting Started
## Requirements
* You will need a launcher version of Unreal Engine 4 version 4.24 or later.
* You must purchase (for free) the Linter plugin on the Unreal Engine Marketplace.
@TODO: Add link here once I have it
## Installing From The Launcher
1. Close all your instances of Unreal Engine 4
2. Using the Epic Launcher find Linter in your Vault
3. Use the Install to Engine button to install Linter to your Engine

## Enabling Linter
1. Open your project
2. Open the Plugins window by clicking Edit on the main toolbar and navigating to Plugins
3. Search for Linter
4. Enable the Linter plugin by ensuring the Enabled checkbox is checked
5. Restart the editor
## Using Linter
Once installed there isn't much in the way of using Linter. Operating Linter is pretty straightforward:
1. Right-click on a content folder in your project
2. Click "Scan with Linter"
3. Select the ruleset you would like to use for linting
4. Wait for the results

## The Lint Report
Once a project is scanned, you will be presented with a Lint Report that provides an overall summary of the state of your project.

================================================
FILE: docs/howitworks.md
================================================
# How Does Linting Work?
Linter's bundled rulesets are included in the Linter Plugin content folder. Engine and Project plugin folders might be hidden in your engine. To show them, make sure the checkboxes next to Show Engine Content and Show Plugin Content are both checked in your Content Browser's View Options.

## Dissecting a Linter Rule Set

Linters are defined by `LintRuleSets`, essentially a fancy [Data Asset](https://www.youtube.com/watch?v=gLWXZ3FXhO8). In the above example, we are looking at the `MarketplaceLintRuleSet` asset which defines all of the rules we want to use when scanning for marketplace guideline compliance.

In the above image you'll see that this `LintRuleSet` uses a `NamingConvention` Data Asset named `MarketplaceNamingConvention` In addition to a NamingConvention asset, `LintRuleSet` assets also contain something called a Class Lint Rules Map. This is a map of Unreal Engine 4 classes paired with a list of `LintRules`, which are assets that make up individual rules that we'll cover later.

When objects in an Unreal Engine 4 project are linted, they are scanned using the rules that match the "most specific" class defined in the Class Lint Rules Map. You can use any class in this map, with the base `UObject` being a special case.
Unfortunately at this time the Unreal Engine 4 editor does not allow `UObject` as a valid value as a key in this Class Lint Rules Map, so if you want to define rules that you want to scan `UObjects` with, please use the `AnyObject_LinterDummyClass` class instead.
With the above example ruleset, when the Linter comes across a `UBlueprint` asset it will scan that asset using the four lint rules defined above. This is because `UBlueprint` is a more specific class definition than `UObject`. Another asset type, such as a data asset, will instead use the `AnyObject_LinterDummyClass` rules when being scanned unless there is a more specific matching class defined in the ruleset than `UObject`.
**NOTE:** Currently there isn't support for allowing cascading rule checks, i.e. allowing a `UBlueprint` being scanned against rules paired with `UBlueprint` *as well as* `UObject`. This support is planned to be added in a future release. See [todo](/todo).
## How Lint Rules Are Implemented
While `LintRules` can be implemented in both Blueprint and C++, currently there aren't too many functions exposed to Blueprint that deal with asset metadata and lower level asset management checks and tasks. It is currently strongly recommended that you do your rule checking logic in C++ and then only expose configuration settings to a Blueprint class.
All of Linter's bundled `LintRules` are Blueprint child classes that parent from a native C++ `LintRule`, with the goal that the Blueprint `LintRules` only expose configuration options.
### PassesRule_Internal_Implementation
The core of implementing your own `LintRule` is to implement the `PassesRule_Internal_Implementation` function. This function can be implemented in either C++ or Blueprint as this is a `BlueprintNativeEvent`.
This should be where the business logic of your `LintRule` operates. To report a rule violation, push a new `FLintRuleViolation` to the `OutRuleViolations` array and return false. You should always return false if **any** rule is violated and you should always return true if **no** rules were violated. A `FLintRuleViolation` is simply a struct that has a reference to the asset that is violating the rule, a reference to the rule that is being violated, and potentially any additional optional recommended text to display to the user reading the Lint Report.
Implementing this function is all you need for your `LintRule` to be functional and ready for use. For the sake of example, here is how the Unreal Engine Marketplace Guideline rule for ensuring your textures are not too big is implemented:
```cpp
bool ULintRule_Texture_Size_NotTooBig::PassesRule_Internal_Implementation(UObject* ObjectToLint, const ULintRuleSet* ParentRuleSet, TArray