Unity C#:如何用单个for循环替代9个循环生成小六边形组成的大六边形?
优化思路:用单个循环生成六边形网格
这是个很棒的优化问题!先拆解你现有代码里的重复逻辑,找到规律后就能轻松把9个嵌套循环合并成一个。
第一步:找出重复逻辑的规律
观察你写的9列代码,能发现两个关键规律:
- 列的x坐标规律:所有列的x值可以用列索引
col(从-4到4,共9列)计算:x = col * 0.75f- 比如col=0时x=0(中间列),col=1时x=0.75(第一列右侧),col=-1时x=-0.75(第一列左侧),完全匹配你代码里的x值。
- 每列的y范围规律:对于任意列
col,y的起始值是4f - 0.5f * Mathf.Abs(col),结束值是这个起始值的相反数,且y每次递减1。每列的cell数量是9 - Mathf.Abs(col):- col=0时,y从4到-4(共9个);
- col=±1时,y从3.5到-3.5(共8个);
- col=±4时,y从2到-2(共5个),完美对应你原代码的循环范围。
第二步:用单个循环实现
基于上面的规律,有两种简洁的实现方式:
方式1:用LINQ生成所有坐标,再单个foreach循环
这种方式可读性最高,先一次性生成所有需要的坐标,再用一个循环完成实例化:
using System.Linq; // 生成所有列的索引:从-4到4 var columns = Enumerable.Range(-4, 9); // 生成所有要实例化的坐标对 var allCellPositions = columns.SelectMany(col => { float x = col * 0.75f; float startY = 4f - 0.5f * Mathf.Abs(col); // 生成当前列的所有y值 var yValues = Enumerable.Range(0, 9 - Mathf.Abs(col)) .Select(i => startY - i * 1f); return yValues.Select(y => new Vector2(x, y)); }); // 单个循环完成所有实例化 foreach (var pos in allCellPositions) { Instantiate(cell, pos, Quaternion.Euler(0.0f, 0.0f, 90.0f)); }
方式2:先收集坐标到列表,再单个循环实例化
如果你不想用LINQ,可以手动收集所有坐标,再用一个循环处理:
List<Vector2> allCellPositions = new List<Vector2>(); // 先收集所有需要的坐标 for (int col = -4; col <= 4; col++) { float x = col * 0.75f; float startY = 4f - 0.5f * Mathf.Abs(col); int cellCount = 9 - Mathf.Abs(col); for (int i = 0; i < cellCount; i++) { float y = startY - i * 1f; allCellPositions.Add(new Vector2(x, y)); } } // 单个循环完成实例化 foreach (var pos in allCellPositions) { Instantiate(cell, pos, Quaternion.Euler(0.0f, 0.0f, 90.0f)); }
为什么这能替代原来的9个循环?
原来的9个嵌套循环本质上是在重复“计算列x→遍历列内y→实例化”的逻辑,我们把这个逻辑抽象成了基于列索引的数学公式,用一次循环(或先收集再循环)就完成了所有列的处理,完全消除了重复代码。
内容的提问来源于stack exchange,提问作者Tim Markin
相关产品推荐
相关产品推荐

