GameplayKit:当路径被某些障碍物阻挡时停止寻路

问题描述 投票:0回答:1

我有一个 SceneKit 项目,我正在尝试将 GameplayKit 的 2D 寻路功能集成到其中。

我有两种不同的障碍(我们称它们为“好障碍”和“坏障碍”)。主角可以摸到好人,但不能摸坏人(或者关卡失败)。

如果路径中存在“不良障碍”,我需要 GameplayKit 做的是停止寻路并通知我该过程失败

我怎样才能做到这一点?

这里有一些代码来说明我确实有寻路工作——当然减去了所需的行为:

var obstacles = [GKPolygonObstacle]()

//Manually plot a set of points around the circumference of a circle...
//...for use in creating the obstacle (because I was unable to get `GKCircleObstacle` working)
let pegRadius: Float = 0.15
let numOfPoints = 12
let totalRadians: Float = 360.0 * .pi / 180.0
let radiansPerPoint: Float = totalRadians / Float(numOfPoints)
var polyPoints = [SIMD2<Float>]()
for i in 0..<numOfPoints {
   let angle = radiansPerPoint * Float(i)
   let x = pegPosition.x + (pegRadius * cos(angle))
   let y = pegPosition.y + (pegRadius * sin(angle))
         
   polyPoints.append(SIMD2(x: x, y: y))
}

//Create the obstacle:
let obstacle = GKPolygonObstacle(points: polyPoints)

obstacles.append(obstacle)


let graph = GKObstacleGraph(obstacles: obstacles, bufferRadius: 0.05)

//Grab the nodes that will act as "to" and "from":
let receptors = scnView.scene?.rootNode.childNodes(passingTest: { theNode, stop in
     return theNode.name == "receptors"
}) as? [SCNNodeIdentifiable]
var receptorIndex: Int = 0
guard let receptors = receptors else {
     return
}
    
                
var startPointVector = vector_float2(x: Float(receptors[receptorIndex].presentation.worldPosition.x), y: Float(receptors[receptorIndex].presentation.worldPosition.y))
let endPointVector = vector_float2(x: Float(receptors[receptorIndex+1].presentation.worldPosition.x), y: Float(receptors[receptorIndex+1].presentation.worldPosition.y))
var startingPoint = GKGraphNode2D(point: startPointVector)
let endPoint = GKGraphNode2D(point: endPointVector)

graph.connectUsingObstacles(node: startingPoint)
graph.connectUsingObstacles(node: endPoint)
var path = (graph as GKGraph).findPath(from: startingPoint, to: endPoint)
                
if path.count >= 2 {
   //Path found! Do something.
} else {
   //I'd like to end up here if there's a "bad obstacle" in the way of the pathfinding
}

我怀疑答案与

GKRule
GKRuleSystem
有关,但我可以使用一些输入。

感谢您的帮助!

ios scenekit gameplay-kit
1个回答
0
投票

因此,根据文档,处理此问题的正确方法是子类化

GKGraphNode2D
并覆盖
cost(to:)
方法,
findPath
方法使用该方法构建通过图形的路径。

cost(to:)
,文档说如下:

"子类可以实现这个方法来添加其他信息到 成本。例如,游戏可能会使用更高的成本来表示旅行 通过角色难以到达的地图区域 遍历。”

不幸的是,这似乎完全坏了,不起作用。

考虑以下使“坏”障碍的成本高于“好”障碍的尝试:

class MyGraphNode2Dsubclass: GKGraphNode2D {
    var isBadObstacle: Bool = false
    
    override func cost(to node: GKGraphNode) -> Float {
       isBadObstacle ? 10.0 : super.cost(to: node)
    }
    
}

当它到达

super.cost(to: node)
时,我 100% 的时间都会
EXC_BAD_ACCESS
崩溃。

现在,我做的是:

class MyGraphNode2Dsubclass: GKGraphNode2D {
    var isBadObstacle: Bool = false
    
    override func cost(to node: GKGraphNode) -> Float {
       isBadObstacle ? 10.0 : 0.1
    }
    
}

但这会导致所有“好的”障碍具有相同的成本

0.1
而不是真正的成本,因此这不是一个好的解决方案。

显然,如果 GameplayKit 的cost 系统没有真正起作用,那么 GameplayKit 本身也没有真正起作用。

过去几年有一些other问题可能涉及同样的问题——但我不确定。他们可能描述了一些不同的东西,但在同一个主题上。

当然,也有可能是我误解了这个问题——所以如果是这样的话请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.