Brace yourselves, I have a few questions but I will try to be as clear as I can. There is a TL;DR at the bottom.
Ever since I have started using Unity I feel like I am always wrestling with inaccurate calculations, especially whenever I am dealing with movement. My latest endeavors require that I calculate the angular velocity of my character controller so naturally I had a look around the internet to see if someone had already invented the wheel. I happened upon this thread which ended up being pretty useful.
Anyways, the code given in the 18th post (by BenZed) ended up worked pretty well but as he notes in his post, āit does seem to fluctuate somewhatā. I ended up tweaking it slightly to try and remove these fluctuations and the following is what I ended up with.
using UnityEngine;
using System.Collections;
public class ConstantSpin : MonoBehaviour
{
RotationTracker rotationTracker;
private Quaternion lastRotation;
private Quaternion newRotation;
void Start()
{
rotationTracker = GetComponent<RotationTracker>();
lastRotation = transform.rotation;
}
void Update()
{
newRotation = Quaternion.Euler(new Vector3(90.0f, 90.0f, 0.0f) * Time.deltaTime) * lastRotation;
transform.rotation = newRotation;
lastRotation = newRotation;
}
void LateUpdate()
{
Debug.Log(rotationTracker.angularVelocity.magnitude);
}
}
using UnityEngine;
public class RotationTracker : MonoBehaviour
{
//Holds the previous frames rotation
Quaternion lastRotation;
//References to the relevent axis angle variables
float magnitude;
Vector3 axis;
public Vector3 angularVelocity
{
get
{
//DIVDED by Time.deltaTime to give you the degrees of rotation per axis per second
return (axis * magnitude) / Time.deltaTime;
}
}
void Start()
{
lastRotation = transform.rotation;
}
void LateUpdate()
{
Quaternion deltaRotation = transform.rotation * Quaternion.Inverse(lastRotation);
deltaRotation.ToAngleAxis(out magnitude, out axis);
lastRotation = transform.rotation;
}
}
So these two scripts are attached to a cube in the scene and thatās it. The first script rotates the cube by a constant vector of (90, 0, 90) every second. The second script attempts to record the change in rotation (deltaRotation) and has a read only property called angularVelocity that returns just that.
The main thing I did was move the rotation tracking logic and the debug log call to LateUpdate(), the reasoning being that slight differences in when the two scripts update may be causing the fluctuation in the reported angular velocity. This did seem to fix most of the wildly large fluctuations recorded, but the small ones remained.
One of the most annoying fluctuations is this large one that always happens in the third debug log.
Here are the magnitudes from message 1:
And here are the vector results from message 1:
From my calculations the magnitude results are pretty close, the vector (90, 0, 90) should have a length of about 127.2792, however, the printout of the vector itself seems rather strange to me. I expected both x and z to be 90 (or close to it), but I expected y to be 0 (although this may be due to a lack of understanding in vector math on my part, please correct me if I am wrong). Lastly, the y value seems to crash down to a much lower value in log three which correlates with the sudden drop in vector magnitude in log three in the first image. This is strange because the other two values seem to drop very little comparatively.
Luckily the fluctuations seem to be very small and steady after the first couple frames, and I could live with the fact that the first couple frames of playing in the editor are wacky, but it leaves me wondering why there are even spikes like this at all if the code does what I think it does (and Time.deltaTime doesnāt lie). If the spike is frame-rate dependent, then will my gameās code malfunction later on mid-play? I hate seeing data like this because I know not addressing it now will bite me in the ass down the road when there are many more variables at play.
Also I stripped out all the pieces of code I could and even when both uses of Time.deltaTime are removed the code still spits out fluctuating values (try small values like vector like (5, 0, 5) as the code seems to behave erratically when the cube is spinning too fast).
TL;DR
I guess what Iām really asking is: are inaccuracies in time-based values (e.g. movement or angular velocity) just something that game developers live with (like floating point error), or should I continue to assume that something is wrong with the code? It really bothers me that a calculation this basic would fluctuate at such low levels of precision, but if this kind of fluctuation is to be expected then it will put my mind at rest and I will be able to focus on coding to account for it instead of feverishly spending hours trying to debug it.
To anyone who read all of this I thank you,
~PartyBoat