如何用循环精简代码且避免重复随机数?18个GameObject指定Z轴位姿设置求助
解决方案:为18个GameObject分配不重复的Z轴随机位置
看起来你需要给18个障碍物体分配唯一的Z轴位置(都是60的倍数),还要用循环精简代码、避免重复随机数。我帮你整理了两种可行的实现方式,代码简洁且逻辑清晰:
方式一:用List处理(推荐,代码更简洁)
利用C#的List来管理可用的位置索引,它自带的RemoveAt方法可以轻松移除已使用的索引,避免重复:
using UnityEngine; using System.Collections.Generic; public class HurdlePlacement : MonoBehaviour { GameObject[] hurdles; List<int> availablePositionIndices; void Start() { // 找到所有标记为"Hurdles"的物体 hurdles = GameObject.FindGameObjectsWithTag("Hurdles"); // 先做个校验:确保找到的物体数量正好是18个,避免后续逻辑出错 if (hurdles.Length != 18) { Debug.LogError("找到的Hurdles数量不是18个!请检查场景中的物体标签"); return; } // 初始化可用位置索引:0到17,对应Z值0、60、120...1020(17*60) availablePositionIndices = new List<int>(); for (int i = 0; i < 18; i++) { availablePositionIndices.Add(i); } // 循环给每个障碍分配位置 foreach (GameObject hurdle in hurdles) { // 从剩余可用的索引里随机选一个 int randomListIndex = Random.Range(0, availablePositionIndices.Count); int selectedIndex = availablePositionIndices[randomListIndex]; // 计算对应的Z轴位置:索引*60 float targetZ = selectedIndex * 60f; // 设置物体位置(X、Y保持0,你可以根据需求修改) hurdle.transform.position = new Vector3(0f, 0f, targetZ); // 把已使用的索引从列表中移除,避免重复分配 availablePositionIndices.RemoveAt(randomListIndex); } } }
方式二:用数组手动处理(适合不想用List的场景)
如果你不想引入List,也可以用数组自己实现移除元素的逻辑:
using UnityEngine; public class HurdlePlacement : MonoBehaviour { GameObject[] hurdles; int[] availablePositionIndices; void Start() { hurdles = GameObject.FindGameObjectsWithTag("Hurdles"); if (hurdles.Length != 18) { Debug.LogError("找到的Hurdles数量不是18个!请检查场景中的物体标签"); return; } // 初始化可用索引数组 availablePositionIndices = new int[18]; for (int i = 0; i < availablePositionIndices.Length; i++) { availablePositionIndices[i] = i; } foreach (GameObject hurdle in hurdles) { int randomArrayIndex = Random.Range(0, availablePositionIndices.Length); int selectedIndex = availablePositionIndices[randomArrayIndex]; float targetZ = selectedIndex * 60f; hurdle.transform.position = new Vector3(0f, 0f, targetZ); // 移除已使用的索引,更新可用数组 RemoveElementFromArray(ref availablePositionIndices, randomArrayIndex); } } // 辅助方法:从数组中移除指定索引的元素 void RemoveElementFromArray(ref int[] array, int indexToRemove) { int[] newArray = new int[array.Length - 1]; int newArrayIndex = 0; for (int i = 0; i < array.Length; i++) { if (i != indexToRemove) { newArray[newArrayIndex] = array[i]; newArrayIndex++; } } array = newArray; } }
核心逻辑说明
- 不重复随机数的实现:我们不是直接随机生成Z值,而是先维护一个「可用位置索引列表/数组」,每次选完一个索引后就把它移除,这样后续永远不会选到重复的索引,自然也就不会有重复的Z位置。
- 循环精简代码:用
foreach遍历所有障碍物体,代替手动写18次赋值语句,代码更简洁,而且如果后续物体数量变化,只要调整索引范围就能适配。 - Z值计算:因为你需要的Z值是
0,60,120...,正好是索引*60,所以用索引来计算Z值非常方便,不需要额外维护一个Z值数组。
内容的提问来源于stack exchange,提问作者Jamshaid Alam
相关产品推荐
相关产品推荐

