Issues with vertical angles using AddForceAtPosition (hover vehicle physics)

Hi there,

I’ve created a hover vehicle that’s simulating a lot of physics functions. For the most part it works well but I’m running into issues at vertical angles. For example when the hovercraft reaches an angle of 85 degrees to 90 degrees the hover force stops working and the gravity force just kicks in. So the hover force does not work at vertical angles and I’m wondering it’s something to do with AddForceAtPosition

The physics work similar to FZero where the vehicle sticks to the track mesh. Couple things to note, I’m not using the rigid body gravity.

I’ve added a code block so you can see main part of the code where it’s happening.
I’ve added images that describe the issues I’m having.

Something else to note is if my ship is upside down I have AddForceAtPosition to the negative of the transform.up to get the ship to hover upside down.

private void ShipGravity()
        {               
  //Apply Gravity
 if (this.shipGrounded) {
  this.shipGravity = -transform.up * this.settings.shipGravity_Low * 0.6f;
                        }else
                        {
 this.shipGravity = Vector3.down * this.settings.shipGravity_Low;
                                    }
               
//Apply gravity to down
this.shipBody.AddForce(this.shipGravity, ForceMode.Acceleration);


                //Hover Points
                List<Vector3> HoverPoints = new List<Vector3>
                {
transform.TransformPoint(-settings.shipSize.x * 0.5f, 0.0f, settings.shipSize.z * 0.5f),
transform.TransformPoint(settings.shipSize.x * 0.5f, 0.0f, settings.shipSize.z * 0.5f),
transform.TransformPoint(settings.shipSize.x * 0.5f, 0.0f, -settings.shipSize.z * 0.5f),
transform.TransformPoint(-settings.shipSize.x * 0.5f, 0.0f, -settings.shipSize.z * 0.5f)
                };


                       

                //Faling Dampener
                if (this.shipGrounded)
                {
this.fallingDamper = Mathf.Lerp(this.fallingDamper, 0.0f, Time.deltaTime);
                }
                else
                {
this.fallingDamper = Mathf.Lerp(this.fallingDamper, 0.1f, Time.deltaTime);
                }




//Go through each point to make ship hover
this.shipGrounded = false;
for (int i = 0; i < HoverPoints.Count; i++)
                {
int layerMask = 1 << LayerMask.NameToLayer("TrackFloor");
RaycastHit raycastHit;
if (Physics.Raycast(HoverPoints[i], -base.transform.up, out raycastHit, settings.shipRideHeight, layerMask))
                        {

//MeshNormal = new Vector3 (raycastHit.normal.x, raycastHit.normal.y, raycastHit.normal.z);
//MeshAngle =  Vector3.Angle (MeshNormal, Vector3.up);

shipGrounded = true;
                                   
                               
                                   
hoverForce = settings.shipRideHeight - raycastHit.distance; //float (Note that the ride height is 5.5)
spring = HoverPoints[i] - raycastHit.point; //Vector3
length = raycastHit.distance; //float
displacement = length - settings.shipRideHeight; //float
springN = spring / length; //Vector 3
compression = (settings.shipRideHeight / raycastHit.distance - 1) * -1; //float
restoreForce = springN * (displacement * (hoverForce * (-10 + (compression * 3)))); //Vector3
force = restoreForce.y; // float
force -= shipBody.GetPointVelocity(HoverPoints[i]).y * ((0.3f) + fallingDamper);
shipBody.AddForceAtPosition (transform.up * force, HoverPoints [i], ForceMode.Acceleration);

groundDistance = raycastHit.distance;
Debug.DrawRay (HoverPoints[i], -transform.up * groundDistance, Color.green);


                        }


                }



It looks you’re “up” force is acting in the up direction of the hovercraft’s frame (local coords) instead of world up:

shipBody.AddForceAtPosition (transform.up * force, HoverPoints [i], ForceMode.Acceleration);

In your vertical case the hover force isn’t acting up, it’s acting in the horizontal frame. Since there’s nothing to oppose gravitational force, the hover forces won’t do anything to act against it.

Try this instead:

shipBody.AddForceAtPosition (Vector3.up * force, HoverPoints [i], ForceMode.Acceleration);

If you really need this in local coordinates like you’ve got it now, you’ll need some other force to oppose gravity. A car sitting on a vertical wall is going to fall down too, after all…

Hey Todd, thanks for your reply.

Vector3.up was the first thing I thought of actually but that gives me weird results. It’ll actually just push the vehicle up the vertical angle but the force doesn’t stop it from hitting the ground either. I think it’s more likely something to do with the hover force calculation.

Well, like I said, if the hover force is in the vehicle frame and you rotate the vehicle to point nose up, that hover force is pointing away from the wall now. I.e., gravity is down and the hover force is now horizontal so it doesn’t oppose gravity anymore. You need engine thrust or something to hold it in place if that’s what you’re after.