Use GKAgents or not

I am developing (or at least trying to develop) a pretty decent game of real-time tactics (something similar to RTS) using SpriteKit.

I use the GamePlay suite to find paths.

I originally used SKAction to move sprites inside the Path, but quickly realized that this was a big mistake.

Then I tried to implement it with GKAgent (this is my current state) I feel that GKAgent are very raw and premature, and they follow some kind of strange Newton's Law No. 1 that makes them move forever (I can't come up with any scripts where it would be useful - perhaps for presentations at WWDC)

and also I see that they have Angular speed for cornering which I don’t need at all and cannot find how to turn it off ...

Like GKBehavior , given GKGoal , it seems like something strange ...

Setting behavior to avoid obstacles makes my units run around them ... Setting behavior for the next path completely ignores everything, unless maxPredictionTime enough ... I don’t even want to say what happens when I combine both of them.

I feel broken ...

It seems to me that I have 2 options:

1) to fight more with these agents and try to make them behave the way I want

2) To collapse all the movements yourself with GKObstacleGraph and find the path (which is also buggy, I have to say that at some points the path to the point will generate the most terrible path, for example, “go touch this obstacle and then turn it back so that then go to the actual point (which from the very beginning could be reached by a straight line).)

Question:

What would be the best of these options?

+5
source share
2 answers

One of the best ways (in SpriteKit / GameplayKit) to get the behavior you need is to recognize that route planning and the subsequent route should not be the same operation. GameplayKit provides tools for both - GKObstacleGraph is good for planning, and GKAgent is good for following the planned path - and they work best when you combine the strengths of each of them.

(It may be a little erroneous that GKAgent provides obstacle avoidance; do not think of it the same way as finding a route around obstacles, more like responding to sudden obstacles in your way.)

In other words, GKObstacleGraph and GKAgent are like the difference between navigating with a map and driving safely. The first is where you decided to take the CA-85 and US-101 instead of I-280. (And maybe overestimate your decision once in a while - say, to choose a different set of roads around the traffic jam.) The latter is the place where you constantly change lanes, avoid potholes, miss slow vehicles, slow down traffic for intense movements etc.


The Apple DemoBots sample code, they break it down into two stages:

  • Use GKObstacleGraph to plan your paths at a high level. That is, when the bad guys are “here,” and the hero is “way there,” and there are several walls between them, select a series of waypoints that approximate the route from here to there.

  • Use the GKAgent behavior to make the character rudely follow this path, as well as react to other factors (for example, make bad guys not step on each other and give them vaguely realistic motion curves, and not just follow the lines between waypoints).

In this code example, you can find most of the relevant material in TaskBotBehavior.swift - start with addGoalsToFollowPath and look at the places being called and the calls it makes.


Regarding the problems with "moving forever" and "angular" ...

Agent modeling is a strange combination of a motivational analogy (that is, an agent does what it takes to move it to where it "wants" within the limits) and a physical system (i.e. these movements are modeled as forces / impulses) . If you take away the agent’s goals, he doesn’t know that he needs to stop - instead, you need to stop him. (That is, the goal of speed is zero.) There may be a better model than what Apple chose here - file errors , if you have suggestions for improving the design.

Angular speed is harder. The concept of internal physical limitations of agents, which are a kind of analogue, for example, vehicles on land or boats at sea, is pretty well baked in the system. He cannot deal with such things as space fighters, which have to reorient themselves to the vector of their thrust or walking creatures, which can just as happily walk sideways or backward as forward, at least not by themselves. You can get some mileage towards changing the “feel” of the agent’s movement using the maxAcceleration property, but you are limited in that the property covers both linear and angular acceleration.

Remember, however, that the interface between what the system “wants” and what “actually happens” in your game world is under your control. The easiest way to implement GKAgentDelegate is to simply synchronize the velocity and position properties of the agent and the sprite that it represents. However, you do not have to do this - you can calculate a different force / momentum and apply it to your sprite.

+8
source

I can not comment, so I am posting as an answer. Recently, I have faced the same problem: the agent vibrates around a target or an agent that continues to move, even if you delete the behavior. Then I realized that behavior is just an algorithm that controls movement, but you can still access and set the agent’s speed, position and angle manually.

In my case, I have a creature subject that pursues food on stage. When it comes into contact with a food agent, the food item is removed. I tried a lot of things to make the critter stop after eating (he will keep going in a straight line). And all I had to do was set the speed to 0. This is due to the fact that the behavior will not affect the position directly, but the combination of speed and angle (from what I understand). When there is no target for an object, it does not “want” to change its state, therefore, regardless of speed and direction, they will be saved. It just won’t update / change it. Therefore, if you do not create a goal to make it stop, it will swing / continue to move. An easy way is to set the behavior to nil and set the speed to yourself.

If the behavior / target system does not do this for the type of animation you are looking for, you can still use the Agent system and configure the movement using the AgenDelegate protocol and update method and force it to interact with other agents later. You can even synchronize an agent with a node that moves using the physics engine or with actions (or in any other way).

I think the agent system is good because you can use it later, even if it is only for special effects. But just as mixing actions and physics can produce some weird results, mixing targets / behaviors and any other “automated” tool is likely to lead to erratic behavior.

You can also use the agent system for other things than moving the actual sprite. For example, you can use an agent to act as a “target seeker” to simulate reaction times for your enemies. An agent moves around the stage and finds other agents, when he comes in contact with a suitable target, an enemy entity attacks him (random idea).

This is not a “one size fits all” solution, but it is a very good tool.

+2
source

Source: https://habr.com/ru/post/1257410/


All Articles