是否使用GKAgent

时间:2016-09-28 18:09:42

标签: sprite-kit gameplay-kit

我正在开发(或至少尝试开发) 一个体面的大型实时战术游戏(类似于RTS)使用SpriteKit。

我正在使用GamePlay工具包进行寻路。

最初我使用SKAction来移动路径中的精灵,但速度足够快,我意识到这是一个很大的错误。

然后我尝试用GKAgent来实现它(这是我目前的状态) 我觉得GKAgent是非常原始和过早的,他们也遵循一些奇怪的牛顿法#1,使他们永远移动(我想不出任何有用的场景 - 也许是在WWDC的演讲)

以及我看到他们有一些角速度来执行旋转 我根本不需要,也无法真正找到如何禁用它......

除了GKBehavior给出一个GKGoal s似乎有些奇怪之处......

设置避开障碍物的行为让我的单位在他们周围慢跑...... 除非maxPredictionTime足够低,否则设置跟随路径目标的行为将完全忽略所有内容... 我甚至不愿意告诉我将两者结合起来会发生什么。

我感到很伤心......

我觉得我现在有两个选择:

1)与这些代理商争取更多的努力,并试图让他们按照我的意愿行事

2)在GKObstacleGraph的帮助和我自己的路径中找到所有的动作和一个路径Finding(我也不得不说在某些点上路径到达该点的路径会产生最糟糕的路径“去触摸那个障碍物,然后反转触摸那个然后去实际点(从一开始可以通过直线实现)”)。

问题是:

这些选项中最好的是什么?

2 个答案:

答案 0 :(得分:8)

获得您所追求的行为的最佳方式之一(在SpriteKit / GameplayKit中)是识别路径规划和路径跟随需要不一样的操作。 GameplayKit为两者提供工具 - GKObstacleGraph有利于规划,GKAgent有利于遵循计划的路径 - 当你结合每个工具的优势时,它们最有效。

GKAgent提供避障可能有点误导;不要像在障碍物周围寻找路线那样想到这一点,更像是对你的突然障碍做出反应。)

换句话说,GKObstacleGraphGKAgent就像导航地图和安全驾驶汽车之间的区别。前者是您决定使用CA-85和US-101而不是I-280的地方。 (并且可能会在一段时间内重新评估您的决定 - 例如,在交通拥堵周围选择一组不同的道路。)后者是您不断变化的车道,避免坑洼,通过较慢的车辆,减速的地方交通繁忙等。

在Apple的DemoBots示例代码中,他们将此分为两个步骤:

  1. 使用GKObstacleGraph进行高级路径规划。也就是说,当坏人在这里时,#34;并且英雄在那边#34;并且中间有一些墙,选择一系列航路点,大致接近从这里到那里的路线。

  2. 使用GKAgent行为使角色大致遵循该路径,同时也对其他因素做出反应(比如让坏人不相互踩,给他们模糊逼真的动作曲线而不是简单地跟随航路点之间的线路。)

  3. 您可以在该示例代码的TaskBotBehavior.swift中找到此背后的大部分相关内容 - 从addGoalsToFollowPath开始,查看被调用的地点及其所进行的调用。

    至于"永远地移动"和#34;角速度"问题......

    代理人模拟是一种奇怪的动机类比组合(即代理人需要将其移动到需要约束的地方)和物理系统(即那些动作)被建模为力/冲动)。如果你取消了代理人的目标,它就不知道它需要停止 - 相反,你需要给它一个停止的目标。 (也就是说,移动速度目标为零。)如果您有改进设计的建议,可能会有比Apple在此处选择的更好的模型 - file bugs

    角速度比较棘手。代理商的概念'内在的物理限制有点类似于陆地上的车辆或海上的船只,它们很好地融入了系统。它无法真正处理太空战士必须重新定向以引导他们的推力,或行走的生物,这些生物可以像往前一样快乐地侧身或后退 - 至少不是靠自己。你可以在改变'#34;感觉"具有maxAcceleration属性的代理移动,但您受到所述属性同时涵盖线性加速度和角加速度的限制。

    但请记住,代理系统和#34;之间的界面是什么"什么"实际发生"在你的游戏世界是你的控制之下。实现GKAgentDelegate的最简单方法是同步代理的velocityposition属性及其代表的精灵。但是,你不必这样做 - 你可以计算一个不同的力/冲动并将它应用到你的精灵。

答案 1 :(得分:2)

我无法评论,所以我发帖作为答案。我最近遇到了同样的问题:代理人在目标周围晃来晃去,或者即使你移除行为也会继续移动。然后我意识到行为只是控制运动的算法,但您仍然可以手动访问和设置代理的速度,位置和角度。

就我而言,我有一个在场景中追逐食物的生物实体。当它与食物制剂接触时,食物实体被移除。我尝试了很多东西让食物吃完后停下来(它会一直保持直线)。而我所要做的就是将速度设置为0.这是因为行为不会直接影响位置,而是影响速度/角度组合(根据我的理解)。当实体没有目标时,它并不想要"想要"改变它的状态,所以无论它达到什么速度和方向,它都会保持。它根本不会更新/更改它。因此,除非你创造一个让它想要停止的目标,否则它将会摆动/继续前进。简单的方法是将行为设置为nil,并将速度设置为0。

如果行为/目标系统没有为您要查找的动画类型执行此操作,您仍然可以使用代理系统并使用AgenDelegate协议和更新方法自定义移动并使其与其他代理人稍后。您甚至可以将代理与使用物理引擎或动作(或任何其他方式)移动的节点同步。

我认为代理系统很好用,因为您可以在以后使用它,即使它仅用于特殊效果。但正如混合动作和物理学可以给出一些奇怪的结果,混合目标/行为和任何其他"自动化"工具可能会导致不稳定的行为。

您还可以将代理系统用于其他内容,而不是移动实际的精灵。例如,您可以使用代理作为"目标搜索者"模拟敌人的反应时间。代理在场景中移动并找到其他代理,当它与合适的目标接触时,敌方实体会攻击它(随意的想法)。

它不是"一个尺寸适合所有"解决方案,但它是一个非常好的工具。