wingeczz 2024-09-04 18:48 采纳率: 50%
浏览 12

unity无限地图如何实现

想用unity做一个无限循环的楼梯场景,我的设想是始终生成并保留玩家所在及上下两次的楼梯,删除多余的。
现在实际情况是如果没有最后一段删除代码的话,楼梯是可以正常生成的;
否则当我到达一定高度后,所有生成的楼梯都消失了,只剩下顶层的,而且有好几个顶层的。


using System.Collections.Generic;
using UnityEngine;

public class StairGenerator : MonoBehaviour
{
    public GameObject stairPrefab; // 楼梯预制体
    public int initialStairsCount = 5; // 初始楼梯数量
    public float stairHeight = 1.0f; // 楼梯高度(Y轴高度)
    private List<GameObject> stairs = new List<GameObject>(); // 存储楼梯的列表
    private Transform player; // 玩家对象
    private const float playerInitialHeight = 1.98f; // 玩家初始高度
    private int currentPlayerIndex = -1; // 当前玩家所在楼梯索引

    void Start()
    {
        player = Camera.main.transform; // 假设玩家是摄像机
        InitializeStairs();
        UpdatePlayerIndex(); // 初始化玩家当前楼梯索引
    }

    void Update()
    {
        UpdatePlayerIndex(); // 更新玩家楼梯索引
        UpdateStairs(); // 根据新的玩家索引更新楼梯
    }

    void InitializeStairs()
    {
        // 初始化楼梯
        for (int i = 0; i < initialStairsCount; i++)
        {
            CreateStair(i);
        }
    }

    void CreateStair(int index)
    {
        GameObject stair = Instantiate(stairPrefab);
        stair.transform.position = new Vector3(stairPrefab.transform.position.x, index * stairHeight, stairPrefab.transform.position.z);
        stairs.Add(stair);
        Debug.Log($"Creating stair at index {index} at position {stair.transform.position}");
    }

    void UpdatePlayerIndex()
    {
        // 计算当前玩家的楼梯索引
        int playerPositionIndex = Mathf.FloorToInt((player.position.y - playerInitialHeight) / stairHeight);

        // 只在玩家位置变化时更新索引
        if (playerPositionIndex != currentPlayerIndex)
        {
            currentPlayerIndex = playerPositionIndex; // 更新当前玩家楼梯索引
        }
    }

    void UpdateStairs()
    {
        // 计算需要保留的楼梯范围
        int minStairIndex = Mathf.Max(0, currentPlayerIndex - 2); // 下方保留两个楼梯
        int maxStairIndex = currentPlayerIndex + 3; // 上方保留三个楼梯

        // 生成新的楼梯
        while (stairs.Count <= maxStairIndex)
        {
            CreateStair(stairs.Count); // 继续创建新的楼梯,直到达到 maxStairIndex
        }

        // 销毁不在保留范围内的楼梯
        for (int i = stairs.Count - 1; i >= 0; i--)
        {
            if (i < minStairIndex || i > maxStairIndex)
            {               
                Destroy(stairs[i]);
                stairs.RemoveAt(i);
            }
        }

        
    }
}
  • 写回答

2条回答 默认 最新

  • 吃不了席 2024-09-04 18:49
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    要实现一个可以不断生成楼梯并在特定条件下保持这些楼梯的功能,你需要设计一个系统来跟踪玩家的位置以及楼梯的状态。这里是一个简单的示例,展示了如何在Unity中实现这个功能:

    使用Unity脚本实现楼梯生成器

    首先,我们需要定义一些必要的类和方法:

    using UnityEngine;
    
    public class StairGenerator : MonoBehaviour
    {
        public GameObject stairPrefab; // 楼梯预制体
        public float stairHeight = 1.0f; // 楼梯高度(Y轴高度)
    
        private List<GameObject> stairs = new List<GameObject>();
        private Transform player; // 玩家对象
    
        // 获取玩家当前位置
        private float GetPlayerPosition()
        {
            return player.position.y;
        }
    
        // 设置玩家位置
        private void SetPlayerPosition(float position)
        {
            player.position = new Vector3(player.position.x, position, player.position.z);
        }
    
        // 创建楼梯
        private void CreateStair(Transform playerTransform)
        {
            GameObject stair = Instantiate(stairPrefab);
            stair.transform.position = new Vector3(stairPrefab.transform.position.x, playerTransform.position.y, stairPrefab.transform.position.z);
            stairs.Add(stair);
        }
    
        // 更新玩家位置
        private void UpdatePlayerPosition()
        {
            float playerPosition = GetPlayerPosition();
            SetPlayerPosition(playerPosition);
        }
    
        // 移除楼梯
        private void RemoveStair(GameObject stairToRemove)
        {
            if (stairs.Remove(stairToRemove))
            {
                Debug.Log("Removed stair: " + stairToRemove.name);
            }
        }
    
        // 主逻辑:根据玩家位置更新楼梯状态
        private void UpdateStairState()
        {
            foreach (var stair in stairs)
            {
                if (GetPlayerPosition() == stair.transform.position.y)
                {
                    // 如果玩家位于楼梯上,则移除它
                    RemoveStair(stair);
                }
                else
                {
                    // 否则,将其添加到列表中
                    AddStairToList(stair);
                }
            }
        }
    
        // 添加楼梯到列表
        private void AddStairToList(GameObject stair)
        {
            stairs.Add(stair);
        }
    
        // 删除楼梯从列表中的匹配项
        private void RemoveFromList(GameObject stair)
        {
            stairs.Remove(stair);
        }
    }
    
    // 示例:创建楼梯生成器实例
    StairGenerator generator = FindObjectOfType<StairGenerator>();
    
    // 在场景中启用此生成器
    generator.gameObject.SetActive(true);
    

    调试和验证

    • 确保玩家在场景内:确保玩家在一个可用的高度范围内移动,这样楼梯才能正确地生成和被识别。
    • 检查楼梯状态:运行游戏以查看楼梯是否按照预期生成和消失。
    • 性能考虑:注意性能问题,特别是在高密度场景中,可能需要优化算法以提高效率。

    通过上述步骤,你应该能够实现一个基本的楼梯生成器,它可以持续生成楼梯,并且当玩家处于特定高度时自动隐藏那些不再使用的楼梯。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月4日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?