Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SortedSet.Min不包含在SortedSet中_C#_Unity3d - Fatal编程技术网

C# SortedSet.Min不包含在SortedSet中

C# SortedSet.Min不包含在SortedSet中,c#,unity3d,C#,Unity3d,我目前正尝试在Unity和C#中使用脚本进行寻路。我正在使用SortedSet获取距离游戏地图上的目标磁贴最近的磁贴。在某些情况下,SortedSet返回一个不是集合成员的值作为最小值!对于这样一个相对特定的问题,很难发布一个最小的可复制示例,因此我将发布下面使用的脚本: using System.Collections.Generic; using UnityEngine; public class Tile : MonoBehaviour { //--------------------P

我目前正尝试在Unity和C#中使用脚本进行寻路。我正在使用SortedSet获取距离游戏地图上的目标磁贴最近的磁贴。在某些情况下,SortedSet返回一个不是集合成员的值作为最小值!对于这样一个相对特定的问题,很难发布一个最小的可复制示例,因此我将发布下面使用的脚本:

using System.Collections.Generic;
using UnityEngine;

public class Tile : MonoBehaviour
{
//--------------------PATHFINDING-------------------------

//Neighboring tiles stored in a list. Assigned by tile assignment script
public List<Tile> neighbors;

//The tile which leads to this tile when pathfinding. Found during pathfinding.
public Tile previousPathTile { get; private set; }

//The cost of moving across this tile, based on terrain type
public float traversalCost { get; set; }

//The cost of moving through this tile, including the previous tiles already
//on the path. Found during pathfinding.
public float previousTraversalCost { get; private set; }

//The estimated cost from this tile to the end tile. Found during pathfinding.
public float heuristicCost { get; private set; }

//Finds path from current tile to the destination tile
public List<Tile> pathFind( Tile endTile)
{
    //The path which is returned by this function
    List<Tile> path = new List<Tile>();

    //The tiles which have been encountered but not explored
    SortedSet<Tile> unexploredTiles = new SortedSet<Tile>(new TileSortOrder());

    //The tile which is currently being explored
    Tile currentTile;

    //Make sure that we're not adding infinity to our traversal cost from the start!
    this.previousTraversalCost = 0.0f;

    //How much the heuristic cost should guide the search algorithm. Should be set so that the maximum
    //multiplier will not force a terrain switch.
    float steeringPower = 12.0f;

    //Add the starting tile to the unexploredTiles set of tiles
    unexploredTiles.Add(this);

    //Used to break out of infinite loop on SortedSet error!
    int tmp = 0;

    //Run the pathfinding algorithm
    while (unexploredTiles.Count > 0 && tmp < 250)
    {
        ++tmp;

        //---------------- ERROR OCCURS HERE ---------------------------
        UnityEngine.Debug.Log(unexploredTiles.Min);
        currentTile = unexploredTiles.Min;
        if(!unexploredTiles.Contains(unexploredTiles.Min))
        { UnityEngine.Debug.Log("ERROR: unexploredTiles does not contain its own min! " + currentTile + " " + unexploredTiles.Min); }

        //Attempting to remove here results in an error code return by the function.
        unexploredTiles.Remove(currentTile);
        //----------------------------------------------------------------

        //If we are on the final tile
        if(GameObject.ReferenceEquals(currentTile, endTile))
        {
            //Rebuild the path from end to start, then reverse.
            while (currentTile != null)
            {
                path.Add(currentTile);
                currentTile = currentTile.previousPathTile;
            }
            path.Reverse();

            return path;
        }

        int neighborsSize = currentTile.neighbors.Count;
        for (int i = 0; i < neighborsSize; ++i)
        {
            //The tile which we are checking the pathfinding cost for
            Tile nextTile = currentTile.neighbors[i];

            //Get the distance from the next tile to the destination tile only if it hasn't been obtained already.
            if(nextTile.heuristicCost < 0.0f)
            {
                nextTile.heuristicCost = (endTile.gameObject.transform.position - nextTile.gameObject.transform.position).magnitude * steeringPower;
            }

            //Get the actual traversal cost to the next tile.
            float nextTilePreviousTraversalCostFromThisTile = currentTile.previousTraversalCost + currentTile.traversalCost;

            //If the cost from this tile to the next tile is less than the previous lowest cost
            if ( nextTilePreviousTraversalCostFromThisTile < nextTile.previousTraversalCost )
            {
                nextTile.previousPathTile = currentTile;
                nextTile.previousTraversalCost = nextTilePreviousTraversalCostFromThisTile;
                unexploredTiles.Add(nextTile);
            }
        }
    }
    return path;
}
非常感谢您能提供的任何帮助。我很困惑,为什么提供的SortedSet.Min值不能成为集合的一员,我也不确定这是否是因为我犯了一个愚蠢的错误。谢谢!:-)

来自

不支持更改现有项的排序值,可能会导致意外行为

比较器使用previousTraversalCost,这将在代码中更新。您应该删除节点并插入新节点,而不是更新traversalCost。

不支持更改现有项的排序值,可能会导致意外行为


比较器使用previousTraversalCost,这将在代码中更新。您应该删除节点并插入一个新节点,而不是更新traversalCost。

您说得对!我很惊讶在集合中重新排序不会触发对最小值和最大值的重新评估,但这肯定是问题的原因。非常感谢您的帮助!:)你说得对!我很惊讶在集合中重新排序不会触发对最小值和最大值的重新评估,但这肯定是问题的原因。非常感谢您的帮助!:)
public class TileSortOrder : IComparer<Tile>
{
    public int Compare(Tile firstTile, Tile secondTile)
    {
        UnityEngine.Debug.Log("Comparing: " + firstTile.gameObject.name + " and: " + secondTile.gameObject.name + (GameObject.ReferenceEquals(firstTile, secondTile) ? "They were equal." : "They were not equal.") );
        if( GameObject.ReferenceEquals(firstTile, secondTile) )
        {
            return 0;
        }
        else
        {
            float tentativeTraversalCostFirst = firstTile.previousTraversalCost + firstTile.heuristicCost;
            float tentativeTraversalCostSecond = secondTile.previousTraversalCost + secondTile.heuristicCost;
            return tentativeTraversalCostFirst < tentativeTraversalCostSecond ? -1 : 1;
        }
    }
}
ERROR: unexploredTiles does not contain its own min! tile1247 (Tile) tile1247 (Tile)
UnityEngine.Debug:Log(Object)
Tile:pathFind(Tile) (at Assets/Scripts/Tiles/Tile.cs:211)
InputRouting:runPathPlan() (at Assets/Scripts/InputRouting.cs:312)
InputRouting:Update() (at Assets/Scripts/InputRouting.cs:291)