首页 > 其他分享 >Godot UI线程,Task异步和消息弹窗通知

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

时间:2024-04-12 17:33:05浏览次数:26  
标签:Godot Task printHelper System Label vBoxContainer 线程 using

目录

前言

最近我在研究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>("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();

        }
    }
}

总结

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

标签:Godot,Task,printHelper,System,Label,vBoxContainer,线程,using
From: https://www.cnblogs.com/gclove2000/p/18130874

相关文章

  • godot导出可执行程序
    godot导出可执行程序为什么要导出将项目到处为可执行程序,用于向别人分享自己的游戏支持的平台目前godot支持导出到常见平台:Linux/x11WindowsMacOSAndroidiosweb步骤导出模板首先下载并导入官方提供的导出模板​,详细信息参考官方文档注意:导出模板​与godot版本存......
  • Csharp线程
    CSharpe线程 目录CSharpe线程C#如何操作线程Thread1.Thread如何开启一个线程呢?2.Thread中常见的API3.thread的扩展封装threadpool一、.NETFramework2.0时代:出现了一个线程池ThreadPool二、线程池如何申请一个线程呢?三、线程等待四、线程池如何控制线......
  • C#开发AutoCAD插件多线程问题2种解决方法
    后台线程不允许操作界面,解决方案委托主线程来操作,在winform中用控件的Invoke方法。CAD插件里,可以用下面两种方法来实现: 方法一(推荐)://主线程:System.Threading.SynchronizationContextctx=null;ctx=Autodesk.AutoCAD.Runtime.SynchronizationContext.Current;if(ctx==......
  • Godot Label样式 Textrue纹理,实现样式修改,背景填充
    目录前言运行环境新建项目Style样式讲解StyleBoxEmpty:普通样式StyleBoxTexture:字体样式StyleBoxFlat:填充样式StyleBoxLine:行样式总结前言在Godot中,直接的BackGroud背景颜色这个属性。Godot中使用的是Textrue纹理这个属性来表示文本的信息运行环境Godot4.2.1Windows10......
  • Flink源码学习(4) TaskManager从节点启动分析
    taskManager是flink的worker节点,负责slot的资源管理和task执行一个taskManager就是一台服务器的抽象TaskManager基本资源单位是slot,一个作业的task会部署在一个TM的slot上运行,TM会负责维护本地的slot资源列表,并与Master和JobManager进行通信启动主类:TaskManagerRunnerTaskMan......
  • 多线程-多个子线程执行结果插入List集合
    业务场景:将多个子线程的执行结果存入List,但是总会出现List集合的长度小于子线程的执行数的情况1、错误示例(多个线程同时操作同一个List对象,List是线程不安全)packageunitTest;importorg.assertj.core.util.Lists;importjava.util.List;importjava.util.concurrent.Coun......
  • ThreadPoolExecutor线程池解析
    ThreadPoolExecutor线程池解析一、ThreadPoolExecutor常见参数jdk中Executors提供了几种常用的线程池,底层都是ThreadPoolExecutor。publicThreadPoolExecutor(intcorePoolSize,//核心线程数intmaximumPoolSize,//最大线程数......
  • 记录一个springcloud-task-core.jar导致CommandLineRunner @order排序失效的问题
    项目中编写了几个CommandLineRunner,并且加上了spring的@order注解,期望在启动时会按顺序执行(从order的value小到大执行),但是实际使用发现排序不生效于是进行debug,CommandLineRunner类的排序是在SpringApplication.class的callRunners方法privatevoidcallRunners(ApplicationCon......
  • 多线程知识点
     1.多线程基本概念1)概念:多线程简单来说是一个程序具备同时执行多个功能的能力。在多线程中,这些功能被称为线程,每个线程都有自己的执行路径,它们可以并行(xíng)运行,同时共享程序的资源与内存。而在传统的单线程程序中,代码会顺序执行,一个任务完成后才会开始下一个任......
  • 单线程Reactor模型
    1.如何理解reactorreactor是一种设计模式。用于处理事件驱动的系统。reactor模式,主要有两个组件:reactor反应器:负责监听所有事件,当事件发生时,调用相应的处理程序。reactor本身时一个事件循环,负责处理I/O事件。handler处理程序:处理特点类型的事件。当reactor接收......