- Home /
Need help with the movement+rotation C# script
I'm just starting to learn Unity and I've written a basic script for discrete movement + rotation in C#, using a movement script I found online as a basis. It uses WASD to move the rigid body around (without rotating it) and Q and E to rotate it 90 degrees left and right. It seems to work for the most part - however, the z coordinate behaves a bit weird when I follow a route that combines movement and rotation.
Namely, if I start moving from point A(x,y,z) and move forward->rotate right->move forward->rotate right->move forward->rotate right->move forward, coming back to point A again, the new z' coordinate is slightly different from the starting one. As a result, I arrive to point A'(x,y,z') instead of the original A(x,y,z). Same goes for rotating left.
That must have something to do with rotation, because if I only use the WASD movement (without rotation), my rigidbody returns to the same starting coordinates A(x,y,z) without any problem.
To illustrate, here are some screenshots. Starting position. The coordinates are (0, 10, 0).
Movement (small gif):
Resulting position. The coordinates are (0, 10, -1.490116e-08).
Where does the "-1.490116e-08" come from and how do I get rid of it? Here is my script:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (Rigidbody))]
[RequireComponent (typeof (CapsuleCollider))]
public class Movement_new : MonoBehaviour {
public float speed = 1.0f;
private Vector3 endpos;
private bool moving = false;
private float rotationVal = 0.0f;
private Quaternion qTo;
void Start () {
endpos = transform.position;
qTo = transform.rotation;
}
void Awake () {
rigidbody.freezeRotation = true;
rigidbody.useGravity = false;
}
void Update () {
if (moving && (transform.position == endpos) && (transform.rotation == qTo))
moving = false;
if(!moving && Input.GetKeyDown (KeyCode.W)){
moving = true;
endpos = transform.position + transform.forward;
}
if(!moving && Input.GetKeyDown (KeyCode.S)){
moving = true;
endpos = transform.position - transform.forward;
}
if(!moving && Input.GetKeyDown (KeyCode.A)){
moving = true;
endpos = transform.position - transform.right;
}
if(!moving && Input.GetKeyDown (KeyCode.D)){
moving = true;
endpos = transform.position + transform.right;
}
if (!moving && Input.GetKeyDown (KeyCode.E)) {
moving = true;
rotationVal += 90.0f;
qTo = Quaternion.Euler (0.0f, rotationVal, 0.0f);
}
if (!moving && Input.GetKeyDown (KeyCode.Q)) {
moving = true;
rotationVal -= 90.0f;
qTo = Quaternion.Euler (0.0f, rotationVal, 0.0f);
}
transform.rotation = Quaternion.RotateTowards (transform.rotation, qTo, 100 * Time.deltaTime);
transform.position = Vector3.MoveTowards(transform.position, endpos, Time.deltaTime * speed);
}
}
I'm new to Unity and programming alike, so I must be doing something wrong. Any comments/advice would be much appreciated.
It's such a small number, a few things come to $$anonymous$$d first. It might be the friction of the rigidbody (try turning that off). Also, to be sure, you could try the following:
qTo = Quaternion.Euler (qTo.rotation.x, qTorotation.y+rotationVal, qTo.rotation.z);
Well it is just a precision error of the computer, unity is working in floats that is basically 7 digits precision so "-1.490116e-08" is actually Zero, I don't think you have to worry about that nor that it may cause you position issues.
Answer by tanoshimi · Jun 19, 2014 at 11:08 AM
Hi,
First of all, welcome to UA, and thanks for taking the time to write a detailed description (and animated gifs!) of your problem.
"-1.490116e-08" is scientific notation for the number -0.00000001490116 which is a number very, very close to zero (the coordinate value you were expecting) but not quite.
If you're new to programming then this might come as a bit of a surprise, but a lot of calculations performed by computers are not as precise as you think they might be, because they're based on floating-point arithmetic (that's what the float
keyword and the F
you see after some numbers refers to).
When you work with integers, 0 + 10 - 10 = 0 exactly, on the nail. When you work with floats, it might not be.
There's nothing you're doing wrong, and there's nothing you need to do to "fix" it, other than the fact you should never expect nor try to work with floating point numbers as if they contain exact values, because they don't - there's an inherent degree of imprecision in floating-point maths.
Thanks! I wasn't aware that float number calculations work like that. I'll be sure to keep that in $$anonymous$$d.
Your answer
Follow this Question
Related Questions
Player rotating towards direction of movement in 3D 1 Answer
Flip over an object (smooth transition) 3 Answers
Determining the rotation of an object based on its upcoming position? 1 Answer
Rotating character to a direction (2.5d) 1 Answer
Unity 2D movement and rotate sprite to the direction it is moving in 1 Answer