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


    前言

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

    线程安全

    全局消息IOC注入

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

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

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

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

    消息窗口搭建

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

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

    最简单的消息提示

    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");
    
                container = colorRect.GetNode("VBoxContainer");
                title = container.GetNode("Title");
                content = container.GetNode("Content");
                //同步容器大小
                container.Size = colorRect.Size;
                printHelper.Debug(JsonConvert.SerializeObject(title.Size));
    
                //默认设置为不可见
                Scene.Visible = false;
                //throw new NotImplementedException();
            }
    
    
            /// 
            /// 弹窗延迟退出
            /// 
            /// 
            /// 
            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");
                label = Scene.GetNode("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);
            }
    
    
            /// 
            /// 延迟打印
            /// 
            /// 
            /// 
            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");
                label = Scene.GetNode("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();
            }
    
            /// 
            /// 挂载Label
            /// 
            /// 
            private Godot.Label CreateText(string text)
            {
                var newLabel = label.Duplicate() as Godot.Label;
                newLabel.Text = text;
                newLabel.Visible=true;
                vBoxContainer.AddChild(newLabel);
                return newLabel;
            }
    
    
            /// 
            /// 延迟打印
            /// 
            /// 
            /// 
            public async Task ShowInfo(string message)
            {
                printHelper.Debug("Info打印信息");
    
                var newLabel =  CreateText(message);
                await Task.Delay(3 * 1000);
                newLabel.Free();
    
            }
        }
    }
    
    

    总结

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

  • 相关阅读:
    Java 入门练习(11 - 15)
    Linux系统目录结构
    gateway动态网关/通用网关配置
    1222. 可以攻击国王的皇后-力扣双百代码
    最优化问题及线性规划问题
    花青素染料Cy3NS NHS酯,Cy3NS 琥珀酰亚胺活化酯物理化学光谱特性及参数解析,激发波长(nm):554发射波长(nm):568
    Go 基本数据类型和 string 类型介绍
    经典算法之快速排序(QuickSort)
    java内部类详解
    教你在批量将视频逆时针旋转90度的同时添加马赛克
  • 原文地址:https://www.cnblogs.com/gclove2000/p/18130874