目录
前言
最近我在研究Godot的全局消息,然后发现Godot 也是有UI线程限制的,只能在主线程的子线程里面修改UI。
线程安全


全局消息IOC注入
我之前写过Godot 的IOC注入,这些都是CSDN时期的博客。但是后面CSDN的广告实在是太多了,我就转到博客园里面来了。
Godot.NET C# 工程化开发(1):通用Nuget 导入+ 模板文件导出,包含随机数生成,日志管理,数据库连接等功能
注意,我后面的都是基于我那个IOC框架来写的。

消息窗口搭建
如何修改Label样式可以看我上一篇文章
最简单的消息提示

using Godot; using Godot_UI_Test.Utils; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; namespace Godot_UI_Test.SceneModels { public class MessageSceneModel : ISceneModel { private PrintHelper printHelper; private Godot.Label title; private Godot.Label content; private VBoxContainer container; private ColorRect colorRect; public MessageSceneModel(PrintHelper printHelper) { this.printHelper = printHelper; printHelper.SetTitle(nameof(MessageSceneModel)); } public override void Process(double delta) { //throw new NotImplementedException(); } public override void Ready() { printHelper.Debug("加载完成"); colorRect = Scene.GetNode<ColorRect>("ColorRect"); container = colorRect.GetNode<VBoxContainer>("VBoxContainer"); title = container.GetNode<Godot.Label>("Title"); content = container.GetNode<Godot.Label>("Content"); //同步容器大小 container.Size = colorRect.Size; printHelper.Debug(JsonConvert.SerializeObject(title.Size)); //默认设置为不可见 Scene.Visible = false; //throw new NotImplementedException(); } /// <summary> /// 弹窗延迟退出 /// </summary> /// <param name="message"></param> /// <returns></returns> public async Task ShowInfo(string message) { Scene.Visible = true; printHelper.Debug("Info打印信息"); printHelper.Debug(message); await Task.Delay(3000); Scene.Visible = false; } } }
简单使用

虽然有点丑,但是能用

仿Element UI
ElementUI 效果

简单的Label样式

简单的画一下,我就不给具体的参数了,大家点一下就知道了

如何快速加载多个相同节点
如果我们把这个作为场景,又没有那么的复杂。如果用代码生成,写起来很麻烦,也不直观。最好的方法就是复制节点添加。

using Godot; using Godot_UI_Test.Utils; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; namespace Godot_UI_Test.SceneModels { public class MessageSceneModel : ISceneModel { private PrintHelper printHelper; private VBoxContainer vBoxContainer; private AssetsHelper assetsHelper; private Godot.Label label; public MessageSceneModel(PrintHelper printHelper, AssetsHelper assetsHelper) { this.printHelper = printHelper; printHelper.SetTitle(nameof(MessageSceneModel)); this.assetsHelper = assetsHelper; } public override void Process(double delta) { //throw new NotImplementedException(); } public override void Ready() { printHelper.Debug("加载完成"); vBoxContainer = Scene.GetNode<VBoxContainer>("VBoxContainer"); label = Scene.GetNode<Godot.Label>("Label"); //将vBoxContainer居中,GodotProjectSetting是自己设置的 vBoxContainer.Position = new Vector2(GodotProjectSetting.Width/4, 10); //添加label的靠别,不能直接添加label,因为label已经拥有了父节点 var newLabel = label.Duplicate() as Godot.Label; //显示Label newLabel.Visible =true; vBoxContainer.AddChild(newLabel.Duplicate()); vBoxContainer.AddChild(newLabel.Duplicate()); vBoxContainer.AddChild(newLabel.Duplicate()); //CreateText("te321"); //CreateText("te321 3213 321 3434 4 2 41321 st1 te321 3213 321 3434 4 2 41321 st1 te321 3213 321 3434 4 2 41321 st1"); printHelper.Debug(JsonConvert.SerializeObject(vBoxContainer.Position)); printHelper.Debug(JsonConvert.SerializeObject(vBoxContainer.GetWindow().Position)); //Scene.Visible = false; //throw new NotImplementedException(); } private void CreateText(string text) { var res = new Godot.Label(); res.AddThemeStyleboxOverride("normal", assetsHelper.MessageItemStyle); res.AutowrapMode = TextServer.AutowrapMode.WordSmart; res.HorizontalAlignment = HorizontalAlignment.Center; res.Text = text; res.CustomMinimumSize = new Vector2(200, 0); label = res; vBoxContainer.AddChild(res); } /// <summary> /// 延迟打印 /// </summary> /// <param name="message"></param> /// <returns></returns> public async Task ShowInfo(string message) { printHelper.Debug("Info打印信息"); } } }

修改一下,IOC按钮事件注册
using Godot; using Godot_UI_Test.Utils; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; namespace Godot_UI_Test.SceneModels { public class MessageSceneModel : ISceneModel { private PrintHelper printHelper; private VBoxContainer vBoxContainer; private AssetsHelper assetsHelper; private Godot.Label label; public MessageSceneModel(PrintHelper printHelper, AssetsHelper assetsHelper) { this.printHelper = printHelper; printHelper.SetTitle(nameof(MessageSceneModel)); this.assetsHelper = assetsHelper; } public override void Process(double delta) { //throw new NotImplementedException(); } public override void Ready() { printHelper.Debug("加载完成"); vBoxContainer = Scene.GetNode<VBoxContainer>("VBoxContainer"); label = Scene.GetNode<Godot.Label>("Label"); //将vBoxContainer居中,GodotProjectSetting是自己设置的 vBoxContainer.Position = new Vector2(GodotProjectSetting.Width/4, 10); //CreateText("te321 3213 321 3434 4 2 41321 st1 te321 3213 321 3434 4 2 41321 st1 te321 3213 321 3434 4 2 41321 st1"); printHelper.Debug(JsonConvert.SerializeObject(vBoxContainer.Position)); printHelper.Debug(JsonConvert.SerializeObject(vBoxContainer.GetWindow().Position)); //Scene.Visible = false; //throw new NotImplementedException(); } /// <summary> /// 挂载Label /// </summary> /// <param name="text"></param> private Godot.Label CreateText(string text) { var newLabel = label.Duplicate() as Godot.Label; newLabel.Text = text; newLabel.Visible=true; vBoxContainer.AddChild(newLabel); return newLabel; } /// <summary> /// 延迟打印 /// </summary> /// <param name="message"></param> /// <returns></returns> public async Task ShowInfo(string message) { printHelper.Debug("Info打印信息"); var newLabel = CreateText(message); await Task.Delay(3 * 1000); newLabel.Free(); } } }


总结
我只是很潦草的实现了消息弹窗这个功能,还没加动画效果。不过这个确实让我学到了很多,尤其是节点挂载这个事情。