mesh就是组成3d物体的三角形们。
mesh由顶点组成的三角形组成,三角形的大小 并不 需要一样,由顶点之间的位置决定。
mesh可以是一个或者多个面。
贴图的原点在左下角,uv是贴图的坐标,数量和顶点数一样(不是100%确定,比如前后左右4个面,贴图最终如何封闭,我还不知道),是贴图和顶点的对应关系。
新建空场景,把一下代码放到main camera:
- using System;
- using System.Collections;
- using System.Collections.Generic;
-
- using UnityEngine;
- #if UNITY_EDITOR
- using UnityEditor;
- #endif
-
- public class codeMesh2 : MonoBehaviour
- {
- GUIStyle fontStyle = new GUIStyle();
- string msg = " - - ";
- // Start is called before the first frame update
- Vector3 center = new Vector3();
- GameObject o;
- bool ready = false;
- //int startCalled = 0;
- Camera c;
- string err = "";
- int moveRage = 25;
- int moveRage2 = 0;
- int moveRage2_1 = 0;
- Mesh mesh = null;
-
- public int width = 10;
- public int height = 10;
- public Texture aText = null;
-
- ///
- /// 上一次更新帧率的时间
- ///
- private float m_lastUpdateShowTime = 0f;
- ///
- /// 更新显示帧率的时间间隔
- ///
- private readonly float m_updateTime = 0.05f;
- ///
- /// 帧数
- ///
- private int m_frames = 0;
- ///
- /// 帧间间隔
- ///
- //private float m_frameDeltaTime = 0;
- private float m_FPS = 0;
- //private Rect m_fps, m_dtime;
-
- //顶点数组
- private Vector3[] vertices;
- //顶点法线
- private Vector3[] normals;
- private MeshFilter meshFilter;
-
- private int i = 0;
- private bool f = false;
- private string test2 = "";
- private int waitCount = 0;
- private void Awake()
- {
- Application.targetFrameRate = 30;
- moveRage2 = moveRage * 2;
- moveRage2_1 = moveRage * 2 - 1;
-
- fontStyle.normal.background = null; //设置背景填充
- fontStyle.normal.textColor = Color.red; //设置字体颜色
- fontStyle.fontSize = 40;
- fontStyle.wordWrap = true;
- c = GetComponent
(); - msg += " Waiting ";
-
- Vector3 v1 = new Vector3(5, 5, 5);
- Vector3 v2 = new Vector3(5, 5, 3);
-
- test2 = (v2 - v1).normalized.ToString();
- }
-
- void Start()
- {
- try
- {
- o = GenerateMeshTest1();
- center = c.transform.position;
- o.name = "d mesh";
- o.transform.position = new Vector3(-5, -5, 20);
- o.transform.localScale = new Vector3(10.0f, 10.0f, 10.0f);
- o.transform.rotation = Quaternion.Euler(new Vector3(0, 45, 45));
- m_lastUpdateShowTime = Time.realtimeSinceStartup;
- ready = true;
- }
- catch (Exception e)
- {
- err = printException(e);
- }
-
- aText = Resources.Load("type/two_sizes") as Texture;
-
- o.GetComponent
().material.mainTexture = aText; -
- #if UNITY_EDITOR
- showNormals();
- #endif
-
- }
- private void OnGUI()
- {
- GUI.color = Color.red;
- msg = "fps=" + m_FPS + "/"+ Application.targetFrameRate +(err.Length>1?(", err=" + err):"") + " waitCount = " + (ready? waitCount : (waitCount++));
-
- GUI.Label(new Rect(50, 10, 900, 100), "" + test2, fontStyle);
- GUI.Label(new Rect(100, 100, 900, 100), "[V07]:" + msg, fontStyle);
- }
-
- // Update is called once per frame
- void Update()
- {
- if (!ready) return;
- int ri = i % (moveRage2);
-
- float x = ri - moveRage;
-
- if (!f)
- {
- x = moveRage - ri;
- }
-
- if (ri == moveRage2_1)
- {
- f = !f;
- }
- //o.transform.position = new Vector3(x, x, 20);
- //Debug.Log(x);
- //o.transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0));
-
- /*
- Mesh mesh = o.GetComponent
().mesh; - //mesh.Clear();
- Vector3[] vertices = mesh.vertices;
- Vector3[] normals = mesh.normals;
- for (var i = 0; i < vertices.Length; i++)
- {
- vertices[i] += normals[i] * Mathf.Sin(Time.time);
- }
- mesh.vertices = vertices;
- */
-
-
- m_frames++;
- if (Time.realtimeSinceStartup - m_lastUpdateShowTime >= m_updateTime)
- {
- m_FPS = m_frames / (Time.realtimeSinceStartup - m_lastUpdateShowTime);
- //m_frameDeltaTime = (Time.realtimeSinceStartup - m_lastUpdateShowTime) / m_frames;
- m_frames = 0;
- m_lastUpdateShowTime = Time.realtimeSinceStartup;
- //Debug.Log("FPS: " + m_FPS + ",间隔: " + m_FrameDeltaTime);
- }
- i++;
- }
-
-
- private GameObject GenerateMeshTest1()
- {
- GameObject obj = new GameObject();
- meshFilter = obj.AddComponent
(); - //创建mesh
- mesh = new Mesh();
- meshFilter.mesh = mesh;
- MeshRenderer renderer = obj.AddComponent
(); - //标准材质
- Material mat = new Material(Shader.Find("Legacy Shaders/Transparent/Diffuse"));
- mat.color = Color.white;
- renderer.material = mat;
-
- //创建顶点和UV
- vertices = new Vector3[6];
- Vector2[] uv = new Vector2[6];
-
- vertices[0] = new Vector3(0, 1, 0);//0
- vertices[1] = new Vector3(1, 1, 0);//1
- vertices[2] = new Vector3(1, 0, 0);//2
- vertices[3] = new Vector3(0, 0, 0);//3
- vertices[4] = new Vector3(0, 0, 1);//4
- vertices[5] = new Vector3(1, 0, 1);//5-
- int k = 0;
- uv[k++%6] = new Vector2(0, 1);
- uv[k++ % 6] = new Vector2(1, 1);
- uv[k++ % 6] = new Vector2(1, 0.5f);
- uv[k++ % 6] = new Vector2(0,0.5f);
- uv[k++ % 6] = new Vector2(0, 0);
- uv[k++ % 6] = new Vector2(1, 0);
-
- mesh.vertices = vertices;
- mesh.uv = uv;
- //mat.mainTexture = aText;
-
- int[] triangles = new int[12];
- k = 0;
- triangles[k++] = 3;
- triangles[k++] = 2;
- triangles[k++] = 5;
-
- triangles[k++] = 3;
- triangles[k++] = 5;
- triangles[k++] = 4;
-
- triangles[k++] = 0;
- triangles[k++] = 1;
- triangles[k++] = 2;
-
- triangles[k++] = 0;
- triangles[k++] = 2;
- triangles[k++] = 3;
-
-
-
-
- mesh.triangles = triangles; //三角面
- mesh.RecalculateNormals(); //计算法线
-
-
-
- /*Vector3[] normals = new Vector3[4];
- normals[0] = Vector3.back;
- normals[1] = Vector3.back;
- normals[2] = Vector3.back;
- normals[3] = Vector3.back;
- mesh.normals = normals;*/
-
-
-
- //mesh.SetIndices
- //mat.SetTexture()
-
- return obj;
- }
-
- public static string printException(Exception e)
- {
- return "\n\trs=" + e.HResult + ",\n\tmsg=" + e.Message + ",\n\tstack=" + e.StackTrace + "\n------------------------------------\n";
- }
-
-
- #if UNITY_EDITOR
- private void showNormals()
- {
- if (mesh != null)
- {
- //当前对象的操做从局部空间转换到世界空间 这样在下面的操作位置即可同步 否则位置是不会同步的
- Handles.matrix = meshFilter.transform.localToWorldMatrix;
- Handles.color = Color.green;
-
- int vertextCount = mesh.vertices.Length;
- //采用从顶点的位置[法线的起点】到法线的终点位置,既可以显示出当前顶点的法线
- for (int index = 0; index < vertextCount; index++)
- {
- Handles.DrawLine(vertices[index], vertices[index] + normals[index]);
- }
- }
- }
- #endif
- }
two_sizes.png是一张 宽高比为1:2的图片。
三角形之间的定义顺序不会影响贴图。但单个三角形三个顶点是逆时针,则从外部可以看到贴图,从内部看不到。反之亦然:
(顺时针之后,从内部可见)
如果把图片直接放到场景,则两面都可见。