Unity2D程序内容平铺生成

时间:2015-03-09 06:49:53

标签: c# unity3d procedural-generation

我尝试在级别加载后在屏幕上逐步生成图块。这个问题涉及使我的算法尽可能高效。

  • 之前我在做什么: 在Update()函数中( Update()函数的这一部分仅在游戏开始时调用ONCE ),我只是在屏幕上实例化了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;
                  }
              }
            }
&#13;
&#13;
&#13;

  • 我现在想要的是什么:我只想让玩家周围的牌块得到实例化,并且当玩家漫游时,其他牌块将在今后实例化,以便与游戏一样最初加载,并非所有图块同时加载(因此加载时间更短 - 更具动态性)。

&#13;
&#13;
    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;
            }
        }
    }
&#13;
&#13;
&#13;

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

优点:是的!只生成玩家周围的牌子+ 水平加载时间超快。 缺点:每个帧都会调用一个FOR循环(迭代次数达到12000!),因为游戏运行时每秒帧数(fps)非常低。

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

2 个答案:

答案 0 :(得分:0)

将此问题称为警察答案,但如果您的可图块纹理坐标与您的播放器位于相同的坐标处,则您无法将这些坐标和周围坐标转到您想要的任何距离,甚至不会迭代通过其余的?

例如:

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和统一库。

答案 1 :(得分:0)

实例化在Unity中需要很长时间。不是一直实例化瓷砖,而是创建object pool

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