求助:复刻Ditto Zig Zag游戏的平台生成与相机适配问题
解决方案:限制平台生成范围与相机精准移动
一、限制平台生成在相机可视范围内
要让平台不超出屏幕,需先计算相机在世界空间中的可视边界,再在生成平台时做位置校验。
1. 添加必要变量
在PathGenerator脚本中补充以下变量:
[SerializeField] Camera mainCamera; private float minX, maxX, minZ, maxZ; private float platformHalfSize;
2. 初始化边界与平台尺寸
修改Start()方法,计算相机边界和平台半尺寸(避免平台边缘超出屏幕):
void Start() { // 获取平台预制体的半宽度,适配不同尺寸平台 Renderer platformRenderer = trackPrefab.GetComponent<Renderer>(); if (platformRenderer != null) { platformHalfSize = platformRenderer.bounds.extents.x; } // 默认绑定主相机 if (mainCamera == null) mainCamera = Camera.main; // 正交相机边界计算 float cameraHalfWidth = mainCamera.orthographicSize * mainCamera.aspect; float cameraHalfHeight = mainCamera.orthographicSize; // 转换为世界空间边界,预留平台半尺寸的余量 minX = mainCamera.transform.position.x - cameraHalfWidth + platformHalfSize; maxX = mainCamera.transform.position.x + cameraHalfWidth - platformHalfSize; minZ = mainCamera.transform.position.z - cameraHalfHeight + platformHalfSize; maxZ = mainCamera.transform.position.z + cameraHalfHeight - platformHalfSize; CreatePath(amountToPool); UsePath(); }
透视相机适配:替换上述边界计算代码为:
// 透视相机通过视口转世界坐标计算边界 Vector3 bottomLeft = mainCamera.ViewportToWorldPoint(new Vector3(0, 0, mainCamera.nearClipPlane)); Vector3 topRight = mainCamera.ViewportToWorldPoint(new Vector3(1, 1, mainCamera.nearClipPlane)); minX = bottomLeft.x + platformHalfSize; maxX = topRight.x - platformHalfSize; minZ = bottomLeft.z + platformHalfSize; maxZ = topRight.z - platformHalfSize;
3. 修改随机生成逻辑,添加边界校验
重写RandomPicker()方法,确保生成位置不越界:
private void RandomPicker() { var randomNumber = Random.Range(0, 2); Vector3 newPos = lastPos; if (randomNumber < 1) { newPos = new Vector3(lastPos.x - offset, 0, lastPos.z); // X轴越界则反向生成 if (newPos.x - platformHalfSize < minX || newPos.x + platformHalfSize > maxX) { newPos = new Vector3(lastPos.x + offset, 0, lastPos.z); } } else { newPos = new Vector3(lastPos.x, 0, lastPos.z - offset); // Z轴越界则反向生成 if (newPos.z - platformHalfSize < minZ || newPos.z + platformHalfSize > maxZ) { newPos = new Vector3(lastPos.x, 0, lastPos.z + offset); } } spawnPos = newPos; lastPos = spawnPos; }
二、相机精准移动,保持平台可视
相机需跟随游戏推进(如玩家或最新平台),同时实时更新边界,确保后续生成的平台始终在屏幕内。
1. 添加跟随相关变量
[SerializeField] Transform followTarget; // 绑定玩家或路径核心对象 [SerializeField] float followSpeed = 5f;
2. 实现平滑跟随与边界更新
在Update()方法中添加相机跟随逻辑,并实时刷新边界:
void Update() { if (followTarget != null) { // 保持相机在目标正上方(固定Y轴高度) Vector3 targetCamPos = new Vector3(followTarget.position.x, mainCamera.transform.position.y, followTarget.position.z); // 平滑插值移动相机 mainCamera.transform.position = Vector3.Lerp(mainCamera.transform.position, targetCamPos, followSpeed * Time.deltaTime); // 实时更新相机边界 UpdateCameraBounds(); } } // 提取边界更新方法,方便复用 private void UpdateCameraBounds() { if (mainCamera.orthographic) { float cameraHalfWidth = mainCamera.orthographicSize * mainCamera.aspect; float cameraHalfHeight = mainCamera.orthographicSize; minX = mainCamera.transform.position.x - cameraHalfWidth + platformHalfSize; maxX = mainCamera.transform.position.x + cameraHalfWidth - platformHalfSize; minZ = mainCamera.transform.position.z - cameraHalfHeight + platformHalfSize; maxZ = mainCamera.transform.position.z + cameraHalfHeight - platformHalfSize; } else { Vector3 bottomLeft = mainCamera.ViewportToWorldPoint(new Vector3(0, 0, mainCamera.nearClipPlane)); Vector3 topRight = mainCamera.ViewportToWorldPoint(new Vector3(1, 1, mainCamera.nearClipPlane)); minX = bottomLeft.x + platformHalfSize; maxX = topRight.x - platformHalfSize; minZ = bottomLeft.z + platformHalfSize; maxZ = topRight.z - platformHalfSize; } }
额外注意事项
- 初始
lastPos需设置在相机边界内,避免第一个平台直接越界 - 若使用对象池复用平台,需确保每次复用前重新校验位置
内容的提问来源于stack exchange,提问作者Deepanshu Soni
相关产品推荐
相关产品推荐

