I saw this one all over the web, but I couldn’t find the solution for my specific problem. This is to help any other new people having this problem. What there isn’t a fix for(I couldn’t find it) is getting rid of the error message in the console. The reason for getting rid of the error message in the console is due to performance(I was losing about 600+ FPS(yes, that much) when it was checking for the error). Debugging always gives a performance hit, so here is how to get rid of it to gain that performance back.
// Script isn't perfect. For example purposes.
void Movement()
{
float axisX = Input.GetAxis("Horizontal");
float axisY = Input.GetAxis("Vertical");
float axisCombined = axisY / axisX;
float speed = 5f;
// The fix is here. Just add a very small value to the float
// to get rig of the error. In this case, it's axisX
Vector3 movement = new Vector3(axisX + 0.001f, 0.0f, axisY);
rbody.AddForce(movement * speed, ForceMode.Acceleration);
Quaternion newRotation = Quaternion.LookRotation(movement);
if(axisCombined >= 0.1f || axisCombined <= 0.1f)
{
transform.rotation = Quaternion.Slerp
(transform.rotation, newRotation, 20 * Time.deltaTime);
}
}
This error message pops when you try to call a rotation method towards a vector zero (0,0,0).
You can easily fix this using an if statement before calling the quaternion methods that pop this error.
if (movement != Vector3.Zero) {
// Do the rotation here
}
or
if (movement.Magnitude > EPSILON) { // Where EPSILON is a very small number
// Do the rotation here
}
I agree you should not use Vector3.magnitude unless you need an important distance calculation, as it computes the square root, a costly calculation. If you’re just comparing which of two things is farther, you would want to use Vector3.sqrMagnitude instead.
It doesn’t seem to be common knowledge, but the Vector3 operator for comparing equality (==) automatically includes an epsilon-based comparison, and if you want to be more explicit, you can use Vector3.Equals(). So saying velocity == Vector3.zero is already saying “it is effectively stopped.”
That isn’t a real solution to the problem, as it only shifts the error (and in this particular case, it has the slight advantage of decreasing the probability of the error popping up, as the input will rarely be equal to the small constant value that you add).
Suppose F(x) where x = 0 causes an error, i.e F(0) => error
You cannot fix it by adding a constant, as in F(x + c), because it fails when x = - c, as in F(-c + c) = F(0).
You must either avoid the call when x=0, or only add a small value when x=0, so that 0 is never passed.
The same applies when Vector.Zero causes an error.
Why doesn’t it just not rotate when the resulting rotation is ZERO. Is the performance cost worth having us check the sqrMagnitude to avoid computing the look rotation?
It definitely does “just not rotate”, but if you call Quaternion.LookRotation(Vector3.zero), then there’s probably a problem with whatever code leads up to that so the engine prints out that warning to let you know there’s an issue. Checking if a vector is != zero is essentially zero performance cost.
The resulting rotation is not “zero”. You simply can’t construct a valid quaternion / rotation when the direction vector is zero. The code behind LookRotation is similar to what is shown in this answer. You can not normalize the zero vector as it doesn’t represent any direction.
I’ve got this erro using Vector3.zero, I changed by Vector3.one; and the error is gone. Because there are no vector3.zero rotation, you must use a number.
FYI there is a Quaternion.identity value which represents the concept of “no rotation”, which is somewhat analogous to Vector3.zero for vectors. This may be the appropriate value to use for code which is expected to generate a Quaternion in all cases:
@StarManta I’m saying it should just default to Quaternion.Indentity when it sees a Vector3.zero instead of complaining about it. Now their code tests for it and my code test for it to avoid the error. What other intention than Quaternion.Identity would anyone feeding it a value of 0,0,0 have?
It’s inconvenient but I guess I can see why there’s an error. Quaternion.LookRotation(Vector3.zero) asks for a look rotation to nowhere, which is sort of nonsensical. I think it’s reasonable for the API to require the programmer to write sensible instructions - instead of asking LookRotation for a rotation to nowhere, you can just yield Quaternion.identity instead to clarify your intent. I guess the API designer’s assumption was that if programmers are asking for a look rotation to nowhere, they’ve likely done something wrong.
On the other hand, it looks like Quaternion.identity exists specifically to represent the concept of “rotation to nowhere”… so I see where you’re coming from, too.
In any case if it’s very bothersome, a utility function which implements my snippet from above solves the issue.
I think it’s more like ‘2022 and some folk still can’t tell a bug from a feature’. You can’t get a rotation from zero - there is nowhere to face, and nothing for the code to conjure a Quaternion from as the only reference point you give it is the relevant direction - which is somehow where the observer is stood. Try and look in the direction of the focal point of your own eyeball and tell me which way you’re facing; I can’t manage it but something tells me it’s tricky.
Either live with the performance cost of the console error (which is massive, don’t do this), or go through the mild inconvenience of writing a wrapper for LookRotation that includes checking for Vector3.zero and decides what to do about it in a way appropriate to your use-case. Local functions are good for this, as the use-cases are usually highly specific.