【问题标题】:Controlling the dynamic terrain creation in Unity在 Unity 中控制动态地形创建
【发布时间】:2018-04-18 16:41:19
【问题描述】:

我正在创建一个玩家总是沿着路径向前移动的游戏。地形由段组成(总是有 9 个),我有创建相对于另一个段的段的脚本。

现在我想创建一个脚本来控制这些段的创建和销毁。我的想法是创建具有 3 行和 3 列的数组,因为总是有 9 个段,所以数组的每个元素都将包含另一个段。所以脚本会这样工作:

  1. 一开始它将创建九个段,玩家将位于中心。

  2. 每帧它都会检查玩家是否在中间的其他部分。

  3. 如果他在另一个段上,它将首先销毁所有底部段,然后更改数组中剩余对象的位置,最后在顶部创建新段。现在进入第 2 步。

这是第 3 步的可视化:

我的问题是我开始统一制作游戏,但我不知道如何正确编码。你知道如何检查播放器当前是否在另一个段上吗? 我也不知道整个脚本应该是什么样子(我有一些想法,但我认为更有经验的人会做得更好)。如果有人向我解释如何编码,我将不胜感激。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    我的问题是我开始统一制作游戏,但我不知道如何 正确编码

    这不是问题,这是一个挑战,而且确实很有趣。

    你知道如何检查玩家当前是否在另一个 段?

    我不了解 Unity,但我猜一个非常简化的帧更新可能看起来像这样:

    private Segment lastSegment;
    
    public void UpdateFrame()
    {
        Segment currentSegment = MovePlayer();
        if (currentSegment != lastSegment)
        {
            // Handle player entering the new segment here
            lastSegment = currentSegment;
        }
    }
    
    private Segment MovePlayer()
    {
        // if up-button is pressed, then move up and so on
        // Then find and return the current segment
    }
    

    但我认为更有经验的人会做得更好

    是的,但如果其他人为你做,你就错过了乐趣。

    gamedev 经常回答与游戏相关的问题,所以请前往那里看看。此外,segment 和 chunk 这两个词通常表示相同的意思,因此请尝试在搜索中也使用 chunk。

    编码愉快!

    【讨论】:

      【解决方案2】:

      我看到这是一个旧线程,但我希望这种技术对其他有类似问题的人有用。 我发现最简单和最快的方法之一就是随玩家移动瓷砖,而不是动态生成它们,或者将瓷砖从后面移动到前面。假设我们有 9 个无缝地形图块,中心图块将是其他 8 个相邻图块的父图块。我们需要做的就是检查玩家是否在子地形内移动,如果是,则将中心的位置分配给该子地形的位置,所有其他瓦片将自动占据适当的新位置,因为它们是中心。下面是说明这种方法的代码:

      public UnityEngine.Terrain Center;
      public UnityEngine.Terrain N;
      public UnityEngine.Terrain S;
      public UnityEngine.Terrain E;
      public UnityEngine.Terrain W;
      public UnityEngine.Terrain NE;
      public UnityEngine.Terrain NW;
      public UnityEngine.Terrain SE;
      public UnityEngine.Terrain SW;
      
      public GameObject _player;
      
       /// <summary>
      /// 0=Center, 1=N, 2=S, 3=E, 4=W, 5=NE, 6=NW, 7=SE, 8=SW
      /// </summary>
      private int _ret; //the tile occupied by the player
      private int tw; //terrain width
      
      void Start()
      {
          tw = (int)Center.terrainData.size.x;
      }
      
       void Update()
      {
          UpdateTileset(); //make the terrain endless
      }
      
      private void UpdateTileset()
      {
          _ret = -1;
          //this first check is not really necessary:
          if (_ret == -1 && _player.transform.position.x >= Center.transform.position.x &&
              _player.transform.position.x <= Center.transform.position.x + tw &&
              _player.transform.position.z >= Center.transform.position.z &&
              _player.transform.position.z <= Center.transform.position.z + tw)
          {
              //we're inside the center
              _ret = 0;
          }
          else if (_ret == -1 && _player.transform.position.x >= N.transform.position.x &&
               _player.transform.position.x <= N.transform.position.x + tw &&
               _player.transform.position.z >= N.transform.position.z &&
               _player.transform.position.z <= N.transform.position.z + tw)
          {
              //we're inside the N
              _ret = 1;
          }
          else if (_ret == -1 && _player.transform.position.x >= S.transform.position.x &&
               _player.transform.position.x <= S.transform.position.x + tw &&
               _player.transform.position.z >= S.transform.position.z &&
               _player.transform.position.z <= S.transform.position.z + tw)
          {
              //we're inside the S
              _ret = 2;
          }
          else if (_ret == -1 && _player.transform.position.x >= E.transform.position.x &&
              _player.transform.position.x <= E.transform.position.x + tw &&
              _player.transform.position.z >= E.transform.position.z &&
              _player.transform.position.z <= E.transform.position.z + tw)
          {
              //we're inside the E
              _ret = 3;
          }
          else if (_ret == -1 && _player.transform.position.x >= W.transform.position.x &&
              _player.transform.position.x <= W.transform.position.x + tw &&
              _player.transform.position.z >= W.transform.position.z &&
              _player.transform.position.z <= W.transform.position.z + tw)
          {
              //we're inside the W
              _ret = 4;
          }
          else if (_ret == -1 && _player.transform.position.x >= NE.transform.position.x &&
              _player.transform.position.x <= NE.transform.position.x + tw &&
              _player.transform.position.z >= NE.transform.position.z &&
              _player.transform.position.z <= NE.transform.position.z + tw)
          {
              //we're inside the NE
              _ret = 5;
          }
          else if (_ret == -1 && _player.transform.position.x >= NW.transform.position.x &&
              _player.transform.position.x <= NW.transform.position.x + tw &&
              _player.transform.position.z >= NW.transform.position.z &&
              _player.transform.position.z <= NW.transform.position.z + tw)
          {
              //we're inside the NW
              _ret = 6;
          }
          else if (_ret == -1 && _player.transform.position.x >= SE.transform.position.x &&
              _player.transform.position.x <= SE.transform.position.x + tw &&
              _player.transform.position.z >= SE.transform.position.z &&
              _player.transform.position.z <= SE.transform.position.z + tw)
          {
              //we're inside the SE
              _ret = 7;
          }
          else if (_ret == -1 && _player.transform.position.x >= SW.transform.position.x &&
              _player.transform.position.x <= SW.transform.position.x + tw &&
              _player.transform.position.z >= SW.transform.position.z &&
              _player.transform.position.z <= SW.transform.position.z + tw)
          {
              //we're inside the SW
              _ret = 8;
          }
      
          //move the tiles:
          if (_ret != 0)
          {
              switch (_ret)
              {
                  case 1: //N
                      Center.transform.position = N.transform.position;
                      break;
                  case 2: //S
                      Center.transform.position = S.transform.position;
                      break;
                  case 3: //E
                      Center.transform.position = E.transform.position;
                      break;
                  case 4: //W
                      Center.transform.position = W.transform.position;
                      break;
                  case 5: //NE
                      Center.transform.position = NE.transform.position;
                      break;
                  case 6: //NW
                      Center.transform.position = NW.transform.position;
                      break;
                  case 7: //SE
                      Center.transform.position = SE.transform.position;
                      break;
                  case 8: //SW
                      Center.transform.position = SW.transform.position;
                      break;
              }
          }
      }
      

      这个工作非常快速和流畅,旧职位和新职位之间的过渡完全不可见,如果您对如何改进这种方法有一些想法,如果您分享,我会很高兴。我希望你会发现这很有用:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-26
        相关资源
        最近更新 更多