Unity3D 동적 생 성 평면 격자

4899 단어 Unity3D평면 격자
기하학 적 착색 기 를 작성 할 때 기본 Plane 이 수 요 를 만족 시 키 지 못 하고 정점 순 서 를 알 수 없 음 을 발 견 했 습 니 다.그래서 격자 생 성 코드 를 써 서 지정 한 크기 의 Plane 을 만 들 수 있 고 정점 순 서 를 제어 할 수 있 습 니 다.
효 과 는 다음 과 같 습 니 다:

하나의 단원 격 은 네 개의 정점,두 개의 삼각 면 으로 이 루어 져 있다.
네 개의 정점 은 아래 그림 과 같다.

생 성 면 의 정점 순 서 는:
왼쪽 위 삼각형:0->1->2
오른쪽 아래 삼각형:2->3->0
유 니 티 에 서 는 시계 반대 방향 으로,시계 반대 방향 으로 그립 니 다.
구현 스 크 립 트 는 다음 과 같 습 니 다:

//PlaneBuilder.cs

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

#region Editor

#if UNITY_EDITOR

using UnityEditor;

[CustomEditor(typeof(PlaneBuilder))]
public class PlaneBuilderEditor : Editor
{
 public override void OnInspectorGUI()
 {
 PlaneBuilder builder = (PlaneBuilder)target;

 EditorGUI.BeginChangeCheck();

 base.OnInspectorGUI();

 if (EditorGUI.EndChangeCheck())
 {
  builder.UpdateMesh();
 }

 if (GUILayout.Button("    "))
 {
  builder.UpdateMesh();
 }
 }
}

#endif

#endregion Editor

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class PlaneBuilder : MonoBehaviour
{
 [SerializeField]
 private MeshFilter _meshFilter;

 [SerializeField]
 private MeshRenderer _meshRenderer;

 /// <summary>
 ///      
 /// </summary>
 [SerializeField]
 private Vector2 _cellSize = new Vector2(1, 1);

 /// <summary>
 ///     
 /// </summary>
 [SerializeField]
 private Vector2Int _gridSize = new Vector2Int(2, 2);

 public MeshRenderer MeshRenderer
 {
 get
 {
  return _meshRenderer;
 }
 }

 public MeshFilter MeshFilter
 {
 get
 {
  return _meshFilter;
 }
 }

 private void Awake()
 {
 _meshFilter = GetComponent<MeshFilter>();
 _meshRenderer = GetComponent<MeshRenderer>();
 UpdateMesh();
 }

 public void UpdateMesh()
 {
 Mesh mesh = new Mesh();

 //  Plane  
 Vector2 size;
 size.x = _cellSize.x * _gridSize.x;
 size.y = _cellSize.y * _gridSize.y;

 //  Plane    
 Vector2 halfSize = size / 2;

 //     UV
 List<Vector3> vertices = new List<Vector3>();
 List<Vector2> uvs = new List<Vector2>();

 Vector3 vertice = Vector3.zero;
 Vector2 uv = Vector3.zero;

 for (int y = 0; y < _gridSize.y + 1; y++)
 {
  vertice.z = y * _cellSize.y - halfSize.y;//    Y 
  uv.y = y * _cellSize.y / size.y;//        V

  for (int x = 0; x < _gridSize.x + 1; x++)
  {
  vertice.x = x * _cellSize.x - halfSize.x;//    X 
  uv.x = x * _cellSize.x / size.x;//        U

  vertices.Add(vertice);//       
  uvs.Add(uv);//         
  }
 }

 //    
 int a = 0;
 int b = 0;
 int c = 0;
 int d = 0;
 int startIndex = 0;
 int[] indexs = new int[_gridSize.x * _gridSize.y * 2 * 3];//    
 for (int y = 0; y < _gridSize.y; y++)
 {
  for (int x = 0; x < _gridSize.x; x++)
  {
  //       
  a = y * (_gridSize.x + 1) + x;//0
  b = (y + 1) * (_gridSize.x + 1) + x;//1
  c = b + 1;//2
  d = a + 1;//3

  //           
  startIndex = y * _gridSize.x * 2 * 3 + x * 2 * 3;

  //     
  indexs[startIndex] = a;//0
  indexs[startIndex + 1] = b;//1
  indexs[startIndex + 2] = c;//2

  //     
  indexs[startIndex + 3] = c;//2
  indexs[startIndex + 4] = d;//3
  indexs[startIndex + 5] = a;//0
  }
 }

 //
 mesh.SetVertices(vertices);//    
 mesh.SetUVs(0, uvs);//  UV
 mesh.SetIndices(indexs, MeshTopology.Triangles, 0);//      
 mesh.RecalculateNormals();
 mesh.RecalculateBounds();
 mesh.RecalculateTangents();

 _meshFilter.mesh = mesh;
 }

#if UNITY_EDITOR

 private void OnValidate()
 {
 if (null == _meshFilter)
 {
  _meshFilter = GetComponent<MeshFilter>();
 }
 if (null == _meshRenderer)
 {
  _meshRenderer = GetComponent<MeshRenderer>();
  if (null == _meshRenderer.sharedMaterial)
  {
  _meshRenderer.sharedMaterial = new Material(Shader.Find("Standard"));
  }
 }
 }

#endif
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기