Godot 学习笔记(5):彻底的项目工程化,解决GodotProjectDir is null+工程化范例
文章目录
- 前言
- GodotProjectDir is null
- 解决方法
- 解决警告问题
- 根本解决代码问题
- 测试引用
- 其实其它库的输出路径无所谓。
- 工程化范例
- 环境
- 命名规范
- Nuget
- 项目结构
- 架构代码
- ISceneModel
- IOC服务
- 测试
- GD_Extension 通用扩展
- TestUtils
- GD_Program
- TestService
- MainSceneModel
- Godot对应的脚本实体
- 测试
- 总结
前言
Godot 项目工程化上有一朵乌云,我看Godot的Visual Studio 项目的时候,发现如果是手动新建项目导入Godot包,会导致编译的warning,这个虽然不影响正常运行,但是有warining还是不不爽,这次彻底解决他。
GodotProjectDir is null
出现这个问题的原因是,我想分项目开发
然后会报warning
所以我之前的项目封装,是放在一个文件家里的,非常的丑陋
解决方法
先把这三个先装上
解决警告问题
GitHub上面找了一圈,找到了解决方案
C# Godot project with MSTest - Error: Generator ‘ScriptPathAttributeGenerator’ failed to generate source. #87753
这个是解决警告问题。
<PropertyGroup><IsGodotToolsProject>true</IsGodotToolsProject>
</PropertyGroup>
根本解决代码问题
添加输出路径
$(GodotProjectDir).godot\mono\temp\bin\
<PropertyGroup><GodotProjectDir>../Godot/</GodotProjectDir></PropertyGroup>
测试引用
外面这里做一个做简单的测试
其实其它库的输出路径无所谓。
我们看这两个项目的输出路径
1>------ 已启动全部重新生成: 项目: ClassLibrary1, 配置: Debug Any CPU ------
已还原 D:\workspace\program\Godot Game\Train\Test18\Godot\Test18.csproj (用时 12 毫秒)。
已还原 D:\workspace\program\Godot Game\Train\Test18\ClassLibrary1\ClassLibrary1.csproj (用时 16 毫秒)。
1>ClassLibrary1 -> D:\workspace\program\Godot Game\Train\Test18\Godot\.godot\mono\temp\bin\Debug\net6.0\ClassLibrary1.dll
2>------ 已启动全部重新生成: 项目: Test18, 配置: Debug Any CPU ------
2>Test18 -> D:\workspace\program\Godot Game\Train\Test18\Godot\.godot\mono\temp\bin\Debug\Test18.dll
========== “全部重新生成”: 2 成功,0 失败,0已跳过 ==========
========== 重新生成 于 0:09 完成,耗时 01.830 秒 ==========
其实只要Godot的输出路径是对的就可以了
工程化范例
既然已经成功可以项目分离了,我就做个我心中的工程化范例好了
环境
- Godot 4.2.1
- .net core 8.0(需要手动更改)
- window10
- visual studio 2022
命名规范
Nuget
项目结构
依赖关系,从底层开始
Godot_Extension->Godot_Program->Godot
架构代码
架构代码主要是在GD_Program里面。因为IOC容器时在GD_Program里面。
ISceneModel
/// <summary>
/// SceneModel的基类
/// </summary>
public abstract class ISceneModel
{/// <summary>/// 挂载场景,强制Node2D/// </summary>public Node2D? Sence { get; set; }/// <summary>/// 打包场景,用于生成/// </summary>public PackedScene? PackedScene { get; set; }/// <summary>/// 重载Ready事件/// </summary>public abstract void Ready();/// <summary>/// 重载Process事件/// </summary>/// <param name="delta"></param>public abstract void Process(double delta);/// <summary>/// 方便加载场景/// </summary>/// <param name="sceneName"></param>public virtual void SetPackedScene(string sceneName){var targetName = sceneName.Replace("Scene", "");var url = $"res://Scenes//{targetName}.tscn";GD.Print($"加载PackedScene,{sceneName}:{url}");PackedScene = ResourceLoader.Load<PackedScene>(url);}}
IOC服务
public class Program{/// <summary>/// IOC容器/// </summary>public static IServiceProvider Services = ConfigureServices();/// <summary>/// Configures the services for the application./// </summary>private static IServiceProvider ConfigureServices(){var builder = new ServiceCollection();AddServices(builder);AddSceneModel(builder);return builder.BuildServiceProvider();}/// <summary>/// 添加服务,应以Singleton形式添加/// </summary>/// <param name="service"></param>public static void AddServices(ServiceCollection builder){builder.AddSingleton<TestService>();}/// <summary>/// 添加SceneModel,应以Transient添加/// </summary>/// <param name="service"></param>public static void AddSceneModel(ServiceCollection builder){//比如//builder.AddTransient<MainSceneModel>();}}
测试
GD_Extension 通用扩展
TestUtils
测试类
public class TestUtils{public TestUtils(){}public void Test(){GD.Print("我是Utils方法");}}
GD_Program
TestService
public class TestService
{public TestService() { }public void Test(){GD.Print("我是TestService方法");}
}
MainSceneModel
public class MainSceneModel : ISceneModel
{private TestService testService;private TestUtils testUtils = new TestUtils();public MainSceneModel(TestService testService){this.testService = testService;}public override void Process(double delta){}public override void Ready(){GD.Print("Hello Godot!");//在Ready中测试IOCtestService.Test();testUtils.Test();}
}
Godot对应的脚本实体
public partial class MainScene : Node2D
{public MainSceneModel Model { get; set; }public MainScene(){Model = Program.Services.GetService<MainSceneModel>();Model.Sence = this;Model.SetPackedScene(nameof(MainScene));}public override void _Ready(){Model.Ready();base._Ready();}public override void _Process(double delta){base._Process(delta);}
}
测试
总结
看来确实是设置IsGodotToolsProject就可以用了,这样我们终于能标准化开发Godot项目了
相关文章:

Godot 学习笔记(5):彻底的项目工程化,解决GodotProjectDir is null+工程化范例
文章目录 前言GodotProjectDir is null解决方法解决警告问题根本解决代码问题测试引用其实其它库的输出路径无所谓。 工程化范例环境命名规范Nuget项目结构架构代码ISceneModelIOC服务 测试GD_Extension 通用扩展TestUtils GD_ProgramTestServiceMainSceneModel Godot对应的脚本…...

算法打卡day23|回溯法篇03|Leetcode 39. 组合总和、40.组合总和II、131.分割回文串
算法题 Leetcode 39. 组合总和 题目链接:39. 组合总和 大佬视频讲解:组合总和视频讲解 个人思路 这道组合题主要是有总和的限制,当递归和超过了总和就return,递归时加上回溯去遍历数组。 解法 回溯法 把组合问题抽象为如下树形结构 如上…...

Google研究者们提出了VLOGGER模型
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
Python从入门到精通秘籍十九
一、Python之union 联合类型注释 当谈论Python中的联合类型注释时,通常会提到Union类型。Union是typing模块中定义的一个泛型类,用于表示多个可能的类型。 Union的语法如下: Union[type1, type2, ...]其中type1, type2, … 是要组成联合类…...

解决:您还有0天的时间继续使用internet download manager
通过修改注册表来白嫖的IDM方法 1、新建txt文件复制代码(命名为idm.reg) 2、代码如下 Windows Registry Editor Version 5.00[-HKEY_CURRENT_USER\Software\Classes\CLSID\{7B8E9164-324D-4A2E-A46D-0165FB2000EC}] [-HKEY_CURRENT_USER\Software\Clas…...
操作系统目录
北航操作系统 chapter 1 北航操作系统 chapter3-1 内存管理 北航操作系统chapter3-2 内存管理 北航操作系统chapter3-3 页式管理 北航操作系统chapter3-4 段式管理 北航操作系统chapter3-5 虚拟内存管理 操作系统chapter4-1 进程与线程 北航操作系统-chapter4.2 同步与互斥…...
常用的Node.js命令集锦
当使用Node.js开发时,以下是一些常用的Node.js命令集锦: npm init 用于初始化一个新的Node.js项目,并创建一个package.json文件来管理项目的依赖和元数据。 npm install [package-name] 用于安装指定的Node.js包,可以通过--save选…...

2021年XX省赛职业院校技能大赛”高职组 计算机网络应用赛项 网络构建模块竞赛真题
“2021年XX省赛职业院校技能大赛”高职组 计算机网络应用赛项 网络构建模块竞赛真题 目录 一.考试说明 1 二.模块B网络构建 2 (一)任务描述 2 (二)任务清单 9 一.考试说明 本模块比赛时间为…...
80386 ATT汇编语法
文章目录 gcc的预处理,不进行编译、汇编或链接预处理编译汇编 8.8.2 AT&T语法与英特尔语法8.8.3操作码命名8.8.4寄存器命名8.8.5操作码前缀8.8.6内存引用8.8.7跳转指令的处理8.8.8浮点8.8.9写入16位代码8.8.10笔记 gcc的预处理,不进行编译、汇编或链…...

如何在Linux系统使用宝塔面板搭建Inis博客并发布至公网【内网穿透】
文章目录 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道(云端设置)2.3.Cpolar稳定隧道(本地设置) 3. 公网访问测试总…...

【漏洞复现】netgear路由器 boarddataww 存在RCE漏洞
免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…...
什么是原型链
1、原型链的本质 是一个链表,当使用一个构造函数时,就会返回一个实例,在这个实例上找某个属性未找到时,则会顺着proto属性指向它的原型,去原型上找,如果原型也没有的话,则会顺着原型的原型找&a…...

什么是虚拟线程?
1、典型回答 Java 中的虚拟线程,也叫做协程或“轻量级线程”,它诞生于JDK 19(预览 API),正式发布于 JDK 21,它是一种在 Java 虚拟机(JVM)层面实现的逻辑线程,不直接和操作系统的物理线程一一对应,因此它可…...
node.js是什么怎么用常用方法
什么是node.js Node.js是一个基于Chrome V8 JavaScript引擎的服务器端运行环境。它允许使用JavaScript来开发高性能的网络应用程序。Node.js采用事件驱动、非阻塞式I/O模型,使其能够处理大量并发请求而不会出现阻塞。 Node.js最初是由Ryan Dahl于2009年创建的&…...

pikachu靶场第十四关——XSS(跨站脚本)之js输出(附代码审计)
源代码: //这里讲输入动态的生成到了js中,形成xss //javascript里面是不会对tag和字符实体进行解释的,所以需要进行js转义//讲这个例子主要是为了让你明白,输出点在js中的xss问题,应该怎么修? //这里如果进行html的实体编码,虽然可以解决XSS的问题,但是实体编码后…...
AD实用设置教程
目录 一、“多边形敷铜” 设置 “最小间隔” 二、放置的 “过孔” 敷铜 “全连接”...
webpack为什么要使用loader,如何手写loader
webpack是一个打包工具,即webpack会将一切文件视为模块,但是webpack在打包的时候只是认识JS文件或者JSON文件,并不认识CSS文件,png图片等,如果想让webpack能够在打包的时候识别其他文件,就必须要使用loader…...
【银河商学】大蓝短视频学习04——找对标账号
为什么要找对标账号? 标准答案,少走弯路秒上热搜,快速起号预知变现,扬长避短 找什么样的对标账号? 成熟 粉丝量 > 50万持续更新,多年屹立不倒 举例账号 三百者也 模仿 二百者也 易做 简单可量产 有潜…...
Java练手游戏--俄罗斯方块
Java基础小练手游戏项目:俄罗斯方块简单版 使用Java实现俄罗斯方块大概思路: 界面设计: 使用Java Swing或JavaFX创建游戏窗口和用户界面。创建一个主窗口类(如GameFrame.java),负责设置窗口大小、标题等属…...

基础篇Redis
基础篇Redis 1.Redis简单介绍 Redis是一种键值型的NoSql数据库,这里有两个关键字: 键值型NoSql 其中键值型,是指Redis中存储的数据都是以key.value对的形式存储,而value的形式多种多样,可以是字符串.数值.甚至json…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...