How to create a non-spherical 3D GKAgent or GKObstacle?

The title is my direct question, but I will elaborate to provide context, or detail what is needed for a helpful workaround if the answer is: `You can't, log Radar with Apple`


Use case is simple: Have a behavior driven GKAgent3D avoid a plane in my ARKit/SceneKit/GameKit app.


This requires I add a 'toAvoid' GKGoal as a behavior of the agent. Apple currently provides two things to avoid, other GKAgents or GKObstacles. The problem I am having is that I see no way to create a GKAgent3D or GKObstacle for use in SceneKit that is not a sphere. GKAgent3D only has a .radius property to define it's "occupied space" and GKObstacle only has one 3D concrete subclass (GKSphereObstacle) and the obstacles(from:) functions use SpriteKit objects.


I have many agents that all have complex behaviors and there are many planes I'd like them to avoid (ARKit detected). I would rather not resort to manual collision detection, since the goal is to have the agents alter their behavior driven path as a result of the object being in the way. It is not enough to just know that the agent is going to hit the object, I need to have that fact influence it's movement considering all the other goals it has in it's behavior.


I am hoping I am missing something and there is a way to do this, or that someone has a clever workaround. The only workaround I have thought of (but hate for performance reasons) is creating a massive number of small sphere obstacles in a regular array to approximate the surface of the plane.

Replies

why don't you assign a physical property to the plane? you could use a combination of localized gravitational fields or a wind vortex, these would communicate action at a distance without the overhead of a bunch of spheres.


or to go way out on the edge, i'm working on a quantum entanglement model.

Interesting idea. I've avoided physics because my early attempts with any physics fields did not work well when used in ARKit/SceneKit. I tried using weak gravitational forces to "attract" objects slowly, but they only worked reliably at very high forces. Trying to "pull" something slowly with a weak field resulted in the object freezing in space, then a few seconds later, jerking to a new position, then freezing, etc. I never got to the bottom of why low power SceneKit physics forces were wonky but nevertheless you idea is worth a try. I will report back results.


Test Results

I added a linear gravity field to the planes and after fiddling with extent and strength I was able to get a reasonable amount of influence on my agent based characters to prevent them from penetrating the plane.


While helpful, physics fields don't cause the same behavior that an 'avoid' GKGoal would. Adding physics fields to the planes result is the objects "running into and bouncing off" the plane. I suspect if I play with the falloffExponent I could minimize the harsh direction transitions to some degree. An avoid goal would result in a smooth path that avoids the plane altogether. All in all, the physics field workaroud is not a bad solution until I can somehow get a GKGoal(avoid:) that includes 3D objects other than spheres. Thanks.

i have no clue why Scenekit is wonky? that might be work a bug report? you might need to go with a metal implementation and program your own kernel.


sounds like you're on the right path. if you're trying to obtain an 'avoid' goal, i would fall back on lisp methodology, ie, machine learning/AI approach. it probably has too much overheard for iPhone but would ok on a new iPad. you could programmaticaly using a poor man's AI/ML adjust the gravitational parameters to get your effect. if you do a good enough job, you could probably create and sell an SDK.

It may be a stupid question, but do you have evidence that GKGoal can actually pathfind around any GKObstacles in 3D, specifically GKSphereObstacles? The documentation doesn't seem to envisage any usage out of the 2D plane.


In conjunction with that, if there is 3D obstable avoidance at all, do the 2D obstacles have any effect (as if they're solid at z == 0, for example, or as if they're extruded)?


At the very least, you should submit a bug report about the inadequacy of the documentation, as well as the missing functionality. It's not impossible that a response will give you a way of moving forward.


It also occurs to me that a rectanglar (planar) array of spherical obstacles might not need a lot of spheres to do something useful, depending on the complexity of the rest of the obstacles. I doubt this will be a finally adequate solution, but it might be something to play around with.

It is not a stupid question at all. I am not "pathfinding" in GameplayKit parlance. I am using GKAgent3D objects to generate autonomous movement of multiple SCNNodes in a SceneKit Scene. I provide the agent the node's current position and rotation in agentWillUpdate() before it does it's calculations, then the agent does it's magic to generate a new position and rotation based on the behavior I've given it (a collection of GKGoals), then I take the agent's results and update the node position and rotation in agentDidUpdate().


My agents do use GKGoal(avoid:) with GKSphereObstacles, along with several other goals, (toReachTargetSpeed:, toWander, toFollow, etc.) and my moving nodes do in fact alter their path beautifully to avoid the sphere obstacles. Since I supply the agent the node's current position and rotation before each update, the running Scene physics simulation is a part of the movement choreography. The effects of gravity, collisions, etc, all play a part in the node's final movement. This works amazing well and I have very organic, responsive, dynamic movement that has some nice emergent behaviors.


I have learned that very small changes in goal weights, agent speeds, prediction times, etc. can have a profound impact on the resutling movement. It took me a bit of fiddling to get the hang of what values were needed to get the desired result. Other than not being able to avoid any 3D shape other than a sphere, (and one bothersome rotational quirk to be posted as a separate question) I am very pleased.


In response to your question about 2D obstacles, I have not tried an avoid goal on a GKAgent3D with a 2D GKPolygonObstacle since there is no way for me to specify "what Z is" (and I don't want Z=0). I suppose it is possible the system will consider the GKPolygonObstacle like a planar obstacle at Z=0, I'm just not sure.


My gut tells me that unless I am missing something and there is already a way to avoid non-sphere 3D shapes, this must be in the works. Read what's new in the iOS 11.3 beta notes and I think you will agree that non-spherical obstacles must be coming. SpriteKit has a lot more goodies for us devs, but it is a lot more mature and has nowhere near the CPU/GPU performance implications, so I hopeful more SceneKit/GameplayKit love is coming soon. In the meantime, I'll keep pushing at it and see what can be done to address the needs I have. Any other thoughts, ideas, or questions are welcome.