Support Forum

Pathing on the inside edge of a spinning spacestation

Hi,
The task I’m trying to do is navigate on the inside edge of a spinning space-station. You might imagine it like walking around halo.

I want to accomplish it using navmesh and an AI controlled with a rigidbody. This would make it easier to interact with my other systems.

However, I am struggling to make the AI walk after the angle of the floor has passed directly up. I have got the pathfinding working, but from what I understand, there seems to be an issue with the funnel algorithm working correctly pass that extreme angle.

The best I can get is for RichFunnel.Update() / FindNextCorners() to fill the buffer/funnelPath with a single corner (there are currently no obstacles) that ends when the path’s angle becomes too extreme.

I was hoping for some insight, Am I approaching it in the wrong way? I’m trying to avoid getting my hands too deep in the code, but I can’t seem to get the result I want.

Thanks.

Hi

That’s pretty tricky.

It’s doable though.
You will have to use the beta version to get support for spherical worlds (can be downloaded here https://www.arongranberg.com/astar/download, see documentation about spherical worlds here: https://www.arongranberg.com/astar/documentation/dev_4_3_45_d1e5882a/spherical.html).
You will also have to use the LocalSpaceGraph and LocalSpaceRichAI scripts to make it possible to rotate the space-station. You can take a look at the example scene called “Moving” to see an example of how those work. Essentially they conspire to make it seem like the graph is moving, while it actually stays in the same spot.

The funnel modifier will work in the beta for non-planar worlds if you check the unwrap and split at every portal options. See https://www.arongranberg.com/astar/documentation/dev_4_3_45_d1e5882a/funnelmodifier.html

Hey,
I am using the beta, and have looked at the spherical world examples.
They use AIPathAlignedToSurface which inherits from AIPath.
While LocalSpaceRichAI inherits from RichAI.

I need to be able to consolidate the two to have both those ideas working at once, right?

The documentation recommends using a custom movement script (which I have tried to do). I copied LocalSpaceRichAI as the basis of my movement script and added AIPathAlignedToSurface’s methods to deal with updating the movementPlane.

Finally I overrode FinalizeMovement to handle moving the AI. (I’ve also tried chucking it in a FixedUpdate)

(Below: CustomGravity is a class that just returns what the gravity would be at a given location, and _gravityConnection deals with changes in movement of the floor.)

    public override void FinalizeMovement(Vector3 nextPosition, Quaternion nextRotation)
    {
	    Debug.Log("nvelocity2D" + velocity2D);
	    Debug.Log("next pos from curr" +  (nextPosition - transform.position));
        
	    Vector3 moveDirection = nextPosition - transform.position;
	    nextPosition = transform.position + Adjust(moveDirection);
	    Debug.Log("adujsted move direction: " + Adjust(moveDirection));
	    
	    if (rigid)
	    {
		    Vector3 gravity = CustomGravity.GetGravity(rigid.position, out upAxis);
		    _gravityConnection.UpdateConnection(upAxis);

		    Vector3 clampedPos = nextPosition;
		    rigid.MovePosition(clampedPos + _gravityConnection.ConnectionVelocity);//  * Time.deltaTime);
            
            
		    rigid.AddForce(gravity, ForceMode.Acceleration);

		    rigid.rotation = _gravityConnection.GetRotation(moveDirection.normalized, upAxis);//doesnt move toward direction going
		    //rigid.MoveRotation(nextRotation);
	    }
    }
  
    Vector3 Adjust(Vector3 moveDirection)
    {
        Vector3 xAxis = ProjectDirectionOnPlane(Vector3.right, upAxis);
        Vector3 zAxis = ProjectDirectionOnPlane(Vector3.forward, upAxis);
        Vector3 contactNormal = upAxis;
        
        xAxis = ProjectDirectionOnPlane(xAxis, contactNormal);
        zAxis = ProjectDirectionOnPlane(zAxis, contactNormal);
        
        return xAxis * moveDirection.x + zAxis * moveDirection.z;
    }
    
    Vector3 ProjectDirectionOnPlane (Vector3 direction, Vector3 normal) {
        return (direction - normal * Vector3.Dot(direction, normal)).normalized;
    }

I’ve also tried applying the funnel modifier to LocalSpaceRichAI, but as far as I understand from the documentation, it doesn’t use funnel modifiers.

“The RichAI script uses its own internal funnel algorithm, so you never need to attach the FunnelModifier component.”
and
“The AIPath and AILerp movement scripts use modifiers however the RichAI movement script will ignore most of them (all that smooth and simplify the path). The RichAI movement script instead includes its own internal version of the funnel modifier which is slightly more specialized for the RichAI script. You can still attach other modifiers when using the RichAI movement script.”

Here is a video of what is currently happening:

Thanks again