Search Unity

Why is My Object Taking the Wrong If?

Discussion in 'Scripting' started by FGPArthurVII, Oct 31, 2017.

  1. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    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)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class TrackFollower : MonoBehaviour
    6. {
    7.     public GameObject[] markers;
    8.     private GameObject curmar;
    9.     private GameObject pos;
    10.  
    11.     private float speed;
    12.     private float step;
    13.     private int index;
    14.  
    15.     void Start ()
    16.     {
    17.         pos = new GameObject ("G?ostly_EntIty3443-103.b");
    18.         pos.transform.position = new Vector3 (this.transform.position.x, this.transform.position.y, this.transform.position.z);
    19.         speed = 50;
    20.         step = speed * Time.deltaTime;
    21.         index = 0;
    22.         curmar = markers[0];
    23.  
    24.         for (int i = 0; i < 5; i++)
    25.         {
    26.             Debug.Log (markers[i]);
    27.         }
    28.     }
    29.  
    30.     void Update ()
    31.     {
    32.         curmar = markers[index];
    33.         pos.transform.LookAt (curmar.transform);
    34.         pos.transform.position = new Vector3 (this.transform.position.x, this.transform.position.y, this.transform.position.z);
    35.         Follow ();
    36.      
    37.     }
    38.  
    39.     void Follow ()
    40.     {
    41.         if (transform.rotation.y < pos.transform.rotation.y)
    42.         {
    43.             this.transform.Rotate (new Vector3 (0, 70 * Time.deltaTime, 0));
    44.             transform.position = Vector3.MoveTowards(transform.position, curmar.transform.position, step);
    45.             Debug.Log ("RIGHT");
    46.         }
    47.         else if (transform.rotation.y > pos.transform.rotation.y)
    48.         {
    49.             this.transform.Rotate (new Vector3 (0, -70 * Time.deltaTime, 0));
    50.             transform.position = Vector3.MoveTowards(transform.position, curmar.transform.position, step);
    51.             Debug.Log ("LEFT");
    52.         }
    53.      
    54.     }
    55.  
    56.     void OnTriggerEnter ()
    57.     {
    58.         if (index < 4)
    59.         {
    60.             index += 1;
    61.         }
    62. //        else
    63. //        {
    64. //            index = 0;
    65. //        }
    66.         Debug.Log("Touched");
    67.     }
    68. }
    69.  
    Can someone Help Me?


    Thanks;
    Arthur.
     
  2. MaxGuernseyIII

    MaxGuernseyIII

    Joined:
    Aug 23, 2015
    Posts:
    315
    Have you attached a debugger?

    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.
     
  3. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    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)
     
  4. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    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.
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I tried to pad my ignorance/lack of knowledge of Quaternions prior to posting this :)

    Do you want to check the '.eulerAngles.y' instead?
     
  6. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    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. :)
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    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.
     
  8. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    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
     
  9. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    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.
     
  10. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    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.
     
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Can't hurt to log the values you're testing :)

    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).
     
  12. Errorsatz

    Errorsatz

    Joined:
    Aug 8, 2012
    Posts:
    555
    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.
     
  13. iamvideep

    iamvideep

    Joined:
    Oct 27, 2017
    Posts:
    118
    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:
    https://docs.unity3d.com/ScriptReference/Transform.Rotate.html

    else otherwise you can try slerp. this also works well:
    https://docs.unity3d.com/ScriptReference/Transform.Rotate.html

    Let us know if this works.

    Cheers!
     
    MaxGuernseyIII likes this.