Godot进阶学习
项目文件
- project.godot
- 项目配置信息文件,class_name 自定义的类也会被写入
- 此文件导出后会被放入 pck 文件中
- 多人合作时,要小心此文件的覆盖问题
- override.cfg
- 存放项目设置信息的文件。
- 可覆盖 project.godot 中重复的设置信息。
- 但需要手动或使用代码创建。
- ProjectSettings
- 与项目设置相关的单例,可以使用代码在这个单例中设置项目设置的信息。
- 并保存为 project.godot 或 override.cfg
- 使用代码修改的信息,不会对运行中的游戏造成实质性的影响。
RefCounted
RefCounted 内置了一个独特的引用计数器(可以自动销毁的类)
RefCounted 对象的生成类名.new() (类名由 class_name 进行自定义)load(“路径”).new()(也可以 preload(”路径”).new())
RefCounted 的特征
- 引用计数器归 0 时,此对象自动被程序删除
- 在 GDS 中不包含任何内置属性,仅有四个内置函数,也不必像节点一样要频繁的受场景树的控制,参与服务器的计算工作,相比于节点更加轻量
- 作用:比 Node 占用更少的内存节约更多的电脑的算力、还可以进行内存的自动管理。非常适合用于制作游戏中数目庞大的数据对象
RefCounted 的重要子类:
Resource
游戏文件与游戏程序的中转站
所有的图片、音频、视频文件都必须先转为 Resource 才可以被节点等对象使用Astar2D/Astar3D
可以用于构建游戏中的寻路数据Thread/Mutex/SemaPhore
可以用于构建多线程FileAcess/DirectoryAcess
可用于加载读取计算机内的文件
某些子类进行 UDP、TCP 或Websocket 的网络通信StreamPeer
可以以字节单位对网络传输中收发的数据进行处理
此外,它的子类还涉及了正则、JSON、游戏物理、自定义引擎编辑器等领域
Resource
Resource 的继承关系
- Resource 对象继承自 RefCounted
- Resource 可以进行信号绑定、脚本绑定等一系列 Object 可以进行的操作
- Resource 也有内置引用计数器,计数器归 0 时,资源自动被删除
需转为 Resource 的常见文件
- 图片、3D模型、音频、视频文件
- 场景文件
- 脚本文件
资源供对象的使用的方式
- 多对象使用同一资源本身、适用于图片、3D 模型、音频、视频文件等
- 资源经过再处理后,生成新对象,供不同对象使用
- 脚本资源再处理生成的对象在 GDS 中不可见,这个新对象被编写在内置代码中, 当使用 set_script 或绑定脚本的对象生成时它也将自动生成
程序中 Resource 对象的创建
- 通过路径加载文件生成资源
- 资源随场景启动而自动创建
- 将资源文件(可以转化为资源的文件)拖入游戏项目中。
- 编辑器对资源文件进行导入,生成特殊文件以及资源文件对应的 import 文件。 import 文件会指向特殊文件。
- 游戏启动后借由 import 文件加载特殊文件生成资源对象。
- 加载路径产生资源时,如果原先的资源不消失,则不会产生这个文件的新资源对象, 而只返回引用。在任意一处对此资源的修改,都将影响到所有使用此资源的对象。
load 与 preload
如果加载的文件已经被转化为资源,且此资源引用计数器不为0,则在此加载此文件不会产生新的资源对象,而是返回一个原先资源对象的引用
▪ load(“文件路径”)或 preload(“文件路径”)
创建新对象:
由类名 .new()创建,不会产生相同引用。
▪ 内置资源类:某些内置资源类也可以使用 new 以外的函数来创建资源对象。部分内置资源类内部拥有读取与保存文件的函数。
▪ 自定义资源类
load 与 preload 的区别
- load 的参数可以是字符串变量。preload 则无法使用变量,这是由于二者执行的时机不一样所导致的。
- load 后可跟随字符串变量,字符串变量的值可以在程序运行时改变,如果改变变量,load 可以加载不同的文件
- preload 后只能跟随固定的字符串,不会在程序运行时改变
当脚本文件转化为脚本资源时,转换部分的程序会自动翻找文件中是否出现了 preload 函数,若出现,则在脚本资源生成的同时进行 preload 资源的加载。这时候变量还没有出现,因此只能以文本字符串的形式来告知 preload 加载的内容。
资源保存的格式
tres :文本资源格式。具有可读性。
res :二进制资源格式。程序加载速度更快。
某些资源会提供特殊格式来保存自己的数据。
MainLoop
程序启动后,程序会创建一个主循环对象,它包含了初始化、空闲帧同步回调、物理帧同步回调等方法
这个类中不包含与节点相关的具体操作
制作游戏时几乎不会遇到需要自行编写 MainLoop 的情况
空闲处理与物理处理(Idle Process 与 Physic Process)
- 物理处理:Godot 中会内置一个物理服务器,用于处理游戏世界内的各种物理计算。在每一次物理计算之前,这个服务器都会给予主循环一次参与计算的机会, 这就是主循环中的物理处理。默认情况下,物理服务器一秒内会进行 60 次运算,因此主循环中的物理处理也会每秒进行六十次处理。
- 空闲处理:在 Godot 相对“空闲”(当某些内置服务器运行结束的时候)的时候执行此处理。引擎会尽可能快的利用空闲时间来绘制新的游戏图像。
节点中的空闲处理与物理处理
- _process(delta): 空闲帧回调函数 delta 表示距上次空闲帧调用的时间
- _physic_process(delta):物理帧回调函数 delta 表示距上次物理帧调用的时间
- call(函数名):立即调用函数
- call_deffer(函数名):到下个空闲帧调用函数
Viewport
游戏运行时出现的第一个节点,当第一次加载主场景时, 游戏程序将先创建一个 viewport 节点并且将此节点添加到场景树下,然后再将主场景的根节>点作为 Viewport 的子节点添加过去。场景树下的节点都是第一个 viewport 节点的子节点。
Viewport 节点的功能
这个节点可以在屏幕中创建一个不同的窗口或在另一个窗口中创建子窗口。
游戏世界中出现的第一个 Viewport 节点将会创建一个World2D 与一个World3D 对象,分别代表一个独立运行的 2D世界和 3D世界
Viewport 节点的子 Node2D 节点与子 Node3D 节点将分别参与两种世界的构成。
Viewport 节点的子 Camera2D/Camera 节点(2D 摄像机与 3D 摄像机)节点,可以调整游戏显示的区域
应用
高阶应用:
- 访问 world_2d(world_3d)属性,直接对游戏世界造成影响或查询游戏世界中物 理 / 视觉 / 声音元素的状态。
常用应用:
- 双人游戏时的分屏效果
分屏效果就是用两个 Camera2D(Camera)节点,来显示同一个World2D (World3D)对象内的不同区域内容。而一个 Camera2D 只可以影响到一个 Viewport 节点的显示范围,因此,我们可以创建两个代表相同World2D 对象的 Viewport 节点。
补充:默认情况下,当我们手动新建一个 SubViewport 节点时,这个节点将会创建 一个新的World2D 对象,而不会去创建一个新的World3D 对象。这将导致 Viewport 节点拥有一个独立的 2D 世界,而它代表的 3D 世界则是最近的上级 Viewport 节点代表的 World3D 对象。 - 输入事件的处理
其他:
- 获取屏幕画面截图 ▪ 设置 / 获取鼠标位置 ▪ 等等 ……(详情请查询文档)
输入事件处理(Viewport 节点最常用的功能)
节点的_input 与__unhandled_input 函数
- 都是输入事件处理函数,当我们点击鼠标、按下键盘和进行其他输入设备的操作时,一个对应的输入事件就会被创建,输入事件会在节点中进行传播
此时节点中的_input 函数将根据传播的顺序依次被调用。 - 在_input 传播中, 输入事件未被处理掉,则在节点中再进行一次此事件的传播,此时_unhandle_input 自动被调用。unhandle_input 的含义即为未处理输入。
- 参数 event 可以代表鼠标点击、键盘按压、屏幕触碰、屏幕拖拽等多种输入事件,不同种类的事件被划分为 InputEvent 的不同子类,它们各自拥有不同的属性,在编写 _input 与_unhandle_input 函数时,要先判断 event 的类型,再进行具体属性的处理。
Viewport 对 event 的处理
- 将事件设为已处理
- 创建 input 输入事件
- 创建 unhandleinput 事件
- 创建文本输入事件
技巧积累
- 多用信号,避免繁琐的节点访问。
- 避免频繁切换场景(change_scene_to_file()方法),否则性能开销较大。考虑使用一个Main根节点来组织场景树。
- 在_process()(或其他频繁调用的方法)中避免高消耗的操作,例如加载素材。
- 尽量使用@export的方法加载复杂路径的节点,避免在脚本中直接写节点路径,这样在更改节点路径后不会出问题。


