# Floating Origin (Position and Velocity) - Rotation problem when zeroing out velocity while low fps

I am building a space simulator.
I have made a FloatingOrigin script based on the one from the wiki, but I added a velocity reset too.

Basically, I have a scene with two container objects at the root : Userspace and Universe.
The Spaceship and the FirstPersonController are both direct children of the Userspace.
The Universe contains all the other objects (planets, other spaceships, etc).

• Userspace
---- FirstPersonController
---- Spaceship
• Universe
---- Planet
---- Sun
---- SpaceStation

When controlling the spaceship, the FirstPersonControllerâ€™s RigidBody is Kinematic and has a script to follow the spaceship :

``````void LateUpdate() {
character.transform.position = spaceship.transform.position;
}
``````

To make the spaceship accelerate, I check for WASD inputs in FixedUpdate() on a script attached to the spaceship.
Exemple for forward :

``````if (Input.GetKey (KeyCode.W)) {
}
``````

Here everything works as expected, except for a shaking effect due to floating point precision.
To fix that I have made a FloatingOrigin system which resets the spaceship to the origin and moves the Universe, both position and velocity.

My FloatingOrigin script (shortened) :

``````public float maxDistanceFromOrigin = 1000f;
public float maxVelocity = 1000f;

public GameObject universe;
public GameObject spaceship;

void LateUpdate() {
if (spaceship.rigidbody.velocity.sqrMagnitude > maxVelocity) {
universe.rigidbody.velocity -= spaceship.rigidbody.velocity;
spaceship.rigidbody.velocity = Vector3.zero;
}
if (spaceship.transform.position.magnitude > maxDistanceFromOrigin) {
universe.transform.position -= spaceship.transform.position;
spaceship.transform.position = Vector3.zero;
}
}
``````

Now, the actual problemâ€¦
When accelerating very fast and very far, and the FloatingOrigin script already reset the position/velocity a few times, at some point, with the forward key input pressed, the spaceship starts rotating on itâ€™s X axis for no reason.
When trying to accelerate sideways, it actually rotates on itâ€™s Y axis.
It seams to be happening on a very random base, but mainly (or maybe only) when the FPS drops much lower than 20 FPS, which is about half my Fixed Timestep of 0.02 Iâ€™ve set in the project settings.

It seams to be caused by the velocity reset of the spaceship, doesnâ€™t matter if the position is also being reset or not.

When I disable this FloatingOrigin script, everything works fine (except for that shaking effects of the floating point precision of course), it never rotates no matter how much I accelerate or how far I go from the origin.

Anyone has a clue on this issue ? Is it a bug in Unity or in the way Iâ€™m using it ?
Thanks for the help !

Edit : FirstPersonController does not use the built-in scripts. Itâ€™s homemade and it`s movement is disabled when attached to (controlling) the spaceship.
Also, this FirstPersonController does not collide with the spaceship as itâ€™s position is forced in the middle of the spaceship (see script above), not touching the walls.

The spaceship used for this test is simply 5 stretched cubes surrounding the FirstPersonController.

Satellites in orbit will tumble around. Thereâ€™s no glitch or mistake, but I think an error in your spacecraftâ€™s design. You need some way of returning your rotation to the desired velocity, so stabilizers. When youâ€™re flying through space your ship may start to do just that same thing. If you want to do it cheaply, add angular drag.

The rotation was NOT a simple angular imprecision that decays over time, but rather it was a sudden, quick and steady rotation, exacly like if I had manually set an angular velocity to a very big value, since it was rotating Very fast.

Setting an angular drag simply makes the rotation to slow down after a whileâ€¦ but when it starts to rotate itâ€™s instantaneous and happens suddenly.
I guess I forgot to mention this small detail.

I found out that calling the FloatingOrigin calculations on FixedUpdate instead of LateUpdate solved the problem (I think).
Still not sure whyâ€¦

But anyways Iâ€™m still having issues with collision detection using 32bit floatsâ€¦ Iâ€™m going to use a Double precision physics system, if I find any, Or I would have to code it myself.
Would you happen to know about a physics library in the asset store that supports 64bit floats ?
Thanks

No, and Iâ€™m still not sure what youâ€™re trying to do, either. I am trying to visualize the need for numbers larger than floats but I guess I donâ€™t see it.

This guy describes what you are proposing in detail. You do indeed need a double precision object system outside of the Unity coordinate space. No idea how you go about constructing it. Very interesting though.

Full thesis

http://www.floatingorigin.com/ThorneThesis.pdf

The problem has been solved for a while now, but thanks anyways.

For others who experience the same problem, you simply need to put your ResetToOrigin script in the FixedUpdate instead of LateUpdate or Update like in the original script.

The reason is simple :
FixedUpdate is for everything physics related (both static objects movements and rigidbody stuff).
Update and LateUpdate are for rendering.
These two ARE NOT synchronized !

When resetting a velocity in the rendering frame, two physics calculations can happen on the Same rigidbody WHILE resetting the velocity, especially while rendering FPS is low, thus the physics (FixedUpdate) FPS will be higher.
Unity calculates every object using their Absolute positions, thus resetting a rigidbodyâ€™s parent objectâ€™s velocity will affect itâ€™s childrenâ€™s positions and rotations.
This will cause â€śun-normalizedâ€ť vectors on other physics parameters like torque, hence causing unexpected, sudden rotations, when the numbers are normalized by the physics engine.

For my game I ended up creating my own server-side physics system in double-precision, and Unity simply receives positions of everything else in single precision relative to the camera.

3 Likes