【问题标题】:c# Unity 3D - 1000 cube instantiation scriptc# Unity 3D - 1000立方体实例化脚本
【发布时间】:2014-09-01 19:50:16
【问题描述】:

为什么下面的脚本会使 Unity 运行非常缓慢且无法使用?

public Transform brick;
public int gridWidth=10;
public int gridDepth=10;
public int gridHeight=10;
void Start() {
    for (int y = 0; y < gridHeight; y=y+2) 
    {
        for (int z = 0; z < gridDepth; z=z+2) 
        {
            for (int x = 0; x < gridWidth; x=x+2) 
            {
                Instantiate (brick, new Vector3 (x, y, z), Quaternion.identity);
            }
        }
    }
}

在变换中,我放置了一个基本上是刚体立方体的预制件。

如果我删除包含 z int 的 For-Loop,它运行正常(因此 10x10 网格 / 100 个立方体就可以了)。但是,在 z int 循环到位后,它会中断(10x10x10 网格/1000 个立方体)

我怎样才能在不使 Unity 无法使用的情况下使其真正有效地工作?

【问题讨论】:

  • 实例化 1000 个游戏对象会显着减慢速度,问题是它只慢了一秒钟(实例化)还是之后的任何时间? (渲染太多)
  • 一直慢。我注意到我没有重新编译我的代码,尽管这在 Unity 中意味着 100x100x100 网格卡住了,但是,在重新编译 10x10x10 网格之后工作正常。 50x50x50 一开始很慢,但之后就好了....75x75x75 让一切都停止了。在 75x75x75 时,我关闭了渲染,但它仍然很慢......所以假设它可能是别的东西,但也就是说,75x75x75 是 400,000 多个对象,所以我想它会很慢!
  • 请记住,它在您的特定系统上运行得好或坏,这可能比其他用户运行您的游戏的(最低要求)系统快得多/慢得多。

标签: c# unity3d


【解决方案1】:

我认为最好的解决方案是使用 Oclussion Culling。这是一个“不渲染”活动摄像头不可见的对象的系统。

这里是关于它的 Unity 信息。

Oclussion Culling at Unity Manual (PRO ONLY)

但是,此功能仅适用于 Unity Pro 用户,如果您有免费版本,您应该寻找一个像这样的自定义 Oclussion Culling 脚本:

Oclussion Culling

请记住,这只是我在网上找到的一个脚本,可能还有更好的脚本。无论如何,用该脚本的创建者的话来说:

在我的测试场景中,该脚本将绘图调用/tris/verts 减少了 >80%,渲染器循环速度加快了 >85%,代价是帧速率降低了 12%(从 75 到 66 FPS)。虽然这对于因绘制调用而陷入困境的场景非常有用,但我对任何可以减少脚本开销以使其适合一般使用的反馈感兴趣。

可能值得一试。

【讨论】:

  • Unity Pro 的遮挡剔除旨在预先计算(在“烘焙”步骤中)。它不适用于程序生成的场景。
【解决方案2】:

我想你可以从预制件中移除刚体;只留下盒子对撞机并使其成为static。首先,这将允许 Unity 有效地batch draw calls。 PhysX 将能够利用broad phase 并提高碰撞检测的性能。

【讨论】:

  • afaik 批量绘图仅在 Unity Pro 中可用
  • @LearnCocos2D,是的,没错
【解决方案3】:

我可能对这个示例看得太远了,但它似乎就像您在尝试模拟“块状”渲染的体素。

虽然对于非常个简单的立方体示例可能有效,但您可以实例化、渲染和让物理系统保持跟踪的数量存在一定的限制,即使使用剔除也是如此。

您应该使用一种方法来渲染体素,该方法会生成具有预定义大小的区域(通常称为“块”)的奇异网格。这允许对每种材料进行一次绘制调用,固有的剔除比任何可以自动生成的东西都要快(因为它是生成网格的“免费”副作用),消除了多个碰撞器的开销,并且 更多

这是一项听起来比实际更艰巨的任务。有numerous tutorials 可以满足您的需求。我还发现thesethreesources写得特别好。

我个人不建议尝试单独使用遮挡剔除和批处理来使用您当前的方法,因为它仍然是一种非常低效的方法。另请注意,Unity Pro 的遮挡剔除设计为预先计算,因此不适用于您的情况。

【讨论】:

    【解决方案4】:

    生成一个立方体。

    public Transform cubePrefab;
    
    public int rows,columns,depth;
    public float padding;
    
    // Use this for initialization
    void Start () {
        for(int i =0; i < depth; i ++) {
            for(int j=0;j< columns;j++){
                for(int k=0; k < rows;k++){
                    Vector3 pos = new Vector3(k * padding,j * padding,i * padding);
                    //print(pos);
                    Transform foo = (Transform) Instantiate(cubePrefab,pos,Quaternion.identity);
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-11
      • 1970-01-01
      • 2017-11-13
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-01
      相关资源
      最近更新 更多