深度有限搜索的寻径(Unity/ c# ~)

本文关键字:Unity 搜索 深度 | 更新日期: 2023-09-27 18:13:18

我正在制作一款基于网格的游戏,其中角色可以轮流移动他们的单位。每个角色都有一个移动量(例如4 -他们可以移动4个贴图)。我已经实现了一个DLS(它限制了它们的移动量)。使用这种方法,玩家可以移动到的所有可用贴图都会被高亮显示。

这很好。然而,我想修改算法(或实现一个特定的算法)来计算出路由。例如,玩家想要G3 -角色应该走什么路线(向前1,向左1等)。请记住,每个瓷砖可以有不同的属性(例如有些可能被阻塞)。

private void DLS(int x, int z, int depth, float jump, float previousHeight)
    {
        int resistance=1;
        if (depth >=0)
        {
            tiles[x,z].GetComponentInChildren<CheckIfClicked>().Selected();
            if (x+1 < 25)
            {
                CheckTile(x+1, z, depth, jump, previousHeight);
            }
            if (x-1 >= 0)
            {
                CheckTile(x-1, z, depth, jump, previousHeight);
            }
            if (z+1 <25) 
            {
                CheckTile(x, z+1, depth, jump, previousHeight);         
            }
            if (z-1 >=0)  
            {
                CheckTile(x, z-1, depth,jump, previousHeight);          
            }
        }
    }
    private void CheckTile(int x, int z, int depth, float jump, float previousHeight)
    {   
        float tileHeight = tiles[x, z].GetComponent<TileDimensions>().height;
        float difference = tileHeight - previousHeight;
        if (difference<0) difference*=-1;
        if (!tiles[x, z].GetComponentInChildren<CheckIfClicked>().occupied && difference<jump)
        {
            int resistance = tiles[x, z].GetComponent<TileDimensions>().getResistance();
            if (resistance<0) resistance=1;
            DLS(x, z, depth-resistance, jump, tileHeight);  
        }
    }

我的代码利用了不同的贴图属性(比如贴图的阻力(有些贴图限制移动)和高度(你只能爬这么远))。

深度有限搜索的寻径(Unity/ c# ~)

如果您希望使用更有效的算法,有两种建议的实现:

  1. 一个明星。当你知道你想去的目的地,但你需要找到到达那里的路时,最好使用星号。如果你点击了G3,而你在G1,你就知道你要去哪里了。星型算法利用启发式算法试图"猜测"。你还要走多远。这意味着当搜索可能的路线时,A星将尝试选择最短的路线,然后再尝试查看其他路线。这里有一个很棒的教程:Link

  2. Djikstra的算法。当你不知道自己要去哪里,但你想要找到包含特定"东西"的最近节点时,这是最好的选择,例如,你可能希望你的人工智能在FPS中搜索最近的生命包。我以前没有实现过Djikstra的算法,但是网上有很多教程。

使用这两种方法,您可以添加属性,如某些瓷砖的阻力和其他任何属性

既然你的算法是工作的,我想给你一些建议来增强你的代码,都涉及使用列表/字典。

执行一次路径搜索

如果你可以突出显示每个可移动的贴图,这意味着你可以遍历从源贴图到不同目的地贴图的路径,这意味着你可以一个接一个地验证贴图,直到角色无法进行额外的移动。因此,您可以将结果存储到"目标tile - lists"对的字典中。当您需要检索到特定tile的路径时,只需获取先前存储的路径。

执行两次路径搜索

由于上述方法可能占用大量内存,所以你可以在玩家移动时再次运行路径搜索算法。第二次执行所花费的时间应该少于第一次,因为玩家已经指定了特定的贴图作为路径的目的地。在第二次搜索期间,继续更新列表/字典,同时递归地执行路径搜索函数。将每个有效的中间块保存到列表/字典中,然后您可以在搜索后获得路径。


如果你是在手机平台上开发游戏,那么即使是一点点的内存使用也很重要。我建议执行路径搜索的时间是玩家所能接受的时间的两倍。

当然,通过Unity Profiler来检查哪种方法更适合你的需求,始终是一个很好的实践。