Godot C# 如何实现高耗时脚本后台运行避免游戏卡顿
Godot C# 后台执行高耗时逻辑防卡顿解决方案
核心规则:
- Godot 所有节点实例化、属性修改、UI 相关操作必须在主线程执行,否则会触发线程安全报错
- 动态等待、CPU 密集型计算这类高耗时逻辑要放到后台线程执行,避免占用主线程帧时间导致卡顿
完整实现代码(Godot 4.x 适用)
把以下脚本挂到主场景的常驻节点上即可:
using Godot; using System.Threading.Tasks; public partial class AsyncLevelLoader : Node { // 替换成你自己的Tilemap场景预制体 [Export] public PackedScene TilemapScene; private TileMap _loadedTilemap; public override void _Ready() { // 启动异步任务,不阻塞主线程 _ = RunLevelLoadProcess(); } private async Task RunLevelLoadProcess() { // 第一步:后台动态休眠,时长由你的算法生成 int firstWaitTime = YourAlgorithmGenerateWaitTime(); // 替换成自定义时长生成逻辑 await Task.Delay(firstWaitTime); // 第二步:调度到主线程创建并展示Tilemap CallDeferred(MethodName.CreateTilemap); // 第三步:第二次动态休眠 int secondWaitTime = YourAlgorithmGenerateWaitTime(); // 替换成自定义时长生成逻辑 await Task.Delay(secondWaitTime); // 第四步:调度到主线程更新Tilemap的Sprite CallDeferred(MethodName.UpdateTilemapSprite); } private void CreateTilemap() { _loadedTilemap = TilemapScene.Instantiate<TileMap>(); // 替换成你要挂载的Level场景节点路径 GetNode<Node>("/root/Level").AddChild(_loadedTilemap); } private void UpdateTilemapSprite() { // 这里写你更新Tilemap Sprite的逻辑,示例: // _loadedTilemap.TileSet = YourNewTileSet; } // 替换成你自己的动态时长生成算法 private int YourAlgorithmGenerateWaitTime() { return 3000; // 示例返回3秒 } }
关键注意点
- 不要用
Thread.Sleep做等待,该方法会阻塞当前线程,如果在主线程调用会直接卡住游戏,后台线程调用也会占用线程资源,Task.Delay是异步无阻塞等待,更符合需求 - 如果你的高耗时逻辑是CPU密集型计算(比如地图生成、路径计算等),直接把计算逻辑放到
RunLevelLoadProcess的await之前执行即可,计算完成再把结果传给主线程更新节点 - Godot 3.x 版本可以把
CallDeferred替换成OS.InvokeOnMainThread来调度主线程操作,逻辑完全一致
内容的提问来源于stack exchange,提问作者33fred33
相关产品推荐
相关产品推荐

