我一直在尝试为我在 Godot 中制作的游戏编写一个块加载系统。为此,我想使用线程一次加载多个块。
int threadsToUtilise = 7;
Thread[] threads; // array to store threads
ArrayMesh[] threadResults; // array to save meshes returned by WorldLoader.GetChunk();
Vector3I[] chunkIDsLoading; // array to save position (Vector3I) of the chunk thread[i] is loading; serves to later position the mesh at the right position
// the arrays are initialised with a size of threadsToUtilise (7)
List<Vector3I> chunksToLoad = new(); // List to store positions of all chunks that still need to be loaded in
public override void _Process(double delta) // method runs every frame
{
for (var i = 0; i < threadsToUtilize; i++)
{
if (threads[i] == null){
if (chunksToLoad.Count == 0) break;
threads[i] = new Thread(() => { threadResults[i] = WorldLoader.GetChunk(chunksToLoad[0], false); });
threads[i].Start();
chunkIDsLoading[i] = chunksToLoad[0];
chunksToLoad.RemoveAt(0);
}
else if (!threads[i].IsAlive) {
if (threadResults[i] != null) {
// implement some stuff
}
threads[i] = null;
threadResults[i] = null;
chunkIDsLoading[i] = Vector3I.Zero;
}
}
}
通常我想加载一个块,并在创建网格后立即实现它。它或多或少有效,但有两个主要问题:
这看起来像是一个“捕获”问题;尝试:
var idx = i;
var chunk = chunksToLoad[0];
threads[i] = new Thread(() => { threadResults[idx] = WorldLoader.GetChunk(chunk, false); });
它创建我们在 lambda 中“捕获”的值的快照。