Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Chuck26 · Jun 11, 2011 at 10:43 AM · javascriptraycastingcubeclick

Detect face of cube clicked

Does anyone know a script where you can detect the face of an cube clicked and perform an action on it? Or can anyone write one that does that?

I'm guessing it's something to do with Raycasting.

Thanks

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jun 11, 2011 at 12:11 PM 1
Share

You have to be more specific. Other people write 1 page questions so you can understand what he want to do and where the problems are. You sound like you just asking for free code...

You have to do your stuff on your own. If you have problems you can ask a question.

4 Replies

· Add your reply
  • Sort: 
avatar image
8

Answer by Ultimationz · May 26, 2015 at 09:56 PM

You can detect the side of the cube via the following algo

 public enum MCFace
     {
         None,
         Up,
         Down,
         East,
         West,
         North,
         South
     }
 
 public MCFace GetHitFace(RaycastHit hit)
     {
         Vector3 incomingVec = hit.normal - Vector3.up;
 
         if (incomingVec == new Vector3(0, -1, -1))
             return MCFace.South;
 
         if (incomingVec == new Vector3(0, -1, 1))
             return MCFace.North;
 
         if (incomingVec == new Vector3(0, 0, 0))
             return MCFace.Up;
 
         if (incomingVec == new Vector3(1, 1, 1))
             return MCFace.Down;
 
         if (incomingVec == new Vector3(-1, -1, 0))
             return MCFace.West;
 
         if (incomingVec == new Vector3(1, -1, 0))
             return MCFace.East;
 
         return MCFace.None;
     }

Demo Video Bellow: https://dl.dropboxusercontent.com/u/53593879/ShareX/2015/05/2015-05-26_20-20-16.mp4

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image foodiggler · Dec 24, 2016 at 09:13 AM 1
Share

Thanks for this. But, I noticed clicking on the underside of a block did not work, since it returned None.

To get GetHitFace to return Down, had to change the following...

 if (inco$$anonymous$$gVec == new Vector3(0, -2, 0))
avatar image
3

Answer by Bunny83 · Jun 11, 2011 at 12:24 PM

Just some things you might need:

  • Input.GetMouseButtonDown to detect the mousclick

  • Camera.main.ViewportPointToRay to get a ray from the center of your camera

  • Physics.Raycast to perform a raycast against the scene

  • RaycastHit.triangleIndex to retrieve the index of the triangle you've hit.

  • Mesh to get access to the actual mesh (vertices,triangles)

  • Take a closer look at RaycastHit. It provides a lot information (hitpoint, surfacenormal, uvposition, barycentric coordinates,...).

Meshes don't have faces (from techincal view) they are made of triangles. So a cube-side is made of 2 triangles.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by dju4ic · Jun 11, 2011 at 04:16 PM

Using Raycasting: (I am also using a Mesh collider on a cube as opposed to the original box collider).. Hopefully this will save from the guessing game i had to go through. Remember though, this will only work for normal cubes of any size.

 if (triIndex == 0 || triIndex == 1) {
                 Debug.Log  ("Creating On: front - Of: " + myhit.collider.gameObject.name);
                 clone = Instantiate(toCreate, new Vector3 (xRndd, yRndd, (zRndd+1)), Quaternion.identity) as GameObject;
             }
             
             if (triIndex == 2 || triIndex == 3) {
                 Debug.Log  ("Creating On: top - Of: " + myhit.collider.gameObject.name);                    
                 clone = Instantiate(toCreate, new Vector3 (xRndd, (yRndd+1), zRndd), Quaternion.identity) as GameObject;
             }
             
             if (triIndex == 4 || triIndex == 5) {
                 Debug.Log  ("Creating On: back - Of: " + myhit.collider.gameObject.name);
                 clone = Instantiate(toCreate, new Vector3 (xRndd, yRndd, (zRndd-1)), Quaternion.identity) as GameObject;
             }
             
             if (triIndex == 6 || triIndex == 7) {
                 Debug.Log  ("Creating On: bottom - Of: " + myhit.collider.gameObject.name);
                 clone = Instantiate(toCreate, new Vector3 (xRndd, (yRndd-1), zRndd), Quaternion.identity) as GameObject;
             }
             
             if (triIndex == 8 || triIndex == 9) {
                 Debug.Log  ("Creating On: right - Of: " + myhit.collider.gameObject.name);
                 clone = Instantiate(toCreate, new Vector3 ((xRndd-1), yRndd, zRndd), Quaternion.identity) as GameObject;
             }
             
             if (triIndex == 10 || triIndex == 11) {
                 Debug.Log  ("Creating On: left - Of: " + myhit.collider.gameObject.name);
                 clone = Instantiate(toCreate, new Vector3 ((xRndd+1), yRndd, zRndd), Quaternion.identity) as GameObject;
             }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jun 11, 2011 at 04:23 PM 2
Share

For that task it's a bit overkill to use the triangle index...

You can use the hit normal to get the direction the side is facing. No need for such an if chain (which should at least have "else if"). Also the hit normal works with any type of colliders and is much less code. But you can't say what the OP wants to do...

avatar image dju4ic · Jun 11, 2011 at 04:29 PM 1
Share

understood, I just ripped this out of some commented code i had, and have it modified for some non-absolute objects. There are definitely too many variables still open that need to be accounted for in the OP. Everything is in the examples on the scripting resource as well as other postings on here. Reading up on raycasting in general should get you in the right direction

avatar image
0

Answer by GXMark · Jan 31, 2017 at 02:43 PM

Here is another example of using the following game object format

gameobject side0 side1 side_n

It combines meshes for shared materials. Built in face detection code with simple API

Initialise() Setup shared material for all sides SetSharedMaterial() The material that will be used for the shared material AddSelectables() Array of game objects e.g. side0, side1 which are selectable faces RemoveSelectables() Array of game objects which are deselected faces SelectableFaces() Returns the selectable faces DetectFace() Takes a raycast and mesh collider from some input manager and returns the gameobject hit

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class FaceSelection : MonoBehaviour
 {
     private List<MeshFilter> _combinedMeshFilters = new List<MeshFilter>();
 
     private Material _sharedMaterial = null;
 
     // Use this for initialization
     void Start ()
     {
         Initialize();
     }
     /*
     void Update()
     {
         if (Input.GetKeyDown(KeyCode.Alpha1))
             AddSelectables(new GameObject[] { GameObject.Find("Barrel_6Sided_5Mat/Side") });
         if (Input.GetKeyDown(KeyCode.Alpha2))
             AddSelectables(new GameObject[] { GameObject.Find("Barrel_6Sided_5Mat/Top") });
         if (Input.GetKeyDown(KeyCode.Alpha3))
             AddSelectables(new GameObject[] { GameObject.Find("Barrel_6Sided_5Mat/BevelTop") });
 
         if (Input.GetKeyDown(KeyCode.Alpha4))
             RemoveSelectables(new GameObject[] { GameObject.Find("Barrel_6Sided_5Mat/Side") });
         if (Input.GetKeyDown(KeyCode.Alpha5))
             RemoveSelectables(new GameObject[] { GameObject.Find("Barrel_6Sided_5Mat/Top") });
         if (Input.GetKeyDown(KeyCode.Alpha6))
             RemoveSelectables(new GameObject[] { GameObject.Find("Barrel_6Sided_5Mat/BevelTop") });
 
         /*
         if (Input.GetKeyDown(KeyCode.Alpha2))
             AddSelectables(new GameObject[] { GameObject.Find("Cube/Back") });
         if (Input.GetKeyDown(KeyCode.Alpha3))
             AddSelectables(new GameObject[] { GameObject.Find("Cube/Top") });
         if (Input.GetKeyDown(KeyCode.Alpha4))
             AddSelectables(new GameObject[] { GameObject.Find("Cube/Bottom") });
         if (Input.GetKeyDown(KeyCode.Alpha5))
             AddSelectables(new GameObject[] { GameObject.Find("Cube/Left") });
         if (Input.GetKeyDown(KeyCode.Alpha6))
             AddSelectables(new GameObject[] { GameObject.Find("Cube/Right") });
 
         if (Input.GetKeyDown(KeyCode.Alpha7))
             RemoveSelectables(new GameObject[] { GameObject.Find("Cube/Front") });
         if (Input.GetKeyDown(KeyCode.Alpha8))
             RemoveSelectables(new GameObject[] { GameObject.Find("Cube/Back") });
         if (Input.GetKeyDown(KeyCode.Alpha9))
             RemoveSelectables(new GameObject[] { GameObject.Find("Cube/Top") });
         if (Input.GetKeyDown(KeyCode.Alpha0))
             RemoveSelectables(new GameObject[] { GameObject.Find("Cube/Bottom") });
         if (Input.GetKeyDown(KeyCode.Minus))
             RemoveSelectables(new GameObject[] { GameObject.Find("Cube/Left") });
         if (Input.GetKeyDown(KeyCode.Equals))
             RemoveSelectables(new GameObject[] { GameObject.Find("Cube/Right") });
     }
     */
 
     /// <summary>
     /// Initialize all faces to a shared material
     /// </summary>
     public void Initialize()
     {
         _combinedMeshFilters.Clear();
 
         foreach (Transform t in gameObject.transform)
             if (t.GetComponent<MeshRenderer>() != null)
                 _combinedMeshFilters.Add(t.gameObject.GetComponent<MeshFilter>());
 
         if (_sharedMaterial == null)
         {
             _sharedMaterial = new Material(Shader.Find("Standard"));
             _sharedMaterial.color = Color.red;
         }
 
         CombineMeshes(gameObject);
     }
 
     /// <summary>
     /// Set the shared material
     /// </summary>
     public void SetSharedMaterial(Material material)
     {
         _sharedMaterial = material;
 
         CombineMeshes(gameObject);
     }
 
     public GameObject DetectFace(RaycastHit hit, MeshCollider meshCollider)
     {
         Transform[] transforms = gameObject.GetComponentsInChildren<Transform>();
 
         for (int i=0; i< transforms.Length; i++)
         {
             if (hit.collider.gameObject == transforms[i].gameObject)
             {
                 Debug.Log("Object Hit = " + transforms[i].gameObject.name + " Tri Index = " + hit.triangleIndex);
                 return transforms[i].gameObject;
             }
         }
 
             /*
             Mesh mesh = meshCollider.sharedMesh;
             Vector3[] vertices = mesh.vertices;
             int[] triangles = mesh.triangles;
             Vector3 p0 = vertices[triangles[hit.triangleIndex * 3 + 0]];
             Vector3 p1 = vertices[triangles[hit.triangleIndex * 3 + 1]];
             Vector3 p2 = vertices[triangles[hit.triangleIndex * 3 + 2]];
             Transform hitTransform = hit.collider.transform;
             p0 = hitTransform.TransformPoint(p0);
             p1 = hitTransform.TransformPoint(p1);
             p2 = hitTransform.TransformPoint(p2);
             Debug.DrawLine(p0, p1);
             Debug.DrawLine(p1, p2);
             Debug.DrawLine(p2, p0);*/
         return null;
     }
 
 
     // Add selectable face objects
     public void AddSelectables(GameObject[] obj)
     {
         bool combine = false;
 
         for (int i = 0; i < obj.Length; i++)
         {
             MeshRenderer meshRenderer = obj[i].GetComponent<MeshRenderer>();
 
             if (meshRenderer != null)
             {
                 if (!meshRenderer.enabled)
                 {
                     MeshFilter meshFilter = obj[i].GetComponent<MeshFilter>();
                     if (_combinedMeshFilters.Contains(meshFilter))
                     {
                         _combinedMeshFilters.Remove(meshFilter);
                         combine = true;
                     }
                     meshRenderer.enabled = true;
                     meshRenderer.material = new Material(Shader.Find("Standard"));
 
                     MeshCollider meshCollider = obj[i].GetComponent<MeshCollider>();
                     if (meshCollider == null)
                         obj[i].AddComponent<MeshCollider>();
                 }
             }
         }
 
         if (combine)
             CombineMeshes(gameObject);
     }
 
     /// <summary>
     /// Remove selectable face objects
     /// </summary>
     public void RemoveSelectables(GameObject[] obj)
     {
         bool combine = false;
 
         for (int i = 0; i < obj.Length; i++)
         {
             MeshRenderer meshRenderer = obj[i].GetComponent<MeshRenderer>();
 
             if (meshRenderer != null)
             {
                 if (meshRenderer.enabled)
                 {
                     _combinedMeshFilters.Add(obj[i].GetComponent<MeshFilter>());
 
                     MeshCollider meshCollider = obj[i].GetComponent<MeshCollider>();
                     if (meshCollider != null)
                         GameObject.DestroyImmediate(meshCollider);
 
                     combine = true;
                 }
             }
         }
 
         if (combine)
             CombineMeshes(gameObject);
     }
 
     /// <summary>
     /// Return selectable faces
     /// </summary>
     public GameObject[] SelectableFaces()
     {
         List<GameObject> objs = new List<GameObject>();
 
         foreach (Transform t in gameObject.transform)
             if (t.GetComponent<MeshRenderer>() != null)
                 objs.Add(t.gameObject);
 
         return objs.ToArray();
     }
 
     /// <summary>
     /// Combine meshes
     /// </summary>
     private void CombineMeshes(GameObject obj)
     {
         // Remove mesh and its renderer when all selectable faces are used
         if (_combinedMeshFilters.Count == 0)
         {
             if (obj.GetComponent<MeshFilter>() != null)
                 GameObject.DestroyImmediate(obj.GetComponent<MeshFilter>());
 
             if (obj.GetComponent<MeshRenderer>() != null)
                 GameObject.DestroyImmediate(obj.GetComponent<MeshRenderer>());
 
             return;
         }
 
         // Zero transformation is needed because of localToWorldMatrix transform
         Vector3 position = obj.transform.position;
         obj.transform.position = Vector3.zero;
 
         CombineInstance[] combine = new CombineInstance[_combinedMeshFilters.Count];
         int i = 0;
         while (i < _combinedMeshFilters.Count)
         {
             combine[i].mesh = _combinedMeshFilters[i].sharedMesh;
             combine[i].transform = _combinedMeshFilters[i].transform.localToWorldMatrix;
             _combinedMeshFilters[i].gameObject.GetComponent<MeshRenderer>().enabled = false;
             i++;
         }
         MeshFilter meshFilter = obj.transform.GetComponent<MeshFilter>();
         if (meshFilter == null)
             meshFilter = obj.AddComponent<MeshFilter>();
         obj.transform.GetComponent<MeshFilter>().mesh = new Mesh();
         obj.transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine, true, true);
         obj.transform.gameObject.SetActive(true);
 
         // Add Mesh Renderer
         MeshRenderer meshRenderer = obj.transform.GetComponent<MeshRenderer>();
         if (meshRenderer == null)
             meshRenderer = obj.AddComponent<MeshRenderer>();
 
         // Add Mesh Collider
         MeshCollider meshCollider = obj.transform.GetComponent<MeshCollider>();
         if (meshRenderer != null)
             GameObject.DestroyImmediate(meshCollider);
         obj.AddComponent<MeshCollider>();
 
         // Assign the Shared Material
         meshRenderer.sharedMaterial = _sharedMaterial;
 
         //Reset position
         obj.transform.position = position;
     }
 }
 
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Audio play problem on raycast hit colider.gameObject.tag 1 Answer

How to rotate object on mouse click? 1 Answer

Click to destroy object 2 Answers

Need help with script to find and persue target on click. 1 Answer

How to make a N-S magnet Javascript? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges