首页 文章

控制Unity中的动态地形创建

提问于
浏览
1

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

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

  • 一开始它将创建九个分段,玩家将在中心 .

  • 每帧检查玩家是否在中心区域以外的其他区段 .

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

这是第3步的可视化:
Algorithm

我的问题是我开始统一制作游戏而且我不知道如何正确编码 . 你知道怎么检查玩家目前是否在另一个细分市场吗?我也不知道整个剧本应该是什么样的(我有一些想法,但我认为更有经验的人会做得更好) . 如果有人向我解释如何编码,我将非常感激 .

2 回答

  • 2

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

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

    你知道如何检查玩家目前是否在另一个细分市场吗?

    我不知道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 .

    快乐的编码!

  • 1

    我认为这是一个旧线程,但我希望这种技术对其他有类似问题的人有用 . 我发现做到这一点最简单快捷的方法之一就是用玩家移动瓷砖,不要动态生成它们,或者将它们从后面移到前面 . 假设我们有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;
            }
        }
    }
    

    这个过程非常快速和平稳,旧位置和新位置之间的过渡是完全不可见的 . 如果你对如何改进这种方法有一些想法,我会很高兴你分享它们 . 我希望你会发现这很有用:)

相关问题