Unity 2D数组生成2.5D俯视角迷宫的翻转与墙体优化问题
静态迷宫生成问题与2.5D俯视角墙体优化方案咨询
问题描述
我正在为Game Jam制作一款游戏,采用静态迷宫设计。目前生成的迷宫与给定的2D数组样式不匹配,目标数组如下:
{ 1, 0, 1, 1, 1, 1, 1}, { 1, 0, 0, 0, 1, 0, 1}, { 1, 1, 1, 0, 0, 0, 1}, { 1, 0, 0, 0, 1, 0, 1}, { 1, 0, 1, 1, 1, 0, 1}, { 1, 0, 0, 0, 1, 0, 1}, { 1, 1, 1, 0, 1, 1, 1}
生成效果不符合预期(已知部分墙体缺失,暂未添加对应代码)。我尝试过反转x、y坐标,修改生成时的旋转角度,但仍无法将迷宫调整到预期样式。
现有墙体生成代码
void CreateWalls() { for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { if (grid[i, j] == 1) { Vector3 position = new Vector3(i * wallSize, -j * wallSize, 1); Quaternion rotation = transform.rotation; GameObject createdWall = null; bool hasTopWall = false; bool hasLeftWall = false; bool hasRightWall = false; bool hasBottomWall = false; Debug.Log("i: " + i + ", j: " + j); if (i - 1 >= 0) { if (grid[i - 1, j] == 1) { hasLeftWall = true; } } if (i + 1 < gridSize) { if (grid[i + 1, j] == 1) { hasRightWall = true; } } if (j - 1 >= 0) { if (grid[i, j - 1] == 1) { hasTopWall = true; } } if (j + 1 < gridSize) { if (grid[i, j + 1] == 1) { hasBottomWall = true; } } if (hasTopWall && !hasLeftWall && !hasRightWall && hasBottomWall) { // vertical createdWall = Instantiate(verticalWallPrefab, position, rotation); } else if (!hasTopWall && hasLeftWall && hasRightWall && !hasBottomWall) { // horizontal createdWall = Instantiate(horizontalWallPrefab, position, rotation); } else if (hasTopWall && hasLeftWall && hasRightWall && !hasBottomWall) { // top - left - right createdWall = Instantiate(threeWayWallTopLeftRightPrefab, position, rotation); } else if (!hasTopWall && hasLeftWall && hasRightWall && hasBottomWall) { // bottom - left - right createdWall = Instantiate(threeWayWallBottomLeftRightPrefab, position, rotation); } else if (hasTopWall && hasLeftWall && hasRightWall && !hasBottomWall) { // top - left - bottom createdWall = Instantiate(threeWayWallBottomLeftRightPrefab, position, rotation); } else if (hasTopWall && !hasLeftWall && hasRightWall && hasBottomWall) { // top - right - bottom createdWall = Instantiate(threeWayWallTopBottomRightPrefab, position, rotation); } else if (hasTopWall && hasLeftWall && hasRightWall && hasBottomWall) { // four way createdWall = Instantiate(fourWayWall, position, rotation); } else if (hasTopWall && hasLeftWall && !hasRightWall && !hasBottomWall) { createdWall = Instantiate(cornerLeftBottomTop, position, rotation); } else if (hasTopWall && !hasLeftWall && hasRightWall && !hasBottomWall) { createdWall = Instantiate(cornerRightBottomTop, position, rotation); } else if (!hasTopWall && !hasLeftWall && hasRightWall && hasBottomWall) { createdWall = Instantiate(cornerTopRightBottom, position, rotation); } else if (!hasTopWall && hasLeftWall && !hasRightWall && hasBottomWall) { createdWall = Instantiate(cornerTopLeftBottom, position, rotation); } if(createdWall != null) { createdWall.transform.parent = GameObject.Find("WallHolder").transform; } } } } }
解决方案建议
一、迷宫样式匹配问题修复
1. 坐标映射修正
当前代码中-j * wallSize会导致Y轴翻转,让数组的第一行对应场景底部。可以将位置计算改为:
Vector3 position = new Vector3(i * wallSize, (gridSize - 1 - j) * wallSize, 1);
若还是不匹配,可尝试交换i和j的位置,修正数组行列与场景XY轴的对应关系:
Vector3 position = new Vector3(j * wallSize, (gridSize - 1 - i) * wallSize, 1);
2. 修复重复条件判断
代码中有一处完全重复的条件分支,会导致墙体类型错误:
// 重复的条件,需修改第二个分支的判断逻辑 else if (hasTopWall && hasLeftWall && hasRightWall && !hasBottomWall) { // top - left - bottom createdWall = Instantiate(threeWayWallBottomLeftRightPrefab, position, rotation); }
可将该分支的条件改为hasTopWall && hasLeftWall && !hasRightWall && hasBottomWall,对应top-left-bottom的三向墙场景。
3. 补充缺失墙体的判断分支
当前代码未覆盖所有墙体组合情况(比如孤立墙、单侧相邻墙),需补充对应逻辑:
// 孤立墙(无相邻墙体) else if (!hasTopWall && !hasLeftWall && !hasRightWall && !hasBottomWall) { createdWall = Instantiate(singleWallPrefab, position, rotation); } // 仅顶部有相邻墙 else if (hasTopWall && !hasLeftWall && !hasRightWall && !hasBottomWall) { createdWall = Instantiate(singleTopWallPrefab, position, rotation); } // 补充其他单侧/剩余组合情况
二、2.5D俯视角墙体生成优化方案
1. 瓦片地图式生成
直接使用Unity的Tilemap系统,制作包含直墙、拐角、三向/四向墙的瓦片集,遍历数组时直接根据相邻情况设置对应瓦片。这种方式无需手动实例化GameObject,性能更高,且编辑调整更便捷,适合Game Jam快速开发。
2. 基于边的生成(推荐)
不以网格单元格为单位生成墙体,而是以单元格之间的边为判断依据:当相邻单元格一个是墙(1)、一个是空地(0)时,在该边上生成墙体。逻辑简洁,不会出现拐角判断错误:
void CreateWallsByEdges() { for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { if (grid[i, j] == 1) { // 生成右侧墙体(当前是墙,右侧为空地或边界) if (i + 1 >= gridSize || grid[i+1, j] == 0) { Vector3 pos = new Vector3((i + 0.5f)*wallSize, (gridSize - 1 - j)*wallSize, 1); Instantiate(verticalWallPrefab, pos, Quaternion.identity); } // 生成下侧墙体(当前是墙,下侧为空地或边界) if (j + 1 >= gridSize || grid[i, j+1] == 0) { Vector3 pos = new Vector3(i*wallSize, (gridSize - 1 - j + 0.5f)*wallSize, 1); Instantiate(horizontalWallPrefab, pos, Quaternion.identity); } } } } }
3. 网格合并优化
若使用3D墙体模型,可先遍历生成所有墙体数据,再将同类型墙体合并为单个Mesh(通过Mesh.CombineMeshes),减少Draw Call,提升运行性能。
内容的提问来源于stack exchange,提问作者Martin Wagner
相关产品推荐
相关产品推荐

