Godot.NET C# 工程化开发(1):通用Nuget 导入+ 模板文件导出,包含随机数生成,日志管理,数据库连接等功能

前言

我们学编程,不要重复造工具。我之所以使用C# 开发Godot ,而不是Unity。很大的原因就是Godot.NET 支持Nuget的导入,因为Nuget是.NET Core 的第三方库。我也将Godot 的Visual Studio 项目的.NET 版本强制升级到的.NET Core 8.0版本,目前还没有任何问题。

Github项目地址,包含模板文件

Gclove2000/GodotNet_Csharp_IOC_SimpleTemplate

后期思考补充

我将项目分成3层,从上到下是

  • Godot:只是单纯挂载脚本
  • GD_Program:负责游戏逻辑
  • GD_Extension:通用的工具类

但是我后面想了一下,游戏逻辑也有部分是可以通用的,所以我感觉我的三层构造应该是存在过度封装了。两层封装说不定好一些。我后面打算先用两层封装好一点。等后面项目复杂度上来之后,再细分好了。

项目设置

编写失误

我写到后面的时候发现,Interfaces应当放在GD_Extension中。读者记得修改
在这里插入图片描述

环境

  • window 10
  • .net core 8.0
  • godot 4.2.1
  • visual studio 2022

visual studio 配置

  • GD_Extesion:Godot工具类,后面用于导出
    • Assests:资源文件夹
    • Utils:工具类
    • Interfaces:接口类
  • GD_Program:Godot运行逻辑
    • SceneModels:场景脚本实际运行类,IOC装配生成
    • Services:服务类
    • Program.cs:IOC容器位置
  • Godot:Godot引擎生成解决方案
    • Scene:挂载脚本,只用于建立脚本连接关系

在这里插入图片描述

详细的配置看我这篇文章

Godot 学习笔记(5):彻底的项目工程化,解决GodotProjectDir is null+工程化范例

Nuget 推荐

Nuget介绍
Newtonsoft.Json高性能Json序列化库
Bogus随机测试数据生成,比如随机数据,随机人民,地名,手机号,账号,密码
Microsoft.Extensions.DependencyInjection微软IOC框架,个人推荐
Autofac第三方IOC 框架,性能也不错
Nlog日志管理
FreeSql数据库ORM框架,个人推荐
SqlSugar数据库ORM框架,一般来说够用了,游戏开发也不是高频并发操作
MiniExcelExcel ORM框架,简易操作。建议使用CSV
Microsoft.AspNetCore.SignalR.Common微软开发即时通讯框架,用于解决多人联网
Grpc谷歌开发的即使通讯框架,用于解决多人联网

NewtonSoft 成功

在这里插入图片描述

//以匿名对象为例
GD.Print(JsonConvert.SerializeObject(new
{
    Name =  "小王",
    Age = "24"
}));

在这里插入图片描述

Bogus 成功

在这里插入图片描述

Github文档地址

Bugous Github文档地址

在这里插入图片描述

随机生成

//以随机数为例
var faker = new Faker();
for(var i =  0; i < 10; i++)
{
    GD.Print($"Bogus,int 0-10:[{faker.Random.Int(0, 10)}]");
}

在这里插入图片描述

构造器生成

public class MyStudent
{

    public int Id { get; set; }

    public string? Name { get; set; }

    public int Age { get; set; }


    /// <summary>
    /// 构建faker构造器
    /// </summary>
    public static Faker<MyStudent> Faker = new Faker<MyStudent>()
        .RuleFor(t=>t.Id,f=>f.IndexFaker)
        .RuleFor(t=>t.Name,f=>f.Name.FindName())
        .RuleFor(t=>t.Age,f=>f.Random.Int(10,30));

  
}
//以构造器为例
for (var i = 0; i < 10; i++)
{
    var stu = MyStudent.Faker.Generate();
    GD.Print($"Bogus:[{JsonConvert.SerializeObject(stu)}]");
}

在这里插入图片描述

构造器+接口(推荐)

个人建议,上个接口,更规范一点

public interface IModelFaker<T> where T : class
{

    public T FakerOne();

    public IEnumerable<T> FakeMany(int num);
}
public class MyStudent : IModelFaker<MyStudent>
{

    public int Id { get; set; }

    public string? Name { get; set; }

    public int Age { get; set; }


    /// <summary>
    /// 构建faker构造器
    /// </summary>
    private Faker<MyStudent> faker = new Faker<MyStudent>()
        .RuleFor(t => t.Id, f => f.IndexFaker)
        .RuleFor(t => t.Name, f => f.Name.FindName())
        .RuleFor(t => t.Age, f => f.Random.Int(10, 30));

    public MyStudent FakerOne()
    {
        return faker.Generate();
    }

    public IEnumerable<MyStudent> FakeMany(int num)
    {
        return faker.Generate(num);
    }
}

文件夹设置

因为后面会涉及到文件夹的设置问题,我这里简单说明一下
在这里插入图片描述
添加配置
在这里插入图片描述

Visual Studio C# 项目生成时复制项目资源目录到生成目录

Nlog 成功!

在这里插入图片描述

Nlog.config

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <targets>
    <!--将Debug导出为每小时一个-->
    <target name="debug"
            xsi:type="File"
            fileName="${basedir}/Logs/${date:format=yyyy}/${date:format=MM}/${date:format=dd}/${date:format=HH}.log"
            layout="${date:format=yyyy-MM-dd HH\:mm\:ss} [${uppercase:${level}}] : ${message}" />
    <!--将Error导出为每天一个,而且存放在一个Error文件夹中-->
    <target name="error"
            xsi:type="File"
            fileName="${basedir}/Logs/${date:format=yyyy}/${date:format=MM}/Error/${date:format=dd}.log"
            layout="${date:format=yyyy-MM-dd HH\:mm\:ss} [${uppercase:${level}}] : ${message}" />
  </targets>


  <rules>
    <logger name="*"
            minlevel="Debug"
            writeTo="debug" />

    <logger name="*"
        minlevel="Error"
        writeTo="error" />
  </rules>
</nlog>

NlogHelper.cs

Godot的输出比较特别,需要特别处理一下

public class NlogHelper
{
    private Logger logger;

    public NlogHelper()
    {
        var url = string.Format("{0}Assests/NLog.config", AppDomain.CurrentDomain.BaseDirectory.ToString());
        GD.Print($"Nlog加载完毕,url地址为[{url}]");
        LogManager.Configuration = new XmlLoggingConfiguration(url);

        logger = NLog.LogManager.GetCurrentClassLogger();
    }

    public void Debug(string msg)
    {
        GD.Print(msg);
        logger.Debug(msg);
    }

    public void Info(string msg)
    {
        GD.Print($"[info]:{msg}");
        logger.Info(msg);

    }

    public void Error(string msg)
    {
        GD.PrintErr(msg);
		GD.PushError(msg);
        logger.Error(msg);
    }

    public void Warning(string msg)
    {
    	GD.Print($"[warning]:{msg}");
        GD.PushWarning(msg);
        logger.Warn(msg);
    }
}

Nloghelper使用

在这里插入图片描述
在这里插入图片描述

测试

nlogHelper.Debug("Debug");
nlogHelper.Info("Info");
nlogHelper.Warning("Warning");
nlogHelper.Error("Error");

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

FreeSql 以Sqlite为例

FreeSql官方文档

FreeSql官方文档

在这里插入图片描述

sqlite3 安装,CodeFrist则不需要安装。我这里用CodeFrist

SQLite 安装

生成Sqlite数据库文件,这里我取名为sqliteDb.db

sqlite3 sqliteDb.db
.open sqliteDb.db

在这里插入图片描述

Nuget引入,FreeSql核心和FreeSql的Sqlite支持

在这里插入图片描述
在这里插入图片描述

FreeSqlHelper CodeFrist模式

C# FreeSql使用,基于Sqlite的DB Frist和Code First测试

T_ModelBase 数据库基类+Bogus随机生成
/// <summary>
/// 基类
/// </summary>
public abstract class T_ModelBase
{
    /// <summary>
    /// 主键自增
    /// </summary>
    [Column(IsPrimary =true,IsIdentity =true)]
    public long Id { get; set; }

    /// <summary>
    /// 创建时间
    /// </summary>
    public DateTime CreateTime { get; set; } = DateTime.Now;

    /// <summary>
    /// 更新时间
    /// </summary>
    public DateTime UpdateTime { get; set; } = DateTime.Now;
    /// <summary>
    /// 假删除
    /// </summary>
    public bool IsDelete { get; set; } = false;

    public DateTime DeleteTime { get; set; }
}
T_Person,数据库插入类,我习惯用T开头带表数据库实体
public class T_Person : T_ModelBase, IModelFaker<T_Person>
{

    public int Age { get; set; }
    public string Name { get; set; }

    private Faker<T_Person> faker = new Faker<T_Person>()
        .RuleFor(t => t.Id, f => f.IndexFaker)
        .RuleFor(t => t.CreateTime, f => f.Date.Between(new DateTime(2024, 1, 1), DateTime.Now))
        .RuleFor(t => t.Name, f => f.Name.FindName())
        .RuleFor(t => t.Age, f => f.Random.Int(10, 30));

    public IEnumerable<T_Person> FakeMany(int num)
    {
        return faker.Generate(num);
    }

    public T_Person FakerOne()
    {
        return faker.Generate();
    }
}

连接,插入,查询测试使用

var isConnect = freeSqlHelper.SqliteDb.Ado.ExecuteConnectTest(10);
GD.Print($"数据库连接状态:[{isConnect}]");

var insertLists = new T_Person().FakeMany(10);


var insertName = freeSqlHelper.SqliteDb.Insert(insertLists).ExecuteAffrows();
GD.Print($"数据库插入[{insertName}]行数据");

var selectLists = freeSqlHelper.SqliteDb.Queryable<T_Person>().OrderByDescending(t=>t.Id).Take(10).ToList();

foreach (var item in selectLists)
{
    GD.Print(JsonConvert.SerializeObject(item));
}

在这里插入图片描述
在这里插入图片描述

GD_Extension项目打包,用于复用

我写到后面的时候发现,Interfaces应当放在GD_Extension中。读者记得修改

在这里插入图片描述

Icon封面准备

【VisualStudio 】VisualStudio2022 项目模板

准备一个Godot Icon的图片,用于封面展示
在这里插入图片描述

visual studio 导出

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Github项目地址,包含模板文件

Gclove2000/GodotNet_Csharp_IOC_SimpleTemplate

总结

我这里就是简单引入了几个通用的Nuget,这个我后期是会日常去维护的。这个就是我们的脚手架了。而且我在GD_Extension中尽量少的使用Godot的Api。基本只使用了Godot Api 的输出语句。所以这个随着Godot 版本的更新,基本不需要大改。这个以后就是我们宝贵的Godot资源库了。

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值