Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 装载块的地雷船速度_C#_Multithreading_Unity3d_Minecraft_Procedural Generation - Fatal编程技术网

C# 装载块的地雷船速度

C# 装载块的地雷船速度,c#,multithreading,unity3d,minecraft,procedural-generation,C#,Multithreading,Unity3d,Minecraft,Procedural Generation,我正在开发一个体素地形生成器。一切都很好,我有生物群落,街区等等 让我高兴的是我在unity中的项目速度。如果我在主线程上运行所有程序,我只能加载和渲染1到2个块,而不会降低到70fps以下。这主要是因为块中的每个块都必须检查它们的邻居,以定义它们的块侧可见性。一个区块有6个邻居,一个区块有16个区块。这使得很多检查非常迅速 我读过minecraft是单线程的,但我很难相信,因为它的块加载速度非常快,而且没有fps下降 我的解决方案是在另一个线程上运行块的邻居的检查。这将大大提高我的fps和区块

我正在开发一个体素地形生成器。一切都很好,我有生物群落,街区等等

让我高兴的是我在unity中的项目速度。如果我在主线程上运行所有程序,我只能加载和渲染1到2个块,而不会降低到70fps以下。这主要是因为块中的每个块都必须检查它们的邻居,以定义它们的块侧可见性。一个区块有6个邻居,一个区块有16个区块。这使得很多检查非常迅速

我读过minecraft是单线程的,但我很难相信,因为它的块加载速度非常快,而且没有fps下降

我的解决方案是在另一个线程上运行块的邻居的检查。这将大大提高我的fps和区块加载速度。这是正确的方法吗?我不想使用线程,因为我的代码没有经过优化。这就像把灰尘推到地毯下面一样

谢谢你的阅读

编辑:检查邻居的代码

//Block provides its mesh information
//Check for solidity of adjacent blocks
public virtual MeshData CreateBlockData(Chunk chunk, int x, int y, int z, MeshData meshData)
{
    //Set this to true to turn on collider creation shaped like the chunks
    meshData.useRenderDataForCol = true;

    if (!chunk.GetBlock(x, y + 1, z).IsSolid(Direction.down))
    {
        meshData = FaceDataUp(chunk, x, y, z, meshData);
    }

    if (!chunk.GetBlock(x, y - 1, z).IsSolid(Direction.up))
    {
        meshData = FaceDataDown(chunk, x, y, z, meshData);
    }

    if (!chunk.GetBlock(x, y, z + 1).IsSolid(Direction.south))
    {
        meshData = FaceDataNorth(chunk, x, y, z, meshData);
    }

    if (!chunk.GetBlock(x, y, z - 1).IsSolid(Direction.north))
    {
        meshData = FaceDataSouth(chunk, x, y, z, meshData);
    }

    if (!chunk.GetBlock(x + 1, y, z).IsSolid(Direction.west))
    {
        meshData = FaceDataEast(chunk, x, y, z, meshData);
    }

    if (!chunk.GetBlock(x - 1, y, z).IsSolid(Direction.east))
    {
        meshData = FaceDataWest(chunk, x, y, z, meshData);
    }

    return meshData;
}


//The center of block is the origin
protected virtual MeshData FaceDataUp(Chunk chunk, int x, int y, int z, MeshData meshData)
{
    meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z + 0.5f));
    meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f));
    meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z - 0.5f));
    meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z - 0.5f));
    meshData.AddQuadTriangles();
    //Adds UVs range (0 to 3) to uv list
    meshData.uv.AddRange(FaceUVs(Direction.up));
    return meshData;
}
因此,每个16x16x16块的块都有4096个块来运行此函数

创建块的代码只是一个包含以下内容的三重for循环:

static void GeneratePlainBiome(Chunk chunk, int x, int y, int z, FastNoise noise)
{
    int stoneHeight = GetNoise2D(noise, x, z, 0, 50);
    int chunkX = (int)chunk.transform.position.x;
    int chunkY = (int)chunk.transform.position.y;
    int chunkZ = (int)chunk.transform.position.z;

    if(y == 0)
    {
        chunk.SetBlock(x - chunkX, y - chunkY, z - chunkZ, new BlockSnow());
    }
    else if(stoneHeight > y)
    {
        chunk.SetBlock(x - chunkX, y - chunkY, z - chunkZ, new BlockEarth());
    }
    else if(stoneHeight == y)
    {
        chunk.SetBlock(x - chunkX, y - chunkY, z - chunkZ, new BlockGrass());
    }
    else
    {
        chunk.SetBlock(x - chunkX, y - chunkY, z - chunkZ, new BlockAir());
    }
}
填充块后,使用以下函数渲染网格:

//Sends the calculated mesh information to the mesh and collision components
void RenderMesh(MeshData meshData)
{
    //Mesh construction
    filter.mesh.Clear();
    filter.mesh.vertices = meshData.vertices.ToArray();
    filter.mesh.triangles = meshData.triangles.ToArray();

    //Uv mapping
    filter.mesh.uv = meshData.uv.ToArray();
    filter.mesh.RecalculateNormals();

    //Collision component creation
    coll.sharedMesh = null;
    Mesh meshColl = new Mesh();
    meshColl.vertices = meshData.colVertices.ToArray();
    meshColl.triangles = meshData.colTriangles.ToArray();
    meshColl.RecalculateNormals();

    coll.sharedMesh = meshColl;
}
为了继续,我正在检查块的16x16x16块,以了解如何基于邻居渲染块网格。完成该函数后,我可以选择渲染块。我这样做了,假设玩家周围有16x16x16块。(即使我一帧做一块,我也会得到相当糟糕的fps下降。)

编辑2:

对于chunk脚本中的chunk.SetBlock()和chunk.GetBlock():

public void SetBlock(int x, int y, int z, Block block)
{
    if (InRange(x) && InRange(y) && InRange(z))
    {
        blocks[x, y, z] = block;
    }
    else
    {
        LoadBiomes.SetBlock((int)transform.position.x + x, (int)transform.position.y + y, (int)transform.position.z + z, block);
    }
}


public Block GetBlock(int x, int y, int z)
{
    if(InRange(x) && InRange(y) && InRange(z))
    {
        Block block = blocks[x, y, z];

        return block;
    }
    else
    {
        //return new BlockAir();

        int xPos = (int)transform.position.x + x;
        int yPos = (int)transform.position.y + y;
        int zPos = (int)transform.position.z + z;
        Block blockToReturn = LoadBiomes.GetBlock(xPos,yPos,zPos); 

        return blockToReturn;
    }

}

//This work since the values passed to the function are block position - chunk position
public static bool InRange(int index)
{
    if (index < 0 || index >= CHUNK_SIZE)
        return false;

    return true;
}
以及来自探查器的图像(不确定这是否是要求的)


我不是专家,但据我所知,unity 3d使用多边形,不是体素引擎。体素引擎是不同的

这种差异的直接后果是多边形可以 有效地表示具有大量空或空数据的简单3D结构 均匀填充空间,而体素擅长表示 非均匀填充的规则采样空间

有关技术详细信息,请参阅:


一些体素引擎所做的是使用大数组,然后使用它们来确定哪些在视野中,哪些不在视野中。这与从地震开始的经典3d多边形做事方式大不相同。著名的体素游戏包括科曼奇系列,弃儿。。。现在是Minecraft。

您是在计算所有~loaded block~的块侧可见性,还是只计算当前视野中的块侧可见性?我在播放器周围有一个块队列(比如8x8)在渲染块网格之前,我会检查每个块的每个块@FiringSquadWitness块的可见性。你在调试或发布版本中衡量了你的性能吗?我进行构建不是为了让stats and profiler选项卡可用@User743414我不认为如果我有一个发布版本,它会有任何帮助。也许我会掌握一些fps,但这不是重点。虽然,Minecraft是最有名的体素游戏,但它的性能非常差,如果不是最差的话。Unity3d为Minecraft clone提供了足够的电力(实际上有人在youtube上用Unity3d在几个晚上对Minecraft进行了编码)。我只是在看一些其他的多人体素项目,看看能用更少的资源消耗做些什么。我不知道有关Minecraft如何工作的任何细节,我想在2019年,由于硬件加速,你可以用你的方式用多边形做体素引擎。谢谢你的回答,我不认为这是一个与团结有关的问题。我想我只是有太多的迭代,你可以在我所做的编辑中看到。此外,我正在渲染播放器旁边的内容。并不是我一次渲染太多,只是我需要很多次迭代,我不知道如何减少它们。有趣的是,我听到每个人都说minecraft的性能很差,但我找不到一个更好或接近其性能的教程@eocron
//Every face is solid for a cube
public virtual bool IsSolid(Direction direction)
{
    switch (direction)
    {
        case Direction.north:
            return true;
        case Direction.east:
            return true;
        case Direction.south:
            return true;
        case Direction.west:
            return true;
        case Direction.up:
            return true;
        case Direction.down:
            return true;
    }
    return false;
}