【问题标题】:Unity2D Procedural Content Tile GenerationUnity2D 程序内容图块生成
【发布时间】:2015-03-09 06:49:53
【问题描述】:

我正在尝试在关卡加载后立即在屏幕上生成图块。这个问题与使我的算法尽可能高效有关。

  • 我之前在做什么: 在 Update() 函数中(Update() 函数的这一部分仅在游戏开始时调用一次s),我只是在屏幕上将图块实例化 12,000 次以创建整个地图游戏。在下面的代码中,x[i] 和 y[i] 是我在另一个函数中递增的网格坐标值。

缺点:关卡加载时间较长。 优点:加载关卡后,fps 保持一致且较高。

            void Update()
            {
              if (loadThisSectionOnce = false)
              {
                  loadThisSectionOnce = true;
                  for (int i = 0; i <= 12000; i++)
                  {
                    tiles[i] = Instantiate(tile, new Vector3(x[i], y[i], transform.rotation) as GameObject;
                  }
              }
            }
  • 我现在要做的事情:我只想让玩家周围的图块被实例化,并且随着玩家四处游走,其他图块将被实例化,以便在游戏最初加载时,并非所有图块都同时加载(因此加载时间更短 - 更动态)。

    void Update()
    {
        var distance = Vector2.Distance(new Vector2(x[i], y[i], PlayerPosition);
        if (distance < 20.0F)
        {                           
            for (int i = 0; i <= 12000; i++)
            {                                        
                tiles[i] = Instantiate(tile, new Vector3(x[i], y[i], transform.rotation) as GameObject;
            }
        }
    }

注意:这次没有布尔变量来确保 Update() 函数的这一部分只被调用一次,但它被每帧调用一次。

优点:耶!仅生成玩家周围的图块 + 关卡加载时间非常快。 缺点:每帧都会调用一个 FOR 循环(迭代高达 12000 次!),因此游戏运行时每秒帧数 (fps) 非常低。

我需要什么?:如何让我的第二次尝试更有效率?有什么办法吗?感谢您的帮助!

【问题讨论】:

    标签: c# unity3d procedural-generation


    【解决方案1】:

    将此称为逃避答案,但如果您的可平铺纹理坐标与您的播放器的坐标开始于相同的坐标,那么您就不能将这些坐标和周围坐标转到您想要的任何距离,甚至不遍历休息吗?

    例如:

    var distance = Vector2.Distance(new Vector2(x[world_coordinate], y[world_coordinate], PlayerPosition);
    for (int i = int(distance-20); i>= int(distance-20) && i<=(distance+20) i++):
        tiles[i] = Instantiate(tile, new Vector3(x[i], y[i], transform.rotation) as GameObject;
            }
    

    我不确定你是如何在数组中保存图块的,所以我不确定我写的代码是否合适,但我希望你能明白。在玩家周围的给定半径内找到您的瓦片阵列的范围,在本例中为 20 个单位,然后仅遍历这些瓦片并渲染它们。对不起,如果我的代码不正确。我既不精通javascript也不精通统一库。

    【讨论】:

      【解决方案2】:

      在 Unity 中实例化需要很长时间。与其一直实例化图块,不如创建一个object pool

      • 确定角色周围所需的瓷砖数量。
      • 在开始时创建此数量的图块。
      • 记录角色移动了多长时间。您可以在角色控制器中轻松地将其作为具有公共 getter 的属性(如里程表)来执行,因为它无论如何都会执行所有必要的计算。如果自上次检查后角色没有移动足够长的距离,您的图块管理器无需进行任何检查。
      • 如果角色周围需要新的瓷砖,请将它们从池中取出并放置在那里。
      • 如果角色不再需要瓷砖,请将它们放回池中。而现在,这通常是棘手的部分——因为在使用对象池之前,许多附加到世界图块的脚本可能依赖于对象通常的 Unity 生命周期来实现其逻辑。但是您必须以这样的方式重写它们,以便当您将对象返回到池中时,它们会完全重置其状态。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-09
        • 2016-12-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多