Sunday, September 23, 2018

unity - Cube changes position when I use a script to change its UV mapping


I try to code a Minecraft like game with Unity 2017.3. I found a C# script for creating a UV mapped cube with the following layout, using my own texture with 64x64 pixel sides:


MY UV map


If I run the game my cube is now placed in the air. How do I control its position?


MY cube is not on the ground


Here is the script I'm using:


using UnityEngine;
using System.Collections;


[RequireComponent(typeof (MeshFilter))]
[RequireComponent(typeof (MeshRenderer))]
public class UVMapping : MonoBehaviour {

void Start () {

float size = 1f;

Vector3[] vertices = {

new Vector3(0, size, 0),
new Vector3(0, 0, 0),
new Vector3(size, size, 0),
new Vector3(size, 0, 0),
new Vector3(0, 0, size),
new Vector3(size, 0, size),
new Vector3(0, size, size),
new Vector3(size, size, size),
new Vector3(0, size, 0),
new Vector3(size, size, 0),

new Vector3(0, size, 0),
new Vector3(0, size, size),
new Vector3(size, size, 0),
new Vector3(size, size, size),
};

int[] triangles = {
0, 2, 1, // front
1, 2, 3,
4, 5, 6, // back

5, 7, 6,
6, 7, 8, //top
7, 9 ,8,
1, 3, 4, //bottom
3, 5, 4,
1, 11,10,// left
1, 4, 11,
3, 12, 5,//right
5, 12, 13
};


Vector2[] uvs = {
new Vector2(0, 0.66f),
new Vector2(0.25f, 0.66f),
new Vector2(0, 0.33f),
new Vector2(0.25f, 0.33f),
new Vector2(0.5f, 0.66f),
new Vector2(0.5f, 0.33f),
new Vector2(0.75f, 0.66f),
new Vector2(0.75f, 0.33f),

new Vector2(1, 0.66f),
new Vector2(1, 0.33f),
new Vector2(0.25f, 1),
new Vector2(0.5f, 1),
new Vector2(0.25f, 0),
new Vector2(0.5f, 0),
};

Mesh mesh = GetComponent ().mesh;
mesh.Clear ();

mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
mesh.Optimize (); // this is deprecated
mesh.RecalculateNormals ();
}
}

Answer



The default Unity cube mesh has its center at the object's pivot ((0, 0, 0) in local space), and extends to -0.5 and +0.5 on each axis.


The script you're using creates a new cube-shaped mesh with one corner at the pivot, extending from 0 to size on each axis.



So if you're using it to replace a default Unity cube at runtime, you'll find it's shifted by 0.5 units.


You can fix this by adding a quick fixup after your vertices block:


for(int i = 0; i < vertices.Length; i++)
vertices[i] -= Vector3.one * 0.5f * size;

Or you can go through each line and replace every size by 0.5f * size,
and every 0 by -0.5f * size (defining an extents = 0.5f * size makes this neater)


One last note: each cube you use this script on will create its own copy of the mesh, eating memory and draw calls unnecessarily. You might want to consider grouping these, so that you calculate the mesh only once and share it among many cubes. Or even better, just make the mesh you want offline and import it as an asset that all your cubes can reference.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...