This script should lead a box through a track of markers/ points of interest. Everytime It touches a point/ marker (Which is an empty on the scene) It calculates a straight line towards the next marker.
For this, a virtual Game Object called “pos” is created, this will use a looktowards to be always facing the next marker. Then if the angulation of pos is bigger than the box angulation, the box spins right till it matches, if the box angulation is bigger, it turns left instead.
It worked for the track to the first and between the first and fourth of 5 markers I’ve placed, But in certain cases (like for the fourth to the fifth markers track: Box angulation = -78.317, pos angulation = -168.232), for some reason the box spins right instead.
curmar => Current Marker;
markers => Array of all markers (5)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TrackFollower : MonoBehaviour
{
public GameObject[] markers;
private GameObject curmar;
private GameObject pos;
private float speed;
private float step;
private int index;
void Start ()
{
pos = new GameObject ("G?ostly_EntIty3443-103.b");
pos.transform.position = new Vector3 (this.transform.position.x, this.transform.position.y, this.transform.position.z);
speed = 50;
step = speed * Time.deltaTime;
index = 0;
curmar = markers[0];
for (int i = 0; i < 5; i++)
{
Debug.Log (markers[i]);
}
}
void Update ()
{
curmar = markers[index];
pos.transform.LookAt (curmar.transform);
pos.transform.position = new Vector3 (this.transform.position.x, this.transform.position.y, this.transform.position.z);
Follow ();
}
void Follow ()
{
if (transform.rotation.y < pos.transform.rotation.y)
{
this.transform.Rotate (new Vector3 (0, 70 * Time.deltaTime, 0));
transform.position = Vector3.MoveTowards(transform.position, curmar.transform.position, step);
Debug.Log ("RIGHT");
}
else if (transform.rotation.y > pos.transform.rotation.y)
{
this.transform.Rotate (new Vector3 (0, -70 * Time.deltaTime, 0));
transform.position = Vector3.MoveTowards(transform.position, curmar.transform.position, step);
Debug.Log ("LEFT");
}
}
void OnTriggerEnter ()
{
if (index < 4)
{
index += 1;
}
// else
// {
// index = 0;
// }
Debug.Log("Touched");
}
}
If I had to guess, I would posit a scenario where the target is at y rotation -170 and the traveling object is at y rotation 170…or something along those lines.
Did you debug.log both transform.rotation.y and pos.transform.rotation.y to make sure you are getting expected values (not just look in the inspector, but print out the values to the console)
I’ve Debugged “Touched”, when It hits a marker, and then “left” if it’s heading left spin, and “right” if it’s going to spin right. After it touches the fourth marker it prints “right” and spins the same way, when it should print left and go same direction. It is simply falling into the wrong if sentence, even without matching it’s conditions.
So…you didn’t debug the two things to make sure they give you the value you expect? You want to know why it’s not using the if you expect it to, but you don’t know which values it’s even using? I don’t think it’s a bug. You’re comparing two floats, and it’s not just going to mess that up.
@methos5k Don’t feel bad, Quaternions aren’t always the easiest to understand. I haven’t really looked into them much myself. For eulerAngles, I feel like there was another issue with those. But I may be thinking of something else with rotations. So eulerAngles may be the solution.
I don’t feel too badly. I don’t know how to use Quaternions directly, but I try to further my confidence & understanding to use them decently well in Unity
The reason I thought that maybe the comparison wasn’t working as expected was because I thought maybe the rotation.y could be different … um, “than expected” . ( I found some graphing/comparison tool online for Quats and Eulers, and could get some conversions that I think supported this**). Anyways, doesn’t hurt to try.
Tryed EulerAngles now, but for the times the rotation was right now it’s inverted, and when the problem ocurred it just hit the mark and stopped at in spacetime at all
I know the values, they were exatcly the ones I used (Box angulation = -78.317, pos angulation = -168.232) I was keeping up with it through the Inspector.
You mean you had a public variable with the values or you just looked at the transform? It’s not going to run the wrong if statement just because. Which is why I suggested debug.logs. So per your question, why is it taking the wrong if? Because that if is what evaluates to true when the if statement is checked.
One thing I’ve not written but has been on my mind is asking you how important left/right is. Would using rotatetowards or anything that gives a similar result be acceptable to you? In the sense of getting to the same rotation, I mean.
Euler angles can be represented in more than 1 way, I believe.
Plus, when you’re using rotation, that is the Quaternion value (not what you’re seeing in the inspector, usually).
Note that what you see in the inspector won’t always match what you get with transform.eulerAngles.
The latter is derived from the Quaternion, and so it will “loop around” IIRC - for example 300 + 150 = 90, not 450.
The inspector, on the other hand, keeps track of what specific numbers you entered, so if you enter 450 it stays 450.
So to echo what many other people are saying, log the exact value you are comparing to the console. The Debug.Log statement should be literally on the line before the comparison.
Also, while there are exceptions, it usually makes more sense to derive your angles from a field you control, and do comparisons / operations on that field instead.
so this is the usual behaviour of any of the gameobjects in the 3d world. When you have a huge difference between the values that usually incur in a flipping of a rotation of the object. you cannot simply ask it to rotate. but you will have to specify an axis in which it has to rotate, only then the positive and negative values will work:
reference:
else otherwise you can try slerp. this also works well: