You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

随机游走位置生成器加重复检测仍生成重复位置问题求助

问题分析与解决方案

核心问题点

  • 方向排除逻辑完全错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:33:10