Search Unity

Compare two eulerAngles

Discussion in 'Physics' started by Geckoo, Jan 5, 2022.

  1. Geckoo

    Geckoo

    Joined:
    Dec 7, 2014
    Posts:
    144
    Hello everyone. I am making a project with cubes which rotate on a grid. I paint each cube with three colors - on a face and its opposite. A cube can touch another one when faces have the same colors. In other cases, it comes back to its previous place - and movement isn't possible. I am trying to find a way to compare cubes' eulerAngles checking if they are the same. However it is not enough because of a particularity - each color has been painted on two faces for each cube. Do you have an idea how I could check this state? I have to say that in my project, I don't use any collider or rigidbody - only physics. I could use colliders with tags to check if faces have the same color, but I want to avoid any collider. Thank you for your help.

    Take a look at these pictures so as to understand the main idea - main gameplay.
    https://img.itch.zone/aW1hZ2UvNjQ2MDE5LzQ1NjIyMDcucG5n/original/+aPbl/.png
    https://img.itch.zone/aW1hZ2UvNjQ2MDE5LzQ1NjIyMDgucG5n/original/fBOdgI.png
     
  2. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    467
    If I understood correctly, the colors correspond to the axes of the cube (Vector3s transform.right/.up/.forward)
    I assume you already have a way to find neighboring cubes, so lets say you have cubes A and B

    Code (CSharp):
    1. d = (A.transform.position - B.transform.position).normalized;
    2.  
    3. var isX_A = Mathf.Abs( Vector3.Dot( d, A.transform.right ) ) > 0.9f;
    4. var isY_A = Mathf.Abs( Vector3.Dot( d, A.transform.up ) ) > 0.9f;
    5. var isZ_A = Mathf.Abs( Vector3.Dot( d, A.transform.forward ) ) > 0.9f
    6.  
    7. var isX_B = Mathf.Abs( Vector3.Dot( d, B.transform.right ) ) > 0.9f;
    8. var isY_B = Mathf.Abs( Vector3.Dot( d, B.transform.up ) ) > 0.9f;
    9. var isZ_B = Mathf.Abs( Vector3.Dot( d, B.transform.forward ) ) > 0.9f;
    10.  
    11. var sameColorTouching =
    12.     isX_A == isX_B &&
    13.     isY_A == isY_B &&
    14.     isZ_A == isZ_B;
    This uses the fact, that the absolute of the dot product of two vectors is large if they point in the same or opposite direction and is close to zero when they are orthogonal to each other.
     
  3. Geckoo

    Geckoo

    Joined:
    Dec 7, 2014
    Posts:
    144
    Hello. Thank you for your help. I really appreciate.
    Yes! You understaood correctly - the colors correspond to the axis of the cubes.
    I did this code, but I guess that it could be improved.

    Code (CSharp):
    1.  
    2. // simple function to compare two values - return the higher
    3. private int returnHigher(int first, int second)
    4. {
    5.     if (first >= second)
    6.         return first - second;
    7.     else
    8.         return second - first;
    9. }
    10. (...)
    11. foreach (GameObject g in cc)
    12. {   // excludes cube player which are not in our radius
    13.     if (g != thisOne && Vector3.Distance(g.transform.position, thisOne.transform.position) < 1.33f)
    14.     {   // absolute them
    15.         int x = Mathf.Abs((int)thisOne.transform.eulerAngles.x);
    16.         int y = Mathf.Abs((int)thisOne.transform.eulerAngles.y);
    17.         int z = Mathf.Abs((int)thisOne.transform.eulerAngles.z);
    18.  
    19.         int xx = Mathf.Abs((int)g.transform.eulerAngles.x);
    20.         int yy = Mathf.Abs((int)g.transform.eulerAngles.y);
    21.         int zz = Mathf.Abs((int)g.transform.eulerAngles.z);
    22.         // in order to save values
    23.         int xxx = returnHigher(x, xx);
    24.         int yyy = returnHigher(y, yy);
    25.         int zzz = returnHigher(z, zz);
    26.              
    27.         if ((xxx == 0 || xxx == 180) && (yyy == 0 || yyy == 180) && (zzz == 0 || zzz == 180))
    28.             Debug.Log("it works as expected");
    29.         else
    30.             computeMove(-direction, thisOne, true, true);
    31.     }
    32. }
    33.  
    Now I want to test yours which could be better :)
     
    Last edited: Jan 5, 2022
  4. N1ghtSiren

    N1ghtSiren

    Joined:
    Dec 19, 2020
    Posts:
    5
    You can just use Mathf, it has some useful functions
    Code (CSharp):
    1.  
    2. Mathf.Max( first, second );
    3.  
    And compare using normalized and magnitude
    Code (CSharp):
    1.  
    2. //returns 0~2 range, depending on rotation difference
    3. //will return 2 if they are facing each other (180 deg)
    4. //will return 1 if they are on 90 degrees
    5. //will return 0 if they are facing the same direction
    6. private float ColorCheck(Transform playerCube, Transform targetCube)
    7. {
    8.     return ( playerCube.transform.eulerAngles.normalized - targetCube.transform.eulerAngles.normalized ).magnitude;
    9. }
    10.  
     
  5. Geckoo

    Geckoo

    Joined:
    Dec 7, 2014
    Posts:
    144
    Thank you everyone for your kind help. As we can read somewhere "without counsel purposes are disappointed: but in the multitude of counselors they are established". I really appreciate all your help. I did many tests, but finally the best solution has been given by tjmaul. This function is very stable, more than mine.

    @N1ghtSiren - your explanation is not bad, but it doesn't fit with some features in my project.
    However, thank you for your suggestion.

    I wish you the best, my friends. Thank you ++
     
    tjmaul likes this.