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
0
Question by $$anonymous$$ · Mar 02, 2018 at 07:08 AM · meshuvuvs

Fixing Uvs on a mesh by code cylinder

So I've just constructed a Cylinder by code (I know its sloppy) but when I apply a texture and compare it to a normal unity cylinder the texture seems backwards I think. If anyone knows what I did wrong and can help me fix this I'd appreciate it A LOT. Also if you could educate me on how a for loop is made for the vertices and triangles that would be cool too.

using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine;

public class BuildMesh : MonoBehaviour { //Litterally just for me to remember where locations are (They have no purpose) public Vector3[] verticesLoc; public Vector3[] verticesLocBack;

 // Use this for initialization
 void Start()
 {
     MeshFilter mf = GetComponent<MeshFilter>();
     Mesh mesh = mf.mesh;

     //Vertices
     Vector3[] vertices = new Vector3[]
     {
         //Constructed Clockwise (So is visible from  outside)
         #region Front Face
         //Top
         new Vector3(0.0f, 0.5f, 1),             //0

         new Vector3(-0.15f, 0.475f, 1),         //1
         new Vector3(-0.295f, 0.405f, 1),        //2
         new Vector3(-0.405f, 0.295f, 1),        //3
         new Vector3(-0.475f, 0.15f, 1),         //4
         //Right
         new Vector3(-0.5f, 0.0f, 1),            //5

         new Vector3(-0.475f, -0.15f, 1),        //6
         new Vector3(-0.405f, -0.295f, 1),       //7
         new Vector3(-0.295f, -0.405f, 1),       //8
         new Vector3(-0.15f, -0.475f, 1),        //9
         //Bottom
         new Vector3(0.0f, -0.5f, 1),            //10

         new Vector3(0.15f, -0.475f, 1),         //11
         new Vector3(0.295f, -0.405f, 1),        //12
         new Vector3(0.405f, -0.295f, 1),        //13
         new Vector3(0.475f, -0.15f, 1),         //14
         //Left
         new Vector3(0.5f, 0f, 1),               //15

         new Vector3(0.475f, 0.15f, 1),          //16
         new Vector3(0.405f, 0.295f, 1),         //17
         new Vector3(0.295f, 0.405f, 1),         //18
         new Vector3(0.15f, 0.475f, 1),          //19
         //Center
         new Vector3(0.0f, 0.0f, 1),             //20
         #endregion

         //Constructed Counter Clockwise (So is visible from  outside)
         #region Back Face
         //Top
         new Vector3(0.0f, 0.5f, -1),             //21

         new Vector3(0.15f, 0.475f, -1),          //22
         new Vector3(0.295f, 0.405f, -1),         //23
         new Vector3(0.405f, 0.295f, -1),         //24
         new Vector3(0.475f, 0.15f, -1),          //25
         //Left
         new Vector3(0.5f, 0f, -1),               //26
         new Vector3(0.475f, -0.15f, -1),         //27
         new Vector3(0.405f, -0.295f, -1),        //28
         new Vector3(0.295f, -0.405f, -1),        //29
         new Vector3(0.15f, -0.475f, -1),         //30
         //Bottom
         new Vector3(0.0f, -0.5f, -1),            //31

         new Vector3(-0.15f, -0.475f, -1),        //32
         new Vector3(-0.295f, -0.405f, -1),       //33
         new Vector3(-0.405f, -0.295f, -1),       //34
         new Vector3(-0.475f, -0.15f, -1),        //35
         //Right
         new Vector3(-0.5f, 0.0f, -1),            //36

         new Vector3(-0.475f, 0.15f, -1),         //37
         new Vector3(-0.405f, 0.295f, -1),        //38
         new Vector3(-0.295f, 0.405f, -1),        //39
         new Vector3(-0.15f, 0.475f, -1),         //40
         //Center
         new Vector3(0.0f, 0.0f, -1)              //41
         #endregion
     };

     //Triangles 3 points clockwise determines side visable
     int[] triangle = new int[]
     {
         //Octogon numbers are related to comments next to vertices
         #region Front Face
         0,1,20,
         1,2,20,
         2,3,20,
         3,4,20,
         4,5,20,
         5,6,20,
         6,7,20,
         7,8,20,
         8,9,20,
         9,10,20,
         10,11,20,
         11,12,20,
         12,13,20,
         13,14,20,
         14,15,20,
         15,16,20,
         16,17,20,
         17,18,20,
         18,19,20,
         19,0,20,
         #endregion

         #region Back Face
         21,22,41,
         22,23,41,
         23,24,41,
         24,25,41,
         25,26,41,
         26,27,41,
         27,28,41,
         28,29,41,
         29,30,41,
         30,31,41,
         31,32,41,
         32,33,41,
         33,34,41,
         34,35,41,
         35,36,41,
         36,37,41,
         37,38,41,
         38,39,41,
         39,40,41,
         40,21,41,
         #endregion

         //Goes clock wise around the cylinder starting at the top (Right top, Right Bottom, Left Bottom, Left Top)
         #region Body
         //Top Right Section
         0,21,40,
         40,1,0,
         1,40,39,
         39,2,1,
         2,39,38,
         38,3,2,
         3,38,37,
         37,4,3,
         4,37,36,
         36,5,4,
         //Bottom Right Section
         5,36,35,
         35,6,5,
         6,35,34,
         34,7,6,
         7,34,33,
         33,8,7,
         8,33,32,
         32,9,8,
         9,32,31,
         31,10,9,
         //Bottom Left Section
         10,31,30,
         30,11,10,
         11,30,29,
         29,12,11,
         12,29,28,
         28,13,12,
         13,28,27,
         27,14,13,
         14,27,26,
         26,15,14,
         //Top Left Section
         15,26,25,
         25,16,15,
         16,25,24,
         24,17,16,
         17,24,23,
         23,18,17,
         18,23,22,
         22,19,18,
         19,22,21,
         21,0,19
         #endregion
     };

     //For loop to take x and y of vertices to construct UVS
     Vector2[] UVS = new Vector2[vertices.Length];
     for (var i = 0; i < vertices.Length; i++)
     {
         UVS[i] = new Vector2(vertices[i].x, vertices[i].y);
     }

     //Clear mesh values
     mesh.Clear();
     //Put in my values
     mesh.vertices = vertices;
     mesh.triangles = triangle;
     mesh.uv = UVS;
     //Put back togeather
     MeshUtility.Optimize(mesh);
     mesh.RecalculateNormals();
     //Create a mesh collider on this object and assign it to the mesh
     MeshCollider meshCollider = gameObject.AddComponent(typeof(MeshCollider)) as MeshCollider;
     meshCollider.sharedMesh = mesh;
 }

}

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Mar 03, 2018 at 02:37 AM

There is not much to "fix" here ^^. The UVs you create are a 2d projection along the x-y plane. You simply use the spatial position as UV coordinates which would work for flat meshes but not for 3d objects.


Next thing is a cylinder consists of 3 seperate parts: the top, the bottom and the "side" face(s). Those 3 parts have to use seperate normal vectors as edges between those parts are not continuous. You have to have a sharp edge there. That means you have to use seperate vertices for those 3 parts. Currently you share the vertices between the top / bottom side and the surrounding faces which doesn't work that way.


Generally there are many different ways how you could "unwrap" / UV map a cylinder. However the most common way would be to map the surrounding faces like it's a single rectangle once unrolled and to map the two circles onto the center of the texture.


To create a cylinder procedurally you usually want to create the vertices dynamically. Currently you have them hardcoded so it's like you have created it in a modelling tool.


Here's a procedural cylinder including UV and normal calculation. You can specify how many sides it should have, the radius, the height and the orientation as a Vector3 as well as a percentage value where the pivot should be:

 using UnityEngine;
 
 [RequireComponent(typeof(MeshFilter)), RequireComponent(typeof(MeshRenderer))]
 public class ProceduralCylinder : MonoBehaviour
 {
     public Vector3 direction = Vector3.forward;
     public float pivotPos = 0.5f;
     public float radius = 0.5f;
     public float height = 1f;
     public int sides = 3;
     public float phase = 0f;
 
     void Start ()
     {
         GetComponent<MeshFilter>().sharedMesh = CreateCylinder(direction, pivotPos, radius, height, sides, phase);
     }
 
     public static Mesh CreateCylinder(Vector3 aDir, float aPivot, float aRadius, float aHeight, int aSides, float aPhaseOffset)
     {
         aDir.Normalize();
         aSides = Mathf.Max(3, aSides);
         Vector3 u = Vector3.up;
         Vector2 uv = Vector2.right*0.5f;
         if (Mathf.Abs(aDir.y) > 0.98f)
             u = -Vector3.forward;
         u = Vector3.ProjectOnPlane(u, aDir).normalized;
         u = Quaternion.AngleAxis(aPhaseOffset, aDir) * u;
         Quaternion q = Quaternion.AngleAxis(360f / aSides, aDir);
         Quaternion q2 = Quaternion.AngleAxis(360f / aSides, -Vector3.forward);
         Vector3[] vertices = new Vector3[(aSides+1) * 4 + 2];
         Vector3[] normals = new Vector3[vertices.Length];
         Vector2[] UVs = new Vector2[vertices.Length];
         int[] triangles = new int[aSides * 12];
         // bottom / top center
         Vector3 b = vertices[0] = -aDir * aPivot*aHeight;
         Vector3 t = vertices[1] = aDir * (1f-aPivot) * aHeight;
         normals[0] = -aDir;
         normals[1] = aDir;
         UVs[0] = UVs[1] = new Vector2(0.5f, 0.5f);
         int count = aSides + 1;
         for (int i = 0; i < count; i++)
         {
             // bottom + sides bottom vertices
             vertices[2 + i] = vertices[2 + count + i] = b + u * aRadius;
             // sides top + top vertices
             vertices[2 + count* 2 + i] = vertices[2 + count * 3 + i] = t + u * aRadius;
 
             // bottom normal
             normals[2 + i] = -aDir;
             // top normal
             normals[2 + count * 3 + i] = aDir;
             // sides normals
             normals[2 + count + i] = normals[2 + count * 2 + i] = u;
 
             // bottom UV
             UVs[2 + i] = new Vector2(uv.x + 0.5f, uv.y + 0.5f);
             // sides UV
             float x = (float)i / (aSides);
             UVs[2 + count * 1 + i] = new Vector2(x, 0f);
             UVs[2 + count * 2 + i] = new Vector2(x, 1f);
             // top UV
             UVs[2 + count * 3 + i] = new Vector2(-uv.x + 0.5f, uv.y + 0.5f);
 
             // rotate vectors
             u = q * u;
             uv = q2 * uv;
 
         }
         for(int i = 0; i < aSides; i++)
         {
             // bottom face
             triangles[i * 12] = 0;
             triangles[i * 12 + 1] = 2 + i + 1;
             triangles[i * 12 + 2] = 2 + i;
 
             // top face
             triangles[i * 12 + 3] = 1;
             triangles[i * 12 + 4] = 2 + count * 3 + i;
             triangles[i * 12 + 5] = 2 + count * 3 + i + 1;
 
             // sides faces
             triangles[i * 12 + 6] = 2 + count * 1 + i;
             triangles[i * 12 + 7] = 2 + count * 1 + i + 1;
             triangles[i * 12 + 8] = 2 + count * 2 + i;
 
             triangles[i * 12 + 9] = 2 + count * 2 + i + 1;
             triangles[i * 12 + 10] = 2 + count * 2 + i;
             triangles[i * 12 + 11] = 2 + count * 1 + i + 1;
 
         }
         Mesh m = new Mesh();
         m.vertices = vertices;
         m.normals = normals;
         m.uv = UVs;
         m.triangles = triangles;
         return m;
     }
 }

You can use the static ProceduralCylinder.CreateCylinder anywhere you like or attach the script to a gameobject and set the parameters in the inspector. Note that if "aPivot" is "0" the origin will be at the "bottom" of the cylinder, if it's 1 the origin will be at the top and if it's 0.5 it's in the center.


The UVs are not exactly like Unity's cylinder mesh. My cylinder wraps the texture around the cylinder once while Unity's mesh does wrap it around twice. That means Unity has two UV seams while mine has only one at the side.

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 $$anonymous$$ · Mar 05, 2018 at 12:08 AM 0
Share

Thanks for this, it did feel like I was modeling it when I drew out a picture to see all the hard coded triangle values and how they connected. I'll definitely learn from this while going forward.

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

83 People are following this question.

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

Related Questions

How to change mesh UV's permanent in Unity (texture atlas) 1 Answer

Create planar UVs on procedurally generated mesh 1 Answer

Creating a mesh programatically for a tile-based 2D game 1 Answer

Normalizing mesh UVS? 1 Answer

creating a mesh and generating it's specific uvs 2 Answers


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