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

news/发布时间2024/5/16 22:35:45

目录
  • 前言
  • 线程安全
  • 全局消息IOC注入
  • 消息窗口搭建
    • 最简单的消息提示
      • 简单使用
    • 仿Element UI
      • ElementUI 效果
      • 简单的Label样式
      • 如何快速加载多个相同节点
      • 修改一下,IOC按钮事件注册
  • 总结

前言

最近我在研究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;//显示LabelnewLabel.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();}}
}

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/48545072.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

java中cron表达式 每10分钟执行一次

在Java中,可以使用Quartz框架来定义和调度任务,包括使用Cron表达式来定义任务的执行时间。下面是一个使用Quartz框架实现每10分钟执行一次任务的示例: 添加Quartz依赖 在Maven项目中,添加以下依赖到pom.xml文件中: <dependency><groupId>org.quartz-scheduler…

P4568 [JLOI2011] 飞行路线

分层图的板子题 代码#include <bits/stdc++.h> #define R(x) x=read() #define fi first #define se second using namespace std;typedef pair<int,int> PII; const int N = 1e4, M = 5e5;inline int read() {int x = 0, f = 1;char ch = getchar();while(ch <…

MyBatis动态SQL

MyBatis动态SQL 动态SQL简介 动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦…

Java 中文官方教程 2022 版(十四)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html设置包版本信息原文:docs.oracle.com/javase/tutorial/deployment/jar/packageman.html您可能需要在 JAR 文件的 MANIFEST.MF 中包含包版本信息。您可以使用 MANIFEST.MF 中的以下头部提供此信息: 清单中的头部头部…

Java 中文官方教程 2022 版(二)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html运算符原文:docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html现在你已经学会了如何声明和初始化变量,你可能想知道如何对其进行操作。学习 Java 编程语言的运算符是一个很好的开始。运算符是执行…

狂神说Java Web学习笔记_Session

原理图服务器会给每一个用户(浏览器)创建一个session对象 一个session独占一个浏览器,主要浏览器没有关,这个session就存在 登录之后,整个网站都可以访问 常用场景 保存一个用户的登录信息 在整个网站中经常会使用到的数据 常用的session方法 //得到Session HttpSession s…