初识Unity3D的UV贴图,
我们知道通过物体可以通过调节tiling和offset值来调节uv信息,但是这是不准确的。
例如:原图为这样
而拉伸之后调节tiling值只能适应一两个面的uv值是正确的,如图:
我们通过的代码控制之后就能适应每个面正确的uv贴图,如图:
下面直接上代码
using System.Collections.Generic;
using UnityEngine;
public class Uvtest2 : MonoBehaviour
{
public static List<Vector3> Vertices;//顶点
public static List<int> Triangles;//三角形索引
public static List<Vector2> Uvs;//uv信息
public static float VerticesCount;//顶点个数
public static float TrianglesCount;//三角形索引个数
public static float UVsCount;//uv个数
public static Vector3 Scales;//scale值
void Start()
{
SetUVStart(gameObject);
}
void Update()
{
if (Scales != gameObject.transform.localScale)
{
SetUV(this.gameObject);
Scales = gameObject.transform.localScale;
}
}
public void SetUVStart(GameObject gameObject)//得到控制uv需要的一些初始值
{
Mesh mh = gameObject.GetComponent<MeshFilter>().mesh;
Vertices = new List<Vector3>();
Triangles = new List<int>();
Uvs = new List<Vector2>();
VerticesCount = mh.vertices.Length;
UVsCount = mh.uv.Length;
TrianglesCount = mh.triangles.Length;
for (int i = 0; i < VerticesCount; i++)
{
Vertices.Add(mh.vertices[i]);
}
for (int i = 0; i < TrianglesCount; i++)
{
Triangles.Add(mh.triangles[i]);
}
for (int i = 0; i < UVsCount; i++)
{
Uvs.Add(mh.uv[i]);
}
Scales = gameObject.transform.localScale;
}
public void SetUV(GameObject gameObject)//设置UV
{
Mesh mh = gameObject.GetComponent<MeshFilter>().mesh;
Vector3 scale = gameObject.transform.localScale;
List<Vector2> uvs = new List<Vector2>(mh.uv.Length);
for (int i = 0; i < Uvs.Count; i++)
{
uvs.Add(Uvs[i]);
}
int number = 0;
for (int i = 0; i < Triangles.Count; i += 3)
{
int index1 = Triangles[i];
int index2 = Triangles[i + 1];
int index3 = Triangles[i + 2];
//通过三角形的顶点值判断uv的x、y轴对应的是scale的哪个轴,因为scale是3维二uv是2维
if (Vertices[index2].y - Vertices[index1].y != 0)
{
uvs[index1] = new Vector2(Uvs[index1].x, Uvs[index1].y);
uvs[index2] = new Vector2(Uvs[index2].x, Uvs[index2].y * scale.y);
//判断一个面相应三角形需要变化的uv,一个面由两个三角构成
if (number == 0)
{
if (Vertices[index3].x - Vertices[index1].x != 0)
{
uvs[index2] = new Vector2(Uvs[index2].x, Uvs[index2].y * scale.y);
uvs[index3] = new Vector2(Uvs[index3].x * scale.x, Uvs[index3].y * scale.y);
}
else if (Vertices[index3].z - Vertices[index1].z != 0)
{
uvs[index2] = new Vector2(Uvs[index2].x, Uvs[index2].y * scale.y);
uvs[index3] = new Vector2(Uvs[index3].x * scale.z, Uvs[index3].y * scale.y);
}
number++;
}
else
{
if (Vertices[index3].x - Vertices[index1].x != 0)
{
uvs[index2] = new Vector2(Uvs[index2].x * scale.x, Uvs[index2].y * scale.y);
uvs[index3] = new Vector2(Uvs[index3].x * scale.x, Uvs[index3].y);
}
else if (Vertices[index3].z - Vertices[index1].z != 0)
{
uvs[index2] = new Vector2(Uvs[index2].x * scale.z, Uvs[index2].y * scale.y);
uvs[index3] = new Vector2(Uvs[index3].x * scale.z, Uvs[index3].y);
}
number = 0;
}
}
else if (Vertices[index2].z - Vertices[index1].z != 0)
{
uvs[index1] = new Vector2(Uvs[index1].x, Uvs[index1].y);
uvs[index2] = new Vector2(Uvs[index2].x, Uvs[index2].y * scale.z);
if (number == 0)
{
if (Vertices[index3].x - Vertices[index1].x != 0)
{
uvs[index2] = new Vector2(Uvs[index2].x, Uvs[index2].y * scale.z);
uvs[index3] = new Vector2(Uvs[index3].x * scale.x, Uvs[index3].y * scale.z);
}
else if (Vertices[index3].y - Vertices[index1].y != 0)
{
uvs[index2] = new Vector2(Uvs[index2].x, Uvs[index2].y * scale.z);
uvs[index3] = new Vector2(Uvs[index3].x * scale.y, Uvs[index3].y * scale.z);
}
number++;
}
else
{
if (Vertices[index3].x - Vertices[index1].x != 0)
{
uvs[index2] = new Vector2(Uvs[index2].x * scale.x, Uvs[index2].y * scale.z);
uvs[index3] = new Vector2(Uvs[index3].x * scale.x, Uvs[index3].y);
}
else if (Vertices[index3].y - Vertices[index1].y != 0)
{
uvs[index2] = new Vector2(Uvs[index2].x * scale.y, Uvs[index2].y * scale.z);
uvs[index3] = new Vector2(Uvs[index3].x * scale.y, Uvs[index3].y);
}
number = 0;
}
}
}
mh.uv = uvs.ToArray();//赋值UV
}
}
该代码还相对比较简陋,只能用于立方体的uv控制,复杂的uv还需要慢慢摸索,大家有什么好的方法也可以分享一下。