游戏引擎IDE编辑器、UI控件布局、画面分辨率、导出模板、热更新插件、PCK/Patch、SDK库 API文档
综合
Godot - 读作“戈哦斗欧”,t不发音。 Godot 下载 - https://downloads.tuxfamily.org/godotengine/ 或官网(被墙) - https://godotengine.org Godot 每日构建下载 | Godot SDK Projects Godot IDE 窗口卡住或闪退的,可加参数来查看报错输出:./Godot_v4.x_mono_win64.exe -v 对于不支持 Vulkan 的老旧显卡,可以加降级参数来启动:./Godot_v4.x_mono_win64.exe --rendering-driver opengl3 Godot IDE 编辑器设置配置文件 - C:\Users\person\AppData\Roaming\Godot\editor_settings-4.3.tres Godot IDE “项目设置”窗口点亮“高级设置”之后才会显示额外配置项。 ICON - https://github.com/electron/rcedit Editor→Editor Settings→Export→Windows 指定 E:/game-dev/rcedit-x64.exe 可抑制警告 - WARNING: 资源修改: 无法启动 rcedit 可执行文件。 资源 - 内置支持的音频格式为*.ogg(AudioStreamOggVorbis)、*.wav(AudioStreamPlayer),视频格式为*.ogv;*.mp3不支持? Windows导出*.exe时软件名称为“Godot Engine”,且icon也是默认的,想修改的话可配置工具(编辑器设置→导出→Windows): 下载 https://github.com/electron/rcedit 鼠标悬浮会显示“文件描述/application/file_description”值,“产品名称”也可以顺带改下。
Godot编程
Godot IDE 若报 UNUSED_PARAMETER - The parameter "delta" is never used in the function "_process()". If this is intended, prefix it with an underscore: "_delta". 是指若不使用入参,可加下划线前缀来抑制该警告:_process(_delta) x.tscn格式: [node name="NodeName" parent="." instance=ExtResource("1_234az")] 说明 - 未写名type="Node3D"的node,会从instance值关联资源的type="通常为PackedScene或Material"来确定节点类型,IDE悬浮显示的类型则取自该关联资源的root节点type。
Godot UI - 布局、控件、Node2D
综合: IDE默认的分辨率过于保守,尺寸为1152×648 见源码;故首选移动端的 1280×720,而PC则为 steam使用率最多分辨率 的 1920 x 1080。 只有Control处于焦点时才会触发_gui_input,而不用更早触发的全局_input。 Node2D: 基于锚点(pivot_offset、anchor_...)定位 Control: 基于左上角定位 Node3D: 基于中心点定位 RichTextLabel v4.4+支持了水平居中对齐VERTICAL_ALIGNMENT_CENTER。
插件
Godot Git Plugin: Godot Git插件 已支持到v4.4,或用git命令行或VS Code控制源码。 已知问题 - 电脑:No suitable library found for GDExtension: res://addons/godot-git-plugin/git_plugin.gdextension. Possible feature flags for your platform... 安卓:USER ERROR: Failed loading resource: res://addons/godot-git-plugin/git_plugin.gdextension 排除:导出 -> 资源 -> 从项目中排除 exclude_filter="addons/godot-git-plugin/*" 参考 https://github.com/godotengine/godot-git-plugin/issues/77 解决:虽报错但不阻止游戏启动,若想抑制报错 - Godot 4.4dev6已根据exclude_filter来抑制报错 - https://github.com/godotengine/godot/pull/97216; 或打包前用MSBUILD或手动删除 .godot\extension_list.cfg IDE -> AssetLib 搜“git”或“Godot Git Plugin”,自动安装至项目根目录/addons/下 【或】手动抽取 godot-git-plugin-v3.1.0.zip 至项目 res://addons/godot-git-plugin/plugin.cfg 忽略addons目录 或 插件软链接【管理员身份】: 注意-Target路径结尾不能存在斜杠,以免git命令和git库识别不一。 New-Item -ItemType SymbolicLink -Path ./addons/ -Target E:\godot-git-plugin-v3.1.0\godot-git-plugin-v3.1.0\addons 或只软链接较大插件(30MiB+):New-Item -ItemType SymbolicLink -Path ./addons/godot-git-plugin/ -Target E:\game-dev\godot-git-plugin-v3.1.1\godot-git-plugin-v3.1.1\addons\godot-git-plugin 注意 - Open Project > Version Control > 创建版本控制元数据; 该操作仅生成或重置已配置好的.gitignore文件; 用法(不支持中文路径) - Open Project > Version Control > Version Control Settings > 勾上“连接到VCS”; 该面板Password值在IDE重启后清空;若想存储可考虑用GODOT_GIT_PASSWORD环境变量(官方还未做好):[Environment]::SetEnvironmentVariable("GODOT_GIT_PASSWORD", "[github password...]", 'User') 之后IDE右侧属性面板会增加一个Commit面板;添加至“Staged Changes”面板其实等同执行 git add . 命令,并不是 git stash 命令。 追加至 .gitignore 文件:注意不带斜杠的addons是软链接文件,非目录。 .godot/ addons/godot-git-plugin/ # 软链接路径 addons/godot-git-plugin android/ 且提交前必须执行以下命令行: git config --global user.name "your name" git config --global user.email "you@example.com" Push前还要点面板右下角三个点菜单 -> 新建远程仓库 - Name: origin URL: https://github.com/you/repo.git Windows操作Godot项目提示文件名过长,可通过删除.godot/文件夹解决。 Godot项目改名: [application] config/name="x" 程序集名可选: [dotnet] project/assembly_name="x" VS项目名可选: x.csproj中x x.sln中Project("{...}") = "x", "x.csproj", "{...}" Godot识别USD插件 - https://github.com/V-Sekai/godot-usd 内部用了pip install bpy库的bpy.ops.export_scene.gltf(...) Godot加载gltf格式3D模型 - new GLTFDocument().append_from_file("/path/to/file.gltf", gltf_state_load) Godot播放MP4视频(VideoStreamPlayer仅支持*.ogv) - https://zhuanlan.zhihu.com/p/657396670 Godot图片绑定骨骼制作2D动画工具(比关键帧动画尺寸小) - https://zh.esotericsoftware.com/spine-godot
Godot C#/Mono 外置IDE
VS Code: 也支持无跟踪隐私的VS Codium 安装 ms-dotnettools.csharp 扩展 Godot -> 编辑器设置 -> 高级设置 -> .NET -> Editor -> External Editor 为 Visual Studio Code and VSCodium; VS Code: 在VS Code运行选项卡,创建 launch.json 文件时从下拉菜单中选择 C# Godot, 运行Godot IDE并打开游戏项目等待被控制, 此时运行VSCode的Play in Editor会控制Godot IDE窗体进入调试模式。 [可选] launch.json的“Launch”配置项改成真实路径可无需打开GodotIDE: "executable": "D:\\x\\Godot_v3.3.2-stable_mono_win64.exe", [可选] launch.json的“Attach”配置未测 VS Code -> Trusted Folders & Workspaces:启用后C#智能感知等能力才可用,非系统防病毒排除项。 完全信任 - Settings -> security.workspace.trust.enabled -> 去除勾选 VS Code依赖库管理 - 使用命令行(NuGet Package Manager必须翻墙): dotnet add package NLog -v 4.6.7
Godot - 独立开发者游戏引擎
C#:
// 默认不编译已存在C#文件,必须触发下: Godot IDE -> 项目 -> 工具 -> Create C# solution 或 添加脚本 -> 语言 C# -> 创建 using Godot; using System; // Godot脚本类必须使用partial修饰符 public partial class MyScript : Node3D // 2D : Node { [Export] // 使其出现在Godot IDE属性面板 private Godot.Collections.ArrayArray; [Export(PropertyHint.MultilineText)] string Text { get; set; } // 控制C#属性的读写 public override void _Ready() { // 打印行数等堆栈信息 GD.Print(System.Environment.StackTrace); // 绝对原点 - IDE 3D默认视图 - 后、右、顶 GD.Print(Vector3.Zero); // 绝对朝向 - 物体朝向观众或摄像头的那一面,即IDE的3D后视图 GD.Print(new Basis(1, 0, 0, 0, 1, 0, 0, 0, 1)); // 全局距离 - 相对于绝对原点的远近;即3D视图中心 GD.Print(this.GlobalTransform.Origin); // 全局方向 - 相对于绝对正面的方向 GD.Print(this.GlobalTransform.Basis); // 相对于父节点距离 - 0或实际米数;即物体中心 GD.Print(this.Transform.Origin); // 相对于父节点方向 - 索引值只能0或1 GD.Print(this.Basis); // 等同this.Transform.Basis } public const int MOVE_SPEED = 300; public override void _Process(double delta) { // MoveToward 方法移动可解决瞬移问题; 或换用更常用的 MoveAndSlide(); this.Position = new Vector2(GetGlobalMousePosition().X, this.Position.Y); this.Position = this.Position.MoveToward(new Vector2(200, 200), (float)delta * MOVE_SPEED); } }
GDScript:
extends Node func _ready(): pass func _process(delta): pass
Godot游戏引擎3D/WASD移动模板实例
Godot 3D上下楼梯控制
最简单可用CollisionShape3D的SeparationRayShape3D,可通过旋转调整发射方向,原理是射线遇到障碍物后,从末端推挤自身碰撞区至离发射端最近的碰撞点 - https://github.com/Griiimon/CharacterBody-On-Stairs
或等待提案 https://github.com/godotengine/godot-proposals/issues/2751
Godot游戏引擎2D顶视图八向移动自由转向示例
Godot游戏引擎2D横板左右跳蹲+重力示例
Godot游戏引擎手机端虚拟摇杆
Godot游戏引擎手机端虚拟摇杆(已插件化):
用IDE内部安装会覆盖根目录README.md文件,故应手动下载并放入res://addons/virtual_joystick/。用法视频
虚拟摇杆插件用法实例(MeshInstance3D或Sprite2D脚本中): public override void _PhysicsProcess(double delta) { MoveAndSlide(); } // 注册analogic_chage(move: Vector2)信号 void _on_virtual_joystick_analogic_chage(Vector2 v2) { GD.Print(v2); Velocity = v2 * Speed; } // float Speed = 300.0f; // 3D Vector3用法: Vector3 direction = Vector3.Zero; // 为兼容pc+mobile而归零:_PhysicsProcess 底部追加 if (OS.HasFeature("pc")){ direction = Vector3.Zero; } void _on_virtual_joystick_analogic_chage(Vector2 v2) { direction = new Vector3(v2.X, Vector3.Zero.Z, v2.Y); }
Godot已知问题、反直觉情况
Godot项目支持Windows长路径,但导出Windows程序时却报错,临时解决办法是:导出盘符不要跟项目盘符一样; 另外报 Safe save failed 也是该问题所致,即保存 Shader Cache 时会在 .godot/shader_cache/SceneForwardMobileShaderRD/ 目录创建超长的目录名,可升级至解除限制的Godot 4.4,或通过 编辑器设置->文件系统->保存时->勾掉 Safe Save...。 非 .godot/ 目录报 Safe save failed 解决: Add-MpPreference -ExclusionPath "$env:userprofile\AppData\Local\Godot\"
Godot 3.x升级至4.x差异
C#包内dll可通过ILSpy反编译查看其类库 _Process(float delta) 改为 _Process(double delta);同样适用于 _PhysicsProcess(double delta) GetViewport().Size 改为 GetWindow().Size 注意 - Window类是v4.0新增。 vector2.x、vector2.y 改为 vector2.X、vector2.Y packedScene.Instance(); 改为 packedScene.Instantiate(); GetTree().ChangeScene("res://x.tscn"); 改为 GetTree().ChangeSceneToFile("res://x.tscn"); (int)ButtonList.Left 改为 MouseButton.Left Input.IsKeyPressed((int)KeyList.A) 改为 Input.IsKeyPressed(Key.A) inputEventKey.Scancode 改为了 inputEventKey.Keycode btn.Connect("pressed",this,"OnMethod"); 改为 btn.Pressed += OnMethod; 或 btn.Connect(Button.SignalName.Pressed, new Callable(this, "OnMethod")); 或不用this:Callable.From(OnMethod) 信号回调宽容的入参类型 _on_area_entered(object obj) 改为 强类型的 _on_area_entered(Area2D a) 其他变动: GetNode("AnimationPlayer").PlaybackSpeed 改为 animationPlayer.SpeedScale kinematicCollision.Collider 改为 kinematicCollision3D.GetCollider();适用于 collision.GetNormal() characterBody3D.GetSlideCount() 改为 characterBody3D.GetSlideCollisionCount() characterBody3D.Transform3D 改为 Transform control.RectPosition 改为 control.Position GD.RandfRange(0.9, 1.1) 改为 GD.RandRange(0.9, 1.1); 或(不确定) var rng = new RandomNumberGenerator(); rng.Randomize(); rng.RandfRange((float)0.9, (float)1.1); //入参从double变float
Godot插件开发
综合: 插件内获取导出项名字 - self.get_option("version/code") self 类型为 EditorExportPlugin 而非入参对象 platform.get_option("package/unique_name") GDS插件: 导出时决定是否包含插件aar和依赖库: # 只有 EditorExportPlatformAndroid 入参 platform.get_os_name()=="Android" 才会调用 func _get_android_dependencies(platform, debug): if self.get_option("package/unique_name").ends_with(".fullchannel"): return PackedStringArray(["com.openle.module:aos:1.0.0-SNAPSHOT","com.openle.module:core:1.0.0-SNAPSHOT"]) #return PackedStringArray(["_plugin_name/p-release.aar"]) # for _get_android_libraries(platform, debug) return PackedStringArray() 导出时下载aar文件: func _get_android_libraries(platform, debug): var hr = HTTPRequest.new() Engine.get_main_loop().root.add_child(hr) hr.request("https://congci.com/.well-known/static/images/core/logo.svg") var r=(await hr.request_completed)[3] print(r.get_string_from_utf8()) return PackedStringArray(["x.aar"]) 导出时添加额外配置文件: func _export_begin(features: PackedStringArray, is_debug: bool, path: String, flags: int): var json=("{\"versionCode\":" + str(self.get_option("version/code")) + "}"); add_file("res://export-plugin-gen.json", json.to_utf8_buffer(), false) #add_file("res://gen.bytes",PackedByteArray(),false) 覆盖导出项: func _get_export_options_overrides(platform) -> Dictionary: return { "binary_format/embed_pck": true, } EditorPlugin在IDE“文件系统”右键增加菜单项:func _enter_tree(): # EditorPlugin var plugin = preload("res://addons/OurGameCore/menu.gd").new() add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_FILESYSTEM, plugin) # menu.gd extends EditorContextMenuPlugin func _popup_menu(paths): var pm = PopupMenu.new() pm.add_item("SubMenu",1) pm.add_item("SubMenu2",2) pm.id_pressed.connect(func(ids):print(ids)) add_context_submenu_item("TopMenu",pm) #add_context_menu_item("TopMenu",func(resPaths):print(resPaths))Godot OTA
Godot游戏OTA、PCK、MOD、Patch基本概念 动态PCK: 说明 - PCK项目不需要主场景和类,导出选项最好不要勾上“Runnable/可执行的”,“导出 PCK/ZIP”首选紧凑的*.pck后缀。 var bytes = Godot.FileAccess.GetFileAsBytes("res://ExportingProject.dll"); var asm = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).LoadFromStream(new MemoryStream(bytes)); ScriptManagerBridge.LookupScriptsInAssembly(asm); // GDS则只需要以下1行即可: var ok = ProjectSettings.LoadResourcePack("res://ExportingProject.pck");其他
Godot IDE新建脚本时勾上“Built-in Script”可将代码嵌入到*.tscn中,但不支持C#。 Godot节点各种移动方式 - https://godotlearn.com/godot-3-1-how-to-move-objects/ 文档生成时通过环境变量指定语言:SPHINXOPTS="-D language=zh-CN" 教程 - https://docs.godotengine.org/en/latest/contributing/documentation/building_the_manual.html