随机游走位置生成器加重复检测仍生成重复位置问题求助
问题分析与解决方案
核心问题点
- 方向排除逻辑完全错误:
generateNewPosition中,原方向为1时你排除了2、3、4,导致只能从这三个方向选——若原方向1生成的位置重复,选反向(比如2)会直接回到已存在的前序房间位置,必然重复。正确逻辑应只排除反向方向,避免走回头路,保留原方向和其他侧方向的可能性。 - 新位置生成起点错误:
posGenerator的while循环里,你用positionList[i]作为生成新位置的起点,这是回到第i个房间的位置重新生成,而非基于当前重复的currentPosition调整方向,导致生成的位置依然可能重复或偏离游走逻辑。 - 重复检测效率低:
List<Vector2>.Contains在房间数量增多时效率下降;若你的房间坐标是整数网格,改用HashSet能更精准高效地判断重复(还能避免浮点数精度误差)。
修正后的代码
1. 替换位置存储容器(推荐)
将List<Vector2>替换为HashSet<Vector2Int>(适配整数网格坐标),同时保留List用于后续遍历:
// 类内声明部分 HashSet<Vector2Int> positionSet = new HashSet<Vector2Int>(); List<Vector2Int> positionList = new List<Vector2Int>();
2. 修正generateNewPosition函数
调整为只排除反向方向的逻辑:
// 先定义方向与反向的映射(根据你的directionalPosition逻辑调整对应关系) private Dictionary<int, int> reverseDirectionMap = new Dictionary<int, int>() { {1, 2}, {2, 1}, {3, 4}, {4, 3} }; public Vector2Int generateNewPosition(Vector2Int currentPos, int originalDir) { int excludeDir = reverseDirectionMap[originalDir]; // 生成所有可用方向(排除反向) List<int> availableDirs = new List<int>() {1,2,3,4}; availableDirs.Remove(excludeDir); int randomIdx = Random.Range(0, availableDirs.Count); int newDir = availableDirs[randomIdx]; return directionalPosition(currentPos, newDir); // 确保directionalPosition返回Vector2Int }
3. 修正posGenerator函数的循环逻辑
public void posGenerator() { Vector2Int currentPosition = Vector2Int.RoundToInt(transform.position); positionSet.Add(currentPosition); positionList.Add(currentPosition); for(int i = 0; i < roomCount; i++){ int currentDirection = RandomNumberGenerator(); currentPosition = directionalPosition(currentPosition, currentDirection); // 循环生成直到得到未重复的位置 while(positionSet.Contains(currentPosition)){ // 基于当前重复位置重新生成方向 currentPosition = generateNewPosition(currentPosition, currentDirection); } positionSet.Add(currentPosition); positionList.Add(currentPosition); } // 移出生成方向列表的逻辑,避免循环内重复判断 for(int j=1;j<positionList.Count;j++){ Debug.Log("Position " + j + ": " + positionList[j]); directionList.Add(generateDirectionList(positionList[j-1], positionList[j])); } }
额外说明
- 若你的坐标是浮点数,可保留
Vector2,但建议用HashSet<Vector2>做重复检测,同时确保每次移动的步长是精确值,避免浮点数精度误差导致的误判。 - 原代码中把生成方向列表的逻辑放在循环内的
i+1 == roomCount判断里,移到循环外后逻辑更清晰,也避免了不必要的重复判断。
内容的提问来源于stack exchange,提问作者mpbstrd
相关产品推荐
相关产品推荐

