What should a 3D nav asset offer?

I have a robust 3D flight router, and am currently in the process of expanding it, and am considering placing it on the asset store for $.99 or something. Here is a list of current/planned features:

Flight Volumes

  • 3D volumes are defined by a trigger box collider, and you can have as many as you want in a scene
  • You can recalculate all of part of the volume during runtime to allow dynamically moving objects
  • You can define the layers that are considered impassible
  • The volume is voxelized, the size of the voxels is customizable
  • Links between volumes are automatically produced, allowing flight between areas
  • Runtime baking or (planned) loading from a bake file.
  • All features tied into the gizmo drawer so you can see you grid as you build it

Agents

  • It Require a CharacterController to actually move agent
  • Does greedy-first recursive pathfinding, good but not necessarily most optimized path
  • Speed, acceleration, and momentum can be customized
  • Flock behavior that tries to keep agents a customizable distance from each other
  • Option to tilt the controller during acceleration

It works by voxelizing the volume inside the box collider, and raycasting to see if it can see it’s neighbors. It uses this information to come up with routes through the web, which contain all of the nodes in the path. The path is then optimized to remove any nodes that are just a continuation of the last, as well as cutting some corners if raycasting says that it’s okay.

The system is ideal for arial assets that have six degrees of freedom. Helicopters, drones… It’ll work fine for things like planes, but it might pull some high-g maneuvers.

Here is a scene that I am working on with 9 volumes in total. The green lines are the valid paths within the volumes, and the blue are valid paths between volumes.

1 Like

One thing I’d want from any nav system is for it not to attempt to take control of actors.

Basically, the system should be able to tell where the pathfinding wants it to go, and how fast, but without actually moving the object. It also should be able to recalculate path afterwards if the agent moved in unexpected way.

Something like this won’t lock user into character controllers, and wold allow control of rigidbodies.

2 Likes

I will make it clear in the documentation that the CharacterController member controlled Agent is entirely optional. All of the routing is handled within the volume object itself. You can just ask the system, through a static function for a route from point A to point B. It’s a list of positions.

I’ve modified the Agent so that the CharacterController is nullable. This allows you to still have an agent that is reacted to by other agents, but will just sit there idly allowing you to move it as you wish. I will make a separate method or something to be able to retrieve flock information to integrate into your own motion system.

I suppose that I can have the agent check to see if it’s deviated off of the expected path from outside forces and automatically recalculate. I also plan on having a feature where you can set the destination to be a Transform that can be moved around, allowing the agent to automatically recalculate if the target moves too far.

My system has no built in speed information. Speed is a member of the Agent, which can be altered by other scripts, but isn’t affected by the nav system itself. Should it somehow?

I think I phrased it incorrectly. It wasn’t exactly about speed…

Let’s say the system tells agent move to the left.
This can be done two ways.
Just give normalized vector pointing left with magnitude of 1 unit.

Except the waypoint can be 0.1 units to the left and agent can overshoot.

What I would prefer is to have unnormalized vector pointing where to go till the path change. Basically, if the next waypoint is 0.1 units to the left it could be Vector3(-0.1, 0.0, 0.0), and if it is far, it oculd be Vector3(-10, 0, 0).

DOes it make sense?

“You can move this far”, pretty much.

Of course it depends on how your system is implemented.

1 Like

I’ve modified my original system so that I can have more than one flyable volumes in a scene, and have them linked together. Because it voxelizes the volume, being able to minimize the volume being calculated from speeds things up and reduces memory. These volumes should not overlap, and the system will automatically figure out routes between them. In this scene for example, there are 9 individual volumes.

Check this out!

https://www.youtube.com/watch?v=axy_3sIVYEk

Here I move the “chase” object around, which causes the agent to automatically calculate a new route. I’ve set it’s speed to zero so that I can just test the navigation, and it works perfectly. At the bottom of the screen you can see part of some printout: “created valid, optimized path with 4 positions,” “visual so returning a direct route…” This blue line is a Debug.Drawline, and is turned on and off by a member boolean, but all of this behavior is pulled out in release because it’s wrapped in preprocessor UNITY_EDITOR.

At 0:54, I start highlighting the different nav volumes, showing you what the “gizmos” look like. The green grid indicates valid paths within the volume, and the bluish ones represent valid paths to other volumes.

At 1:10, I highlight all of the volumes at once, and let you see the full mesh.

Here is the API that I have right now, let me know if anyone has any feedback or thoughts on it

NavMesh3D

public static NavMesh3DRoute getRoute(Vector3 from, Vector3 to, int maxSteps, bool optimized = true). //Used automatically by the agent, but allows you to get your own as well
public void recalculateVolume(Vector3 corner1, Vector3 corner2)  //Allows you to have dynamically moving colliders

NavMesh3DRoute

public Vector3 nextPosition(). //Position of the next location in the route
public void nextStep()  //Move to next location in the route

NavMesh3DAgent

public NavMesh3DRoute route;  //Readable and writable!
public void setDestination(Vector3 dest)
public Vector3 directionToNextLocation()
public Vector3 directionToNextLocationNormalized()
public Vector3 directionToNextLocationClampMagnitudeTo(float clamp)

I think the three directionToNextLocation functions is what you described.

Using an unoptimized path lets you see more about how the path is actually calculated. Here you see an unoptimized version. It takes the first path that it finds, which might include some strange moves just because it’s the first one it tried. The optimization then goes through each one and eliminates ones that are necessary, by using line of sight to see what’s skippable.
5944142--636500--Screen Shot 2020-06-05 at 1.39.01 PM.png

look super cool, i like the look of A* on store but at almost 90 euro is much to pricey.