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 /
This question was closed Jun 14, 2016 at 01:04 AM by Browninge for the following reason:

The question is answered, right answer was accepted

avatar image
0
Question by Browninge · May 28, 2016 at 01:20 PM · meshmeshrendereruv mappinguv coordinates

Creating cube in script/ texture stretches on all sides but top and bottom?

I'm trying to create a cube from scratch and everything is going well except when I add a material or texture to it. The texture is correct on the top and bottom faces, but stretches on all other sides. The texture appears correctly on Unity's default cube, but I create the cubes in a way that not all faces are drawn.

I believe the problem may be incorrect UV mapping but I'm finding it quite difficult to understand how that works. The script is included below, and I appreciate any and all help!

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 
 
 public class BlockScript : MonoBehaviour {
 
 
     //Code for rendering mesh
     Vector3[] vertices = new Vector3[8];
     List<int> trianglesOne = new List<int>();
     Vector2[] uvs = new Vector2[8];
     Mesh mesh;
 
     public Material wood;
 
     
 
     //Vector3 pos;
     //End of code for rendering mesh
 
     ChunkScript chunkScript;
     public GameObject CoordChecker;
 
     int xPos;
     int yPos;
     int zPos;
 
     void AddComponents() {
         gameObject.AddComponent<MeshFilter>();
         gameObject.AddComponent<MeshRenderer>();
         gameObject.AddComponent<BoxCollider>();
         BoxCollider box = gameObject.GetComponent<BoxCollider>();
         box.size = new Vector3(.99f, .99f, .99f);
         mesh = GetComponent<MeshFilter>().mesh;
         if (GlobalVariableHolder.wood) gameObject.GetComponent<MeshRenderer>().material = wood;
 
         gameObject.tag = "Block";
     }
     void Start() {
 
 
         AddComponents();
     }
 
     public void printName() {
         print(name);
     }
 
     void OnTriggerEnter(Collider other) {
         if (other.tag == "Chunk") {
             transform.parent = other.transform;
 
             xPos = (int)transform.localPosition.x;
             yPos = (int)transform.localPosition.y;
             zPos = (int)transform.localPosition.z;
 
             transform.name = (xPos + " " + yPos + " " + zPos);
             
 
 
             chunkScript = transform.parent.GetComponent<ChunkScript>();
             chunkScript.blockPos[xPos, yPos, zPos] = true;
             CreateFaces();
             chunkScript.ChunkUpdate();
         }
     }
 
     void OnDestroy() {
         chunkScript.blockPos[xPos, yPos, zPos] = false;
     }
 
 
     //Checks if each direction has a block and calls the respective function to draw the face
     public void CreateFaces() {
         mesh.Clear();
         Vertices();
 
         if (zPos < 9) {
             if (chunkScript.blockPos[xPos, yPos, zPos + 1] == false) FaceNorth();
         } else if(zPos == 9) {
             GameObject checker = Instantiate(CoordChecker, new Vector3(xPos, yPos, zPos + 1), Quaternion.identity) as GameObject;
             CoordCheckerScript checkerScript = checker.GetComponent<CoordCheckerScript>();
             if (checkerScript.containsBlock == false) { FaceNorth(); }
             Destroy(checker.gameObject);
         }
 
         if (xPos < 9) {
             if (!chunkScript.blockPos[xPos + 1, yPos, zPos]) FaceEast();
         } else if(xPos == 9) {
             GameObject checker = Instantiate(CoordChecker, new Vector3(xPos + 1, yPos, zPos), Quaternion.identity) as GameObject;
             CoordCheckerScript checkerScript = checker.GetComponent<CoordCheckerScript>();
             if (checkerScript.containsBlock == false) { FaceWest(); }
             Destroy(checker.gameObject);
         }
 
         if (zPos > 0) {
             if (!chunkScript.blockPos[xPos, yPos, zPos - 1]) FaceSouth();
         } else if(zPos == 0) {
             GameObject checker = Instantiate(CoordChecker, new Vector3(xPos, yPos, zPos - 1), Quaternion.identity) as GameObject;
             CoordCheckerScript checkerScript = checker.GetComponent<CoordCheckerScript>();
             if (checkerScript.containsBlock == false) { FaceSouth(); }
             Destroy(checker.gameObject);
         }
 
         if (xPos > 0) {
             if (!chunkScript.blockPos[xPos - 1, yPos, zPos]) FaceWest();
         } else if (xPos == 0) {
             GameObject checker = Instantiate(CoordChecker, new Vector3(xPos - 1, yPos, zPos), Quaternion.identity) as GameObject;
             CoordCheckerScript checkerScript = checker.GetComponent<CoordCheckerScript>();
             if (checkerScript.containsBlock == false) { FaceWest(); }
             Destroy(checker.gameObject);
         }
 
         if (yPos < 299) {
             if (!chunkScript.blockPos[xPos, yPos + 1, zPos]) FaceTop();
         }
 
         if (yPos > 0) {
             if (!chunkScript.blockPos[xPos, yPos - 1, zPos]) FaceBottom();
         }
 
         int[] triangles = trianglesOne.ToArray();
         mesh.triangles = triangles;
 
     }
 
     //Code to set mesh triangles
     void Vertices() {
         vertices[0] = new Vector3(-0.5f, -0.5f, -0.5f);
         vertices[1] = new Vector3(-0.5f, 0.5f, -0.5f);
         vertices[2] = new Vector3(0.5f, 0.5f, -0.5f);
         vertices[3] = new Vector3(0.5f, -0.5f, -0.5f);
 
         vertices[4] = new Vector3(-0.5f, -0.5f, 0.5f);
         vertices[5] = new Vector3(-0.5f, 0.5f, 0.5f);
         vertices[6] = new Vector3(0.5f, 0.5f, 0.5f);
         vertices[7] = new Vector3(0.5f, -0.5f, 0.5f);
 
         mesh.vertices = vertices;
 
         for(int i = 0; i < vertices.Length; i++) {
             uvs[i] = new Vector2(vertices[i].x, vertices[i].z);
         }
         mesh.uv = uvs;
     }
 
     void FaceNorth() {
         trianglesOne.Add(7);
         trianglesOne.Add(6);
         trianglesOne.Add(5);
         trianglesOne.Add(7);
         trianglesOne.Add(5);
         trianglesOne.Add(4);
         
     }
     void FaceEast() {
         trianglesOne.Add(3);
         trianglesOne.Add(2);
         trianglesOne.Add(6);
         trianglesOne.Add(3);
         trianglesOne.Add(6);
         trianglesOne.Add(7);
     }
     void FaceSouth() {
         trianglesOne.Add(0);
         trianglesOne.Add(1);
         trianglesOne.Add(2);
         trianglesOne.Add(0);
         trianglesOne.Add(2);
         trianglesOne.Add(3);
     }
     void FaceWest() {
         trianglesOne.Add(4);
         trianglesOne.Add(5);
         trianglesOne.Add(1);
         trianglesOne.Add(4);
         trianglesOne.Add(1);
         trianglesOne.Add(0);
     }
     void FaceTop() {
         trianglesOne.Add(1);
         trianglesOne.Add(5);
         trianglesOne.Add(6);
         trianglesOne.Add(1);
         trianglesOne.Add(6);
         trianglesOne.Add(2);
     }
     void FaceBottom() {
         trianglesOne.Add(4);
         trianglesOne.Add(0);
         trianglesOne.Add(3);
         trianglesOne.Add(4);
         trianglesOne.Add(3);
         trianglesOne.Add(7);
     }
Comment
Add comment · Show 4
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 Glurth · May 28, 2016 at 03:31 PM 0
Share

Hmm, this code looks familiar, lol. $$anonymous$$ay I suggest you post an image of the texture you are mapping onto the cube? Here is how I would figure out the UV mapping: looking at the texture image, I would draw six squares on it. Preferably, each edge would be flush with another square's edge ( or flush when possible, given the 2d limitations), and all edges be equal in length. Once the squares are laid out, note the position of each corner as a fraction of total height and width (between 0 and 1). These will be the UV points you want to use for each face.

This method will not distort the UV texture, but it WILL need to leave OUT some of the image (unless you choose to allow those squares to overlap). Also, with this method the square edges that don't touch in the UV texture, will not have perfectly matching edges on the 3d model.

If you DO want all edges to be flush, you will need to select different UV coordinates such that the edges are indeed flush. Drawing six "squares" on the uv image obviously will NOT work for all but one face in this situation (because you simply cannot make all their edges touch; trapazoids might fit better that squares, for some faces, for example). This will probably necessitate that you distort the UV texture you are using.

EDIT: I would suggest you make some "test" texture, that makes clear EXACTLY how the image is getting distorted. I usually whip up some kind of graph-paper (or maybe a big X) with circles- looking thing. You can even draw lines of a particular color, right on your expected UV edges, to confirm that match up.

avatar image Browninge Glurth · May 29, 2016 at 07:51 AM 0
Share

Sorry for my late response (work). Are you saying that I need to declare the UV points in each of the functions that declare the triangles?

avatar image GameMaker_ · May 29, 2016 at 03:14 PM 0
Share

I wrote an answer 22h ago but it has yet not been published... So I post it now as comment.

The texture stretches on all sides but top and bottom because of the following code:

  for(int i = 0; i < vertices.Length; i++) {
      uvs[i] = new Vector2(vertices[i].x, vertices[i].z);
  }

The UVs are good on the top and bottom faces because the X and Z values are different for each corner. However, for the other faces, it makes the selected zone of the texture be a line and not a surface. This is why you get stretched faces...

avatar image Browninge GameMaker_ · May 30, 2016 at 06:12 AM 0
Share

Thanks for taking the time to answer. I believe I understand what you're saying but I'm not sure how to go about doing that. I'm gonna keep reading up on how to properly assign uv coordinates and whatnot. From reading the responses you guys have kindly taken the time to write, I know the problem is definitely the UV mapping, but I'm not entirely sure how to go about doing it.

1 Reply

  • Sort: 
avatar image
0
Best Answer

Answer by cjdev · May 28, 2016 at 04:00 PM

Unfortunately, as far as I know, the only way to procedurally UV a complex mesh is to split it apart into smaller meshes so that they are connected on the UV plane. If you aren't aware, the UV coordinate system is like the XY system except that it goes from 0-1 for a typical texture (beyond 1 it tiles every whole number). To map a cube you can do it a couple ways, depending on what you need: map each face onto the entire 0-1 square, taking up the whole texture and repeating it on each face, or unfolding the cube into a "T" shape within the UV grid.

Either way you'll likely need to split it up as I said because when you add UVs to a procedural mesh you do it one for each vertex. However, when unfolding a mesh there will be points that are shared, the same vertex represented by two points in UV space. For the case of the cube you could solve it by creating 6 squares, a total of 24 verts, and create the UVs for each based on your texture. A more efficient method would be to only double up on the vertices that have more than one UV point. And finally, you could always use a custom shader and save on the vertex count.

Comment
Add comment · Show 3 · 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 Browninge · May 29, 2016 at 07:58 AM 0
Share

Sorry for the late response (work).

I know how to map what part of the texture image to use, so that's not a problem. I just can't wrap my head around mapping the object I'm trying to texture. I basically want to create an object just like the primitive cube that Unity let's you create with the "Create Game Object" button, but only drawing the faces that are visible.

I believe I want to "map each face onto the entire 0-1 square, taking up the whole texture and repeating it on each face" as you put it, I just don't know how to do that.

avatar image cjdev · May 29, 2016 at 12:28 PM 0
Share

In that case for each square you'll want to place each vertex at a corner of a 0-1 square. So there's a vertex with a UV point at 0,0 and one at 0,1 and 1,0 and 1,1. Putting them in the right order is a matter of keeping track of the vertex order and where you want them on your texture.

avatar image Browninge · May 30, 2016 at 06:17 AM 0
Share

I think I have an idea on what to do, but I'll have to play around with it tomorrow and get back to you. Although, if you could provide a small chunk of code I might be able to better understand how to do it properly. That would take a bit of the fun out of it though.

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

UV Tiling/repeat 1 Answer

Texture on custom mesh splits at edge. 1 Answer

need guide in uv texture 0 Answers

Why zero height mesh gets black independent of shader 1 Answer

How to set UV (Map) for Mesh made by script without duplicating vertices? 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