I’m really confused about this issue. Blank project and scene. I wrote a small debug piece of code and found troubles.
using UnityEngine;
public class DirDebug : MonoBehaviour {
public Vector3 dir;
void Start () {
dir = transform.forward;
Debug.Log(transform.forward);
Debug.Log(dir);
}
}
It works fine when I do not rotate an object.
But when I do, it breaks somehow The main problem is it’s not only inspector showing infinite numbers, it also affects transform.translate, transform.lerp etc. so I can’t properly move objects.
That’s not an infinite number. It’s a number that is almost infinitely close to 0. This is caused by floating point issues (Google around a bit about the topic, computers can not represent floating point numbers with 100% accuracy).
You don’t need to worry much about it. The inspector does that sometimes instead of displaying “0”.
This is scientific notation, a way of writing very large or very small numbers. In this case, the e-07 means 10^-7, or 0.0000001. The value of the whole number is therefore -1.192093 * 0.0000001, which is easily within the margin of error that comes with any floating point value.
`` (It's 0 :))[/SIZE][/FONT][/FONT]
Thanks for your answers. The problem is that transform.Translate(transform.forward * speed) only works with 2 directions. When I have 90 degrees rotation, it still moves along x axis, when it supposed to move along z axis.
You simply add this function and the problem occurs.
using UnityEngine;
public class DirDebug : MonoBehaviour {
public Vector3 dir;
void Start () {
dir = transform.forward;
Debug.Log(transform.forward);
Debug.Log(dir);
}
void Update()
{
transform.Translate(dir * 0.1f);
}
}
Each mesh is a parent and has no child, has only this script attached.
Few frames later:
The missiles are supposed to move forward, but they only move along one axis.
even though I remove dir variable and paste just transform.Translate(transform.forward * 0.1f) nothing changes.
Try putting the DirDebug script on an empty GameObject, then making the mesh itself a child object of that. It’s considered bad practice to put scripts directly on meshes, and should make this particular issue easier to comprehend. make sure the mesh’s transform has 0 for all the values, for simplicity. This should result in the arrow pointing along the parent’s local X-axis, and that should be the case for every instance of this object.
I’ve made a workaround, simply sent a message with direction it should follow, according to player’s rotation, but still curious what’s the problem with transform.forward.
The reason it’s acting weird is because you’re basically rotating twice. In Start(), you set dir to transform.forward (which is based on transform.rotation). In Update(), you then use dir in transform.Translate, which move by the supplied vector in local space - in other words, .Translate applies rotation again.
If you use transform.Translate(Vector3.forward) it’ll move forward.
Also, if you’re doing movement in Update(), you’ll want to multiply it by Time.deltaTime, so that it moves indpendent of the framerate. (Otherwise, if your game runs at 60fps, your arrow will shoot twice as fast as if your game were running at 30fps)
As I said, here is the code. I agree that if you swap transform with Vector3, translate works fine, but making this with lerping position doesn’t do the trick. The whole problem is that system reads transform.forward in a wrong way, adds various numbers when GO’s rotation isn’t zero. Correct if I’m wrong
void Start() {
dir = transform.forward;
StartCoroutine(Move());
}
public IEnumerator Move()
{
startPosition = transform.position;
t = 0;
endPosition = new Vector3(startPosition.x + System.Math.Sign(dir.x) * 1,
startPosition.y, startPosition.z + System.Math.Sign(dir.z) * 1);
i
while (t < 1f)
{
t += Time.deltaTime * (speed / 1);
transform.position = Vector3.Lerp(startPosition, endPosition, t);
yield return null;
}
isMoving = false;
yield return 0;
}
OK, that output, along with your code, helps a lot. What’s happening here is that that tiny number - the “effectively zero” - is becoming your issue, thanks to Math.Sign. Normally those tiny numbers can be ignored, but because it’s not exactly zero, Math.Sign is turning it into a full-sized -1.
I’d suggest adding something like this after you set your ‘dir’:
if (Mathf.Abs(dir.x) < 0.0001f) dir.x = 0f;
if (Mathf.Abs(dir.z) < 0.0001f) dir.z = 0f;
That should turn your “effectively zero” into “actually zero”.
Yeah that’s a nice workaround, but is still a workaround Somebody have to report a bug, if it’s considered a bug, since it doesn’t work as intended. Thanks for your effort, you helped a lot for understanding an issue!