我有一个 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
有关,但我可以使用一些输入。
感谢您的帮助!
因此,根据文档,处理此问题的正确方法是子类化
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问题可能涉及同样的问题——但我不确定。他们可能描述了一些不同的东西,但在同一个主题上。
当然,也有可能是我误解了这个问题——所以如果是这样的话请告诉我。