Support Forum

Falling through spherical world sometimes and navmesh rotation

TL;DR; Spanish Galleon is trying to be a spaceship D:

For the most part it works. But then sometimes it seems the collider clips into the planet, and starts falling down with World Y, yet I am not using a rigidbody, so I thought gravity would be forced to the center of the earth?

I have the beta and am using AIPathAlignedToSurface.

It seems it only really happens when the planet rotates.

At first I had a sphere collider on the planet and a box collider on the ship, I tried to swap the planet to an icosphere mesh collider, which caused it to happen much more often. I swapped it back to a sphere and changed the ship collider from a box to a sphere, which reduced the frequency as well, but it’s still far too common.
Trying to reset the position manually results in A* fighting me and causes the ship to flicker in place.

Right when it falls, I get a Quaternion LookRotation is zero message sent by A*, which seems related somehow.

I’m pretty stumped here. I would like to lock it so the distance from 0,0,0 is never more than 5 ± some small delta.

The planet rotates about it’s Axial tilt (the player can also rotate it with input), so I need the navmesh to rotate about it as well. Setting AstarPath.active.data.navmesh.rotation = earth.rotation.eulerAngles and then using Scan() is a VERY slow process, which drops my FPS to like 3 for the frame it’s called on, even when done rarely. I just want to rotate it, not recalculate everything, so what’s a simple way to just apply a rotation transformation to the navmesh? My NavMesh is just using a source mesh that’s an icosphere with a bunch of the tris cut out around the land. I tried using GraphTransformation, but I’m not sure that does what I want, and the docs are quite lacking in that area.

I tried messing with ScanAsync as well, but was unable to get it to do anything at all.


1 Like

It also seems that the system MUST 100% of the time have a destination waypoint. I do NOT want that. I only want want a destination when it has somewhere to go. If I try setting the waypoint thing to null, then setting it again when there is a destination, the boat just falls through the planet.

If the waypoint is set at the exact same location as the boat, then I get the quaternion look direction zero thing spammed every frame in my console, and the boat will not move no matter what, even if the waypoint is moved.

After the boat reaches a waypoint, it will spin in circles trying to continue to get to it, even when “When Close To Destination” is set to stop.

If I try setting the “can move” bool to false, then back to true when there is a destination, the boat falls through the planet.

Tbh, this falling through planet thing is getting infuriating, and I would love an explanation as to why it’s happening so often. It only happens when traversing a path. If I disable the AIPathAlignedToSurface script, the boat doesn’t move, but also doesn’t fall.

Edit: After rewriting AIPathAlignedToSurface, we were able to get it to stay on the navmesh. Still need to solve the rotation problem, however.

Hi

I have uploaded version 4.3.33 which I think fixes these issues.
Thank you for reporting this.

Clarification: are you rotating the whole planet as well? Then you do really need to ensure that one frame of rotation does not cause the whole ship to clip inside the collider. The movement script just uses a raycast to check where the ground is and if it is inside a collider then the raycast will not hit anything.

Thanks for getting back to me.

Yeah, the whole planet rotates.
The planet is always at 0,0,0, which means that the normal is just the ship position normalized, no raycast needed, because sphere.

We had to rewrite the ClampToNavmesh method to prevent the clipping into the planet as well.

How about rotating the NavMesh without having to rescan every time?

A common trick is to rotate the camera around the planet instead of rotating the planet itself.

Unfortunately that isn’t an option here.
Since the navmesh is just using a source mesh, it shouldn’t be too hard to apply a rotation modifier to it, I’d imagine.

Our other idea is to not rotate the nav mesh, but instead query it for a path, transforming the position in by -rotation, then transforming each point along the path out by rotation. However, this would mean we’d have to write all of our own movement code instead of using AIPathAlignedToSurface.

Maybe there is a way for us to step in between the path calculation going in and out from your movement scripts for some matrix transformations?

There is an example scene called ‘Moving’ which uses a similar method.
It tricks the RichAI script into following a path on a graph which is moving (though it actually isn’t).
You can check it out and see if something similar might work for you.
You will however have to modify the AIPathAlignedToSurface script to use those modifications as well, but the changes are quite small I think.

I am working with Spherous on this project and we are now attempting to get the LocalSpaceGraph and LocalSpaceRichAI into our scene that has previously been set up to use a Navmesh Graph with a AI script derived AIPath. When I try to run the scene, I get a null exception error in the LocalSpaceRichAI object when it tries to access its own public graph object. I do have the LocalSpaceGraph script attached to the object that is moving and my AI agent is a child of the moving object (just like in the Moving sample scene). In the Moving sample scene, the graph object in the LocalSpaceRichAI object is not null and I cannot figure out how it is getting connected to the LocalSpaceGraph object.

My intuition is to connect the public graph object in the LocalSpaceRichAI object to my moving object using the inspector but the graph object in LocalSpaceRichAI is not exposed in the inspector (even though it is public).

Any help would be appreciated.

Currently I am trying to get this working in Unity 2020.1.3f1

Jacob

So I still don’t understand how to hook up the graph object as it is done in the moving script but here is how I have it working right now:

        protected override void Start()
        {
            GameObject go = GameObject.Find("Earth");
            if (go == null)
                return;
            graph = go.GetComponent<LocalSpaceGraph>();

#if AIPath_Base_Class
            // AIPath
            base.Start();
            movementPlane = new Util.SimpleMovementPlane(rotation);
#elif RichAI_Base_Class
            //  RichAI
            RefreshTransform();
            base.Start();
#endif
        }