抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

配置并使用FGD

FGD文件是什么

FGD: Forge Game Data ,这里引用VDC的一段描述

FGD (Forge Game Data) is a plain-text file format used to define all of the entities of a game for a map editor, allowing mappers can select them from within the editor and configure their properties.

FGD 代表 Forge Game Data。它是 Hammer(en) 游戏定义文件的文件扩展名。它们定义了游戏的所有实体,因此地图作者可以从编辑器中选择它们。

简而言之,FGD是用来告诉地图编辑器(TrenchBroom),我们的游戏里面有什么实体,然后可以在地图编辑器内选择并放到我们的地图内


FGD资源文件

image.png

当你在项目中添加一个fgd资源时,你会看到好些带FGD的文件可以创建,我们只需要以下四种:

  • FuncGodotFGDBaseClass

    是特殊继承类,用来定义属性

  • FuncGodotFGDSolidClass

    用于创建笔刷*(Brush)*实体,比如trigger , 梯子、水所需要的trigger,还有一些无碰撞的brush

    FGD SolidClass entity definition, used to define brush entities. A MeshInstance3D will be generated by FuncGodotMap according to this definition’s Visual Build settings. If FuncGodotFGDSolidClass Node Class inherits CollisionObject3D then one or more CollisionShape3D nodes will be generated according to Collision Build settings.

    FGD SolidClass 实体定义,用于定义画刷实体。FuncGodotMap 会根据此定义的 Visual Build (一个选项) 设置生成一个 MeshInstance3D。如果 FuncGodotFGDSolidClass节点类 继承自 CollisionObject3D,则会根据 Collision Build 设置生成一个或多个 CollisionShape3D 节点。

  • FuncGodotFGDPointClass

    用来定义点实体,详见点实体 - Valve Developer Community

    以我个人的理解,是用来在地图编辑器内放置环境实体、道具模型(*Props)*实体、和NPC实体

  • FuncGodotFGDModelPointClass

    一种特殊类型的FuncGodotFGDPointClass ,引用Docs的机翻

    可以自动生成 一个特殊的简化、缩放和重新定位的 GLB 模型文件,用于地图编辑器显示

    以我个人的理解,应该是单纯用于放置道具*(Props)*实体的特殊优化版本


FuncGodotFGDBaseClass

基类,用来定义基础FGD属性

image.png

  • FuncGodotFGDEntityClass
    • Entity Definition

      Classname:在地图编辑器内显示的名字

      Description:此类的描述

      Func Godot Internal: 勾选会导致不导出到FGD,仅用于Func_Godot的地图构建过程

      Base Classes : 要继承的基类,这里是要填入别的FGDBaseClass

      Class Properties : 此类的属性,会显示到地图编辑器内,同时会将编辑后的属性添加到Func_Godot生成的节点内

      如何使用:先点击新建键右边的那个笔新建一个String填入名字,然后再点击新建值右边的笔新建你想要的变量(详见:Func_Godot Docs),只有在以上填好了填正确了再去点击添加键值对,不然不会添加到字典内!

      Class Property Descriptions: 此类属性的描述,填写方法如上

      Meta Properties: 此类在地图编辑器的外观属性(size,color,model等)

    • Node Generation

      在基类中不必填写,但是为了方便查阅起见我会写在此处

      Node Class: Func_Godot要生成的节点,例如填入Area3D会生成Area3D而不是普通的CollisionShape3D or Node3D

      Name Property: 疑似是名字,原文:

      Optional. Specifies a class property belonging to this entity that will be used to name the generated node upon map build. The node is renamed to prior to being added to the SceneTree and applying .Overrides the Entity Name Property setting in FuncGodotMapSettings.NOTE: Node names should be unique, otherwise you may run into unexpected behavior!

      1
      "entity" + name_property

      Notion翻译:

      可选。指定属于此实体的一个类属性,该属性将用于在地图构建时命名生成的节点。节点会在被添加到SceneTree之前重命名,并应用。这会覆盖FuncGodotMapSettings中的Entity Name Property设置。

      注意:节点名称应该是唯一的,否则您可能会遇到意外行为!

      节点将被重命名为:”entity” + name_property

一般情况下只需要复制黏贴example内的base fgd就可以使用了,有特殊需求的基类自己重新写一个即可

详情写法请参考func_godot官方的example repo

https://github.com/func-godot/func_godot_example_basic

FuncGodotFGDSolidClass

用于创建笔刷 (Brush) 实体

image.png

  • FuncGodotFGDSolidClass

    Spawn Type : 一般来说默认Entity即可,详情请看docs

    Original Type : 该选项仅在SpawnType为Entity时有效,一般来说默认即可

    • Visual Build

      Build Visuals : 是否生成视觉网格(MeshInstance3D)

      Use in Baked Light :

      将生成的 MeshInstance3D 设置为可用于 FuncGodotMap 构建后的 UV2 展开。用于烘焙光照贴图。

      Sets generated MeshInstance3D to be available for UV2 unwrapping after FuncGodotMap build. Utilized in baked lightmapping.

      Shadow Casting Settings : 投射阴影设置

      Build Occlusion : 是否生成用于遮挡剔除的OccluderInstance3D(具体请看Godot Docs)

      Render Layers : 渲染层调整

    • Collision Build

      • Collision Shape Type:

        可选为

        • None(无)

          不构建碰撞体

        • Convex(凸面)

          MeshInstance3D会构建ConvexCollisionShape3D,非StaitcBody3D节点必须选择此项目(如Area3D及RigidBody3D)

        • Concave(凹面)

          MeshInstance3D会构建ConcaveCollisionShape3D,会跳过处理用了Skip材质的面

        建议以实际游戏需要为准去选择

      Collison Layer : 碰撞层

      Collision Mask : 碰撞遮罩

      Collision Priority : 碰撞优先级

      Collision Shape Margin : 碰撞边距

    • Scripting

      Script Class : 脚本,具体请参照example,文章/视频后面会有演示(也许可以单独分开几个视频?)

FuncGodot FGD Point Class

用来定义点实体,用于在地图编辑器内放置环境实体、道具模型(*Props)*实体、和NPC实体。

image.png

  • FuncGodotFGDPointClass
    • Scene

      Scene File : 你的场景

    • Scripting

      Script Class : 脚本文件

    • Build

      Apply Rotation on Map Build : 当地图编译时是否要引应用旋转

FuncGodot FGD Model Point Class

image.png

  • FuncGodotFGDModelPointClass

    Target Map Editor : 目标地图编辑器,如使用trenchbroom,请选择trenchbroom

    Modifies whether the entity definition uses the or keyword, and how it applies display model scaling. Options are GENERIC or TRENCHBROOM.

    修改实体定义是否使用 “or” 关键字,以及如何应用显示模型缩放。选项为Generic或TRENCHBROOM

    Model Sub Folder : 可选,如填写则模型会相对于FuncGodotLocalConfig中设置的Game Path Models Folder的位置额外创建文件夹并导出在其中(待验证,因为忘了哈哈)

    Scale Expression : 仅限TrenchBroom,应用于模型的缩放表达式,详情请见 TrenchBroom 文档。如果要为其他地图编辑器设置,请设置FuncGodotLocalConfig中的Default Inverse Scale

    Generate Size Property : 通过网格的aabb自动生成覆盖Meta属性内的size项目。正确生成需要将Scale Expression设置为float 或Vector3

    Generate gdignore File : 在模型导出的文件夹内生成 dot gdignore文件,以用来防止Godot导入模型,一般情况下只需要设置一次(但是多点基础无所谓的)

在正式创建一个FGD前…

https://github.com/func-godot/func_godot_example_basic

个人建议将func_godot官方的example内的fgd、他们的脚本文件,以及GameManager.gd复制黏贴到你的项目之后( 注意:在黏贴前请关闭你的项目,否则会报错且无法修复缺失文件 ),在进行接下来的操作

理由是:官方example内已经有基础的fgd(trigger以及灯光摄像机)可以OOTB了,不需要重复造轮子


黏贴好后请把GameManager.gd挂到自动加载上(项目→全局→自动加载);然后打开那些fgd,修复缺失文件,一般来说直接会自动识别,点以下确定就完成了

做完上述步骤后,我来做几个example来演示一下怎么做

示范以及使用

接下来我们写一个没有脚本的模型fgd以及一个有脚本的触发器fgd,他的作用是”在玩家碰到后会在后台输出’hello,world‘ “

我们先来做第一个,也就是单纯的模型FGD:

示例

模型FGD

处理模型:

首先我们先找一个喜欢的模型将他导入到godot内,然后创建一个新场景,将模型拖进3D视图内

image.png

然后点击”在编辑器中打开”,会弹出以下窗口,我们点击”仍然打开“

image.png

打开后,请将模型正面旋转到和-z方向对齐,这样做是为了在tb中的模型的方向也是面相前方,然后看你个人喜好修改一下模型的节点。完成后我们按ctrl+shift+s另存为一个dot tscn文件

创建FGD:

你分类好的fgd资源文件夹 或 没分类好的文件夹 内, 新建一个FuncGodotFGDModelPointClass ,命名不建议非常随意(为了项目管理和以后的你自己着想),我这边命名为”prop_turtle”(既”道具_乌龟”)

编写FGD:

我们直接把上面的tscn文件拖进Scene → scene file内,然后打开Build → Apply rotation on map的选项,顺便把Target Map Editor 选为 TrenchBroom

然后打开Entity DefinitionClassName请填入你的文件名字(为了方便管理),Description可写可不写。

来到下面的Meta Properties, 根据模型实际大小设置size数值

  • 根据我的摸索,xyz都是负数,whd都是正数

    xywh只要填写一样的数字,且xywh互为相反数即可保持在模型中央位置

    zd 的话,z 是控制模型垂直以上方向,d是控制模型垂直以下的方向

    默认1 hammer单位= 0.03125 godot单位,也就是说16hammer单位=0.5Godot单位

    例如我这边的小乌龟模型是1m,也就是32hammer单位,所以我这边是填写成:

    • {-16 , -16 , 32,

      16 , 16 , 0 }

填好后直接ctrl+s保存即可,然后我们继续下一个

如果你想直接测试请跳转到下一章节

触发器FGD

创建FGD:

你分类好的fgd资源文件夹 或 没分类好的文件夹 内, 新建一个FuncGodotFGDSolidClass,我这边命名为trigger_test

编写FGD:

在Func_Godot 2024.2版本中,Origin Type 默认变成了 Bounds Center , 我个人建议改成以前的 Averaged(预防不测)

由于我们只是做一个测试用的触发器,所以可以不动Visual Build的选项,以方便调试

然后来到下面的FuncGodotFGDEntityClass我们填写Classname、Description,然后在Node Class内填入 Area3D

最后我们在上面的Scripting → Script Class内添加一个新的脚本

他这个插件添加脚本是默认生成一个空的文本,然后在Script页面对这个空文本编辑。但由于我使用的是外置编辑器去编辑脚本,所以是需要先在项目内添加脚本,然后再把脚本拖入Script Class的框里面才能正常在外置编辑器内编辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#必须给脚本带上@tool属性
@tool

#建议类名和文件名相对应
class_name TriggerTest
#填写你在*Node Class*填写的内容
extends Area3D

func _init():
#连接到Area3D"body_entered"信号
connect("body_entered" , _on_ent_entered)

func _on_ent_entered(ent: Node) -> void:
print("Hello,world!")

然后保存即可

使用

做完以上两项(或一项)后,你得到了两个fgd文件

我们先找到 ~\addons\func_godot\fgd*func_godot_fgd.tres,然后我们打开你从 exmaple项目 黏贴来的fgd_main.tres,func_godot_fgd.tres拖入到Base Fgd Files*旁边的Array[Rsourece]那个选框里,并将其排序到第一位(如图)。别忘了改FGD名字!

image.png

然后我们打开fgd_main.tres同目录下的fgd_point.tresfgd_solid.tres,分别将你刚刚写的模型fgd触发器fgd 分别 拖入到他们的 Entity Definitions 内(不需要排序)

完成后将 你修改过的fgd_main.tres 拖入到 第一节创建的 func_godot_default_map_settings 文件内的 Entity Fgd,将其替换;然后打开你的 TrenchbroomGameConfig, 将你的 fgd_main.tres拖入拖入到 Entites→ FGD File内。

接下来打开 res://addons/func_godot/game_config/trenchbroom/,将里面的tb_brush_tag_func.trestb_brush_tag_trigger.tres拖入到Tags→Brush Tags内,没有这个笔刷标签,你的trigger实体无法正常使用。完成后 点击 Export File 即可

然后打开trenchbroom和你的地图,验证是否报错,如有请自行排查,或者实在找不到问题所在可以私信我。如果没有问题的话,你应该会在trenchbroom右边看到你所创建的模型实体;对着一个brush右键应该也能看到你的碰撞体实体。(图为示例)

image.png

拉完box后保存,回到Godot内点击编译后运行,如果没什么岔子,那应该能看到你的模型、走入trigger后能在内debug terminal中看到”hello,world!”,那就恭喜你!完成了这一节的教程

你已经很牛逼了,快去做个复杂fgd实体把!

Extra

指向性Brush实体

Brush实体默认不带指向性,如有需要,可以尝试在需要的实体fgdClass Properties 内添加一个 键为 angle 值为 int or float 的类,重新编译后即可使用

但是就算是你有了这个键值,func_godot编译时也不会实际让这个物体的旋转变成这个值,他只会简单粗暴创建一个应用变换后的物体,要使用的话得在脚本内填入以下代码后才能获取你在trenchbroom修改的数值:

1
2
3
4
5
#在@tools下面
@export var angle : float

func _func_godot_apply_properties(props: Dictionary) -> void:
angle = props["angle"] as float

如果没有什么问题,那么在你重新编译后,会在所在node的属性内看到多出来一个angle的键值,上面写着你的旋转属性,接下来就可以在代码内将他的子物体旋转了


Choices & Bit Flags

如果需要在tb内下拉选择(Choices)或者多选额外属性(Bit Flags),请查看Docs

FuncGodot Manual

简单来说,下拉选择就是在Class Properties 内创建字典,键和值固定为Stringint;多选就是建立一个Array,然后在这个Array再建立一个Array,在这个Array内创建一个string和两个***int(*也就是一个为选项名字,另外两个为布尔值)具体请看图

REF

FuncGodot FGD File

FuncGodot FGD Entity Class

FuncGodot FGD Base Class

FuncGodot FGD Solid Class

FuncGodot FGD Point Class

FuncGodot FGD Model Point Class

评论