Godot UI线程,Task异步和消息弹窗通知

前言

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

线程安全

Godot UI线程,Task异步和消息弹窗通知

Godot UI线程,Task异步和消息弹窗通知

全局消息IOC注入

我之前写过Godot 的IOC注入,这些都是CSDN时期的博客。但是后面CSDN的广告实在是太多了,我就转到博客园里面来了。

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

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

注意,我后面的都是基于我那个IOC框架来写的。

Godot UI线程,Task异步和消息弹窗通知

消息窗口搭建

如何修改Label样式可以看我上一篇文章

Godot Label样式 Textrue纹理,实现样式修改,背景填充

最简单的消息提示

Godot UI线程,Task异步和消息弹窗通知

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;          }     } }  

简单使用

Godot UI线程,Task异步和消息弹窗通知

虽然有点丑,但是能用

Godot UI线程,Task异步和消息弹窗通知

仿Element UI

ElementUI 效果

Godot UI线程,Task异步和消息弹窗通知

简单的Label样式

Godot UI线程,Task异步和消息弹窗通知

简单的画一下,我就不给具体的参数了,大家点一下就知道了
Godot UI线程,Task异步和消息弹窗通知

如何快速加载多个相同节点

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

Godot UI线程,Task异步和消息弹窗通知

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打印信息");          }     } }  

Godot UI线程,Task异步和消息弹窗通知

修改一下,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();          }     } }  

Godot UI线程,Task异步和消息弹窗通知

Godot UI线程,Task异步和消息弹窗通知

总结

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

发表评论

评论已关闭。

相关文章