Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Determine which face of a cube is facing the camera

Discussion in 'Scripting' started by Mohamed-Ted, Apr 7, 2015.

  1. Mohamed-Ted

    Mohamed-Ted

    Joined:
    Mar 1, 2015
    Posts:
    3
    I have a Cube with a unique color for each face. I made a script where I can swipe and rotate the Cube in increments of 90 degrees in each direction. what's the best way to determine which face of a the Cube is facing the camera.
     
  2. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    Does your camera move, and does the cube only rotate on one axis? If yes can figure it out just by looking at the cubes rotation.

    Otherwise if you could use a raycast from the camera and its hit info to get the triangle I'd or the UV coord of the hit, and keep a list of what color each triangle is to reference back.
     
  3. Mohamed-Ted

    Mohamed-Ted

    Joined:
    Mar 1, 2015
    Posts:
    3
    thanks for your answer.
    Yes the camera is fixed, but the cube will rotate on different axis.
    I tried to compare the current rotation of the cube with the possible rotation but I can't figure out how many are they.
    also do you have some examples on how to use raycasting (this is my first project in unity)
     
  4. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    well here is a possible way of many of doing this.

    make sure your cube is using a mesh collider instead of a box collider, since this works by reading the triangleID from the collider than looking up a color by id in a list.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CubeSide : MonoBehaviour
    5. {
    6.     private Color[] colors =
    7.     {
    8.         Color.red, Color.red, Color.green, Color.green, Color.blue, Color.blue,
    9.         Color.yellow, Color.yellow, Color.black, Color.black, Color.white, Color.white,
    10.     };
    11.  
    12.     private void Update()
    13.     {
    14.         if (Input.GetMouseButtonDown(0))
    15.         {
    16.             RaycastHit hit;
    17.             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    18.             if (Physics.Raycast(ray, out hit))
    19.             {
    20.                 Debug.Log(colors[hit.triangleIndex]);
    21.             }
    22.         }
    23.     }
    24. }
    25.  
    the reason why i got entries for each of the 6 colors is because this reads the triangleID, and it takes 2 triangles to make a cubes face.


    a other possible way of doing this could be to have 6 gameObjects with there own colliders parted under the cube and alinged to each face, and just find the color based on which one got the rayhit.
     
  5. mcapousek

    mcapousek

    Joined:
    Jan 11, 2013
    Posts:
    9
    I would calculate dotX = Vector3.Dot( camDir, cubeXaxis ), same for dotY and dotZ. Then select extreme ( now you will know if its right/let, top/bottom or front/back) and based on its sign if its right or left, ...
     
  6. Mohamed-Ted

    Mohamed-Ted

    Joined:
    Mar 1, 2015
    Posts:
    3
    I appreciate both your answers guys thank you so much.
    this is what I ended up doing:
    Code (CSharp):
    1.  
    2. using System.Collections.Generic;
    3. .
    4. .
    5. .
    6. Dictionary<Vector3, Face> Faces = new Dictionary<Vector3, Face>()
    7.  {
    8.         {new Vector3(0.0f, 0.0f, 1.0f), Face.Yellow},
    9.         {new Vector3(0.0f, -1.0f, 0.0f), Face.Blue},
    10.         {new Vector3(0.0f, 0.0f, -1.0f), Face.Pink},
    11.         {new Vector3(0.0f, 1.0f, 0.0f), Face.Purple},
    12.         {new Vector3(-1.0f, 0.0f, 0.0f), Face.Green},
    13.         {new Vector3(1.0f, 0.0f, 0.0f), Face.Red},
    14. };
    15. enum Face { Yellow, Blue, Pink, Purple, Green, Red };
    16. .
    17. .
    18. .
    19. void updateFace () {
    20.         var x = Mathf.Round(Vector3.Dot(Camera.main.transform.forward, transform.right));
    21.         var y = Mathf.Round(Vector3.Dot(Camera.main.transform.forward, transform.up));
    22.         var z = Mathf.Round(Vector3.Dot(Camera.main.transform.forward, transform.forward));
    23.      
    24.         Debug.Log(Faces[new Vector3(x, y, z)]);
    25. }
     
  7. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    The easiest way would be to Raycast from each face this.transform.forward, this.transform.right, this.transform.up and the negation of those will get you all the faces. Based on the RaycastHitInfo object take the crossproduct, if you get a zero vector then the face is facing the camera. Or what you can do is take the angle between the two vectors. The closer to 0 the more the two vectors are pointing in the same direction, you can create a threshold and cross check that.
     
  8. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    So this will log the face of the cube that is currently in view of the camera. Your code is hardcoded for the Up, Down, Right, Left of a cube that is static on X, and Z axis. The code below does not matter of the orientation of the camera it will always give you the correct face even if it twists or rotates.


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CubeFace : MonoBehaviour {
    5.     [SerializeField] float threshHold = 5.0f;
    6.     [SerializeField] float rayLength = 1.0f;
    7.  
    8.     void LateUpdate() {
    9.         UnityEngine.Debug.DrawRay(this.transform.position, this.transform.up * this.rayLength, Color.red);
    10.  
    11.         UnityEngine.Debug.DrawRay(this.transform.position, -this.transform.up * this.rayLength, Color.magenta);
    12.  
    13.         UnityEngine.Debug.DrawRay(this.transform.position, this.transform.forward * this.rayLength, Color.blue);
    14.  
    15.         UnityEngine.Debug.DrawRay(this.transform.position, -this.transform.forward * this.rayLength, Color.cyan);
    16.  
    17.         UnityEngine.Debug.DrawRay(this.transform.position, this.transform.right * this.rayLength, Color.yellow);
    18.  
    19.         UnityEngine.Debug.DrawRay(this.transform.position, -this.transform.right * this.rayLength, Color.gray);
    20.  
    21.         // theta = arcos( a • b / |a| • |b|)
    22.         float upAngle = Mathf.Acos(Vector3.Dot(this.transform.up, Camera.main.transform.forward) / (this.transform.up.magnitude * Camera.main.transform.forward.magnitude));
    23.         upAngle *= 180.0f / Mathf.PI; // In Degrees not radians.
    24.  
    25.         float downAngle = Mathf.Acos(Vector3.Dot(-this.transform.up, Camera.main.transform.forward) / (this.transform.up.magnitude * Camera.main.transform.forward.magnitude));
    26.         downAngle *= 180.0f / Mathf.PI; // In Degrees not radians.
    27.  
    28.         float forwardAngle = Mathf.Acos(Vector3.Dot(this.transform.forward, Camera.main.transform.forward) / (this.transform.forward.magnitude * Camera.main.transform.forward.magnitude));
    29.         forwardAngle *= 180.0f / Mathf.PI; // In Degrees not radians.
    30.  
    31.         float backwardAngle = Mathf.Acos(Vector3.Dot(-this.transform.forward, Camera.main.transform.forward) / (this.transform.forward.magnitude * Camera.main.transform.forward.magnitude));
    32.         backwardAngle *= 180.0f / Mathf.PI; // In Degrees not radians.
    33.  
    34.         float rightAngle = Mathf.Acos(Vector3.Dot(this.transform.right, Camera.main.transform.forward) / (this.transform.right.magnitude * Camera.main.transform.forward.magnitude));
    35.         rightAngle *= 180.0f / Mathf.PI; // In Degrees not radians.
    36.  
    37.         float leftAngle = Mathf.Acos(Vector3.Dot(-this.transform.right, Camera.main.transform.forward) / (this.transform.right.magnitude * Camera.main.transform.forward.magnitude));
    38.         leftAngle *= 180.0f / Mathf.PI; // In Degrees not radians.
    39.  
    40.         if(upAngle < this.threshHold) {
    41.             UnityEngine.Debug.Log("Top Face is facing the Camera");
    42.         }
    43.  
    44.         if(downAngle < this.threshHold) {
    45.             UnityEngine.Debug.Log("Bottom Face is facing the Camera");
    46.         }
    47.  
    48.         if(forwardAngle < this.threshHold) {
    49.             UnityEngine.Debug.Log("Forward Face is facing the Camera");
    50.         }
    51.  
    52.         if(backwardAngle < this.threshHold) {
    53.             UnityEngine.Debug.Log("Backward Face is facing the Camera");
    54.         }
    55.  
    56.         if(rightAngle < this.threshHold) {
    57.             UnityEngine.Debug.Log("Right Face is facing the Camera");
    58.         }
    59.  
    60.         if(leftAngle < this.threshHold) {
    61.             UnityEngine.Debug.Log("Left Face is facing the Camera");
    62.         }
    63.     }
    64. }