获得您所追求的行为的最佳方法之一(在 SpriteKit/GameplayKit 中)是认识到路径规划和路径跟踪不必是相同的操作。GameplayKit 为两者都提供了工具——GKObstacleGraph
有利于规划,GKAgent
有利于遵循规划的路径——当你结合两者的优势时,它们的效果最好。
(提供避障可能有点误导GKAgent
;不要认为这与寻找绕过障碍物的路线相同,更像是对路上突然出现的障碍物做出反应。)
换句话说,GKObstacleGraph
就像GKAgent
使用地图导航和安全驾驶汽车之间的区别。前者是您决定采用 CA-85 和 US-101 而不是 I-280 的地方。(也许不时重新评估你的决定——比如说,在交通堵塞周围选择不同的道路。)后者是你不断地改变车道、避开坑洼、通过较慢的车辆、减速的地方。对于交通繁忙等
在 Apple 的DemoBots示例代码中,他们将其分为两个步骤:
用于GKObstacleGraph
进行高级路径规划。也就是说,当坏人在“这里”而英雄在“那边”,并且中间有一些墙时,选择一系列大致近似于从这里到那里的路线的路径点。
使用GKAgent
行为使角色大致遵循该路径,同时对其他因素做出反应(例如让坏人不会互相踩踏,并为他们提供模糊逼真的运动曲线,而不是简单地遵循航路点之间的线)。
TaskBotBehavior.swift
您可以在该示例代码中找到这背后的大部分相关内容——从addGoalsToFollowPath
被调用的地方和它发出的调用开始并查看。
至于“永远移动”和“角速度”的问题……
代理模拟是动机类比(即代理在约束范围内将其移动到它“想要”的位置所需的操作)和物理系统(即这些运动被建模为力/脉冲)的奇怪组合。如果你拿走代理的目标,它不知道它需要停止——相反,你需要给它一个停止的目标。(即,移动速度目标为零。)可能有比 Apple 在此处选择的模型更好的模型——如果您有设计改进建议,请提交错误。
角速度比较棘手。代理的内在物理约束类似于陆地上的车辆或海上的船只的概念在系统中得到了很好的体现。它无法真正处理诸如必须重新定向以引导其推力的太空战斗机,或者可以像向前一样愉快地侧向或向后行走的行走生物——至少,不是靠它自己。您可以通过该maxAcceleration
属性来改变代理运动的“感觉”,但您会受到该属性同时涵盖线性和角加速度这一事实的限制。
但请记住,代理系统“想要”的内容与游戏世界中“实际发生的”内容之间的接口在您的控制之下。最简单的实现方法GKAgentDelegate
是同步代理的velocity
和position
属性以及它所代表的精灵。但是,您不必那样做——您可以计算不同的力/冲量并将其应用于您的精灵。