Search Unity

Get simple rectangle shaped mesh face direction

Discussion in 'Scripting' started by iamIcarus, Aug 26, 2014.

  1. iamIcarus

    iamIcarus

    Joined:
    Jul 3, 2013
    Posts:
    20
    i have a tube that contains several separated rectangle shaped mesh objects. My goal is to spawn an object in the center of each rectangle and face perpendicular to the rectangle surface

    On each separated rectangle i have this code:

    Code (CSharp):
    1. Mesh mesh = GetComponent<MeshFilter>().mesh;
    2.         int[] triangles = mesh.triangles;
    3.  
    4.         Vector3 n0=Vector2.zero,n1=Vector2.zero,n2=Vector2.zero;
    5.         for (int i = 0; i < mesh.triangles.Length; i += 3)
    6.         {
    7.             n0 = mesh.vertices[mesh.triangles[i + 0]];
    8.             n1 = mesh.vertices[mesh.triangles[i + 1]];
    9.             n2 = mesh.vertices[mesh.triangles[i + 2]];
    10.         }
    11.  
    12.         Vector3 a = Vector3.Cross (n1 - n2, n2 - n0).normalized;
    13.  
    14.         Instantiate(prefab, transform.renderer.bounds.center,Quaternion.LookRotation(a));
    Result is this:
    1.png


    My goal is this
    2.png


    any ideas ?? :)
     
  2. Fraconte

    Fraconte

    Joined:
    Dec 6, 2013
    Posts:
    327
    Can this works? (Eventually try changing the 180 angle)
    Code (CSharp):
    1. Instantiate (prefab, transform.renderer.bounds.center, transform.rotation * Quaternion.Euler (180,0,0 ));
    I suspect the transform is that of the tube and you have no transform for the rects. Right? If so I am wrong... sorry.
     
    Last edited: Aug 27, 2014
  3. Fraconte

    Fraconte

    Joined:
    Dec 6, 2013
    Posts:
    327
    If you have no transform for the rectangles, try this:
    Code (CSharp):
    1.  
    2. Instantiate (prefab, transform.renderer.bounds.center, Quaternion.LookRotation (transform.position, transform.up) * Quaternion.Euler (180, 0, 0 ));
    3.  
    You can omit the Euler to invert the rotation and you can try changing the transform.up to transform.forward or right (depending on the tube orientation).
     
  4. Fraconte

    Fraconte

    Joined:
    Dec 6, 2013
    Posts:
    327
    This is my last bet... :)
    Code (CSharp):
    1.  
    2. Instantiate (prefab, transform.renderer.bounds.center, Quaternion.FromToRotation (Vector3.up, a));
    3.  
    You can try .forward or .right depending on the prefab orientation.
     
  5. iamIcarus

    iamIcarus

    Joined:
    Jul 3, 2013
    Posts:
    20
    Thank you for helping but all of the individual rectangles game objects have the same rotation so i cant use the standard functions like this

    I think the solution will be to get the perpendicular to the mesh rectangle front facing side
    What do you think?


    Individual rectangles game objects have the same rotation


    1.jpg

    2.png
     
  6. Fraconte

    Fraconte

    Joined:
    Dec 6, 2013
    Posts:
    327
    I think they have the same localRotation (the same you are looking in the editor) but their transform.up is that green line you are seeing above.

    The first solution I am almost sure could works. I just wonder if you tryed it.
     
    Last edited: Aug 27, 2014
  7. iamIcarus

    iamIcarus

    Joined:
    Jul 3, 2013
    Posts:
    20
    yes i tried the code but the didnt solve it unfortunately . Also the transform.up points to the same direction for all objects (not perpendicular) , i think it cannot be seeing clearly from pics above ... take a look at this new pic with the first code you suggested

    Any thoughts ?? :) 1.jpg
     
  8. iamIcarus

    iamIcarus

    Joined:
    Jul 3, 2013
    Posts:
    20
    just a quick update... i found that (in my original code) if dont use "transform.renderer.bounds.center" location in the instantiate function but use "mesh.bounds.center" the rotation is correct but position is way off

    Code (CSharp):
    1. Instantiate(prefab, mesh.bounds.center,Quaternion.LookRotation(a));
    2.  

    any thoughts/ideas on that? :)

    Untitled.png
     
  9. Fraconte

    Fraconte

    Joined:
    Dec 6, 2013
    Posts:
    327
    If you can send me a sample scene I try to figure out... I'm having an hard time just in understanding your setup :)
     
  10. Fraconte

    Fraconte

    Joined:
    Dec 6, 2013
    Posts:
    327
    You can try:
    1. Transform t = Instantiate (.... mesh.bounds.center
    2. t.position = transform.renderer.bounds.center;
     
  11. Serge_Billault

    Serge_Billault

    Joined:
    Aug 26, 2014
    Posts:
    190
    If your asset is facing the z axis when imported, doing "obj.transform.foward = direction to face" should suffice.
    To illustrate the exemple i made you a sample project with a scrolling inifinte tube that you can download here:
    https://www.sugarsync.com/pf/D2307301_98582733_600566

    for the following result:
     
    NomadKing, iamIcarus and Fraconte like this.
  12. Fraconte

    Fraconte

    Joined:
    Dec 6, 2013
    Posts:
    327
    Thanks! I have not played yet with procedural meshes, so I think I can learn something from that...
    Yutube... nice name! :)
     
    iamIcarus likes this.
  13. IsGreen

    IsGreen

    Joined:
    Jan 17, 2014
    Posts:
    206
    Mesh vertices use local positions, need to convert it to world position to calculate center rectangle.

    I used a Quad as rectangle in this example. Spawned object must look at to forward axis.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent(typeof(MeshFilter))]
    5. public class temp : MonoBehaviour {
    6.  
    7.     public GameObject prefab;
    8.  
    9.     GameObject instancePrefab;
    10.     Mesh meshQuad;
    11.  
    12.     void Start(){
    13.  
    14.         meshQuad = GetComponent<MeshFilter>().mesh;
    15.         instancePrefab = (GameObject)Instantiate(prefab);
    16.  
    17.     }
    18.  
    19.     void prefabLookAt(){
    20.  
    21.         Matrix4x4 localToWorld = transform.localToWorldMatrix;
    22.  
    23.         Vector3 v0 = localToWorld.MultiplyPoint3x4(meshQuad.vertices[meshQuad.triangles[0]]);
    24.         Vector3 v1 = localToWorld.MultiplyPoint3x4(meshQuad.vertices[meshQuad.triangles[1]]);
    25.         Vector3 v2 = localToWorld.MultiplyPoint3x4(meshQuad.vertices[meshQuad.triangles[2]]);
    26.  
    27.         Vector3 normal = Vector3.Cross(v1-v0,v2-v0);
    28.      
    29.         Vector3 center = Vector3.zero;
    30.      
    31.         int i;
    32.         for(i=0;i<meshQuad.vertices.Length;i++)
    33.             center += localToWorld.MultiplyPoint3x4(meshQuad.vertices[i]);
    34.      
    35.         center /= (float)i;
    36.  
    37.         instancePrefab.transform.position = center;
    38.         instancePrefab.transform.rotation = Quaternion.LookRotation(normal);
    39.  
    40.     }
    41.  
    42.     void Update(){
    43.  
    44.         prefabLookAt();
    45.  
    46.     }
    47.  
    48. }
     
    Last edited: Aug 31, 2014
    mazend87, iamIcarus and Fraconte like this.
  14. iamIcarus

    iamIcarus

    Joined:
    Jul 3, 2013
    Posts:
    20
    Sorry for the late reply , i had some free time today and tested isGreen code and it solved my issue :)
    everything works as it should be , thank you for helping me out.

    I will also test the Yseron source with procedural mesh as it looks interesting.

    thanks again for all the help :)
     
    mazend87 likes this.