最近在做编辑器的功能,碰到一个需求是创建任意长度的墙体。思路是点击鼠标,然后拖动鼠标,墙体长度随着鼠标的拖动而增加。 通过实现此功能,感觉其中有几个关键点: 1.绘制矩形顶点 2.绘制矩形三角面 3.绘制矩形纹理 4.绘制矩形法线 5.矩形始终指向鼠标位置 6.在结束绘制矩形时,调用Mesh.Clear(),然后重新给矩形顶点赋值,否则会出现拉近视角,模型消失的情况
目前发现的问题: 在绘制斜着的矩形时,发现贴图会有重影。
实现代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreateMesh : MonoBehaviour
{
[SerializeField]
private Material wallMat = null;
[SerializeField]
private float width = 1;
[SerializeField]
private float height = 3.4f;
private float length = 0;
private float halfWidth = 0;
private Mesh mesh = null;
private MeshRenderer meshRender = null;
private Vector3[] vertics = new Vector3[24];
private int[] triangles = new int[36];
private Vector2[] UVs = new Vector2[24];
private int clickCount = 0;
private RaycastHit hit;
private bool isStartCreate = false;
private Vector3 originPos = Vector3.zero;
private GameObject curObj = null;
private void Start()
{
halfWidth = width / 2f;
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (clickCount == 0)
{
StartCreateCustomObject();
clickCount = 1;
}
else if (clickCount == 1)
{
EndCreateCustomObject();
clickCount = 0;
}
}
CreatingCustomObject();
}
private void StartCreateCustomObject()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
curObj = new GameObject();
meshRender = curObj.AddComponent<MeshRenderer>();
meshRender.sharedMaterial = wallMat;
var vmf = curObj.AddComponent<MeshFilter>();
mesh = vmf.mesh;
curObj.transform.position = hit.point;
originPos = hit.point;
length = 0;
vertics = new Vector3[] {
new Vector3(0,0,halfWidth),
new Vector3(0,height,halfWidth),
new Vector3(0,height,-halfWidth),
new Vector3(0,0,-halfWidth),
new Vector3(0,0,-halfWidth),
new Vector3(0,height,-halfWidth),
new Vector3(0,height,-halfWidth),
new Vector3(0,0,-halfWidth),
new Vector3(0,0,-halfWidth),
new Vector3(0,height,-halfWidth),
new Vector3(0,height,halfWidth),
new Vector3(0,0,halfWidth),
new Vector3(0,0,halfWidth),
new Vector3(0,height,halfWidth),
new Vector3(0,height,halfWidth),
new Vector3(0,0,halfWidth),
new Vector3(0,height,-halfWidth),
new Vector3(0,height,halfWidth),
new Vector3(0,height,halfWidth),
new Vector3(0,height,-halfWidth),
new Vector3(0,0,halfWidth),
new Vector3(0,0,-halfWidth),
new Vector3(0,0,-halfWidth),
new Vector3(0,0,halfWidth)
};
mesh.vertices = vertics;
triangles = new int[] {
0,1,2,
2,3,0,
4,5,6,
6,7,4,
8,9,10,
10,11,8,
12,13,14,
14,15,12,
16,17,18,
18,19,16,
20,21,22,
22,23,20
};
mesh.triangles = triangles;
UVs = new Vector2[] {
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,1),
new Vector2(1,0),
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,1),
new Vector2(1,0),
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,1),
new Vector2(1,0),
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,1),
new Vector2(1,0),
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,1),
new Vector2(1,0),
new Vector2(0,0),
new Vector2(0,1),
new Vector2(1,1),
new Vector2(1,0),
};
mesh.uv = UVs;
mesh.RecalculateNormals();
isStartCreate = true;
}
}
private void CreatingCustomObject()
{
if (isStartCreate)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
vertics = mesh.vertices;
var vEndCenterX = hit.point.x - originPos.x;
var vEndCenterZ = hit.point.z - originPos.z;
length = Mathf.Sqrt(vEndCenterX * vEndCenterX + vEndCenterZ * vEndCenterZ);
var vros = hit.point - originPos;
curObj.transform.rotation = Quaternion.FromToRotation(Vector3.right, vros);
vertics[6] = new Vector3(length, height, -halfWidth);
vertics[7] = new Vector3(length, 0, -halfWidth);
vertics[8] = new Vector3(length, 0, -halfWidth);
vertics[9] = new Vector3(length, height, -halfWidth);
vertics[10] = new Vector3(length, height, halfWidth);
vertics[11] = new Vector3(length, 0, halfWidth);
vertics[12] = new Vector3(length, 0, halfWidth);
vertics[13] = new Vector3(length, height, halfWidth);
vertics[18] = new Vector3(length, height, halfWidth);
vertics[19] = new Vector3(length, height, -halfWidth);
vertics[22] = new Vector3(length, 0, -halfWidth);
vertics[23] = new Vector3(length, 0, halfWidth);
mesh.vertices = vertics;
mesh.RecalculateNormals();
}
}
}
private void EndCreateCustomObject()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
mesh.Clear();
var vEndCenterX = hit.point.x - originPos.x;
var vEndCenterZ = hit.point.z - originPos.z;
length = Mathf.Sqrt(vEndCenterX * vEndCenterX + vEndCenterZ * vEndCenterZ);
var vros = hit.point - originPos;
curObj.transform.rotation = Quaternion.FromToRotation(Vector3.right, vros);
vertics[6] = new Vector3(length, height, -halfWidth);
vertics[7] = new Vector3(length, 0, -halfWidth);
vertics[8] = new Vector3(length, 0, -halfWidth);
vertics[9] = new Vector3(length, height, -halfWidth);
vertics[10] = new Vector3(length, height, halfWidth);
vertics[11] = new Vector3(length, 0, halfWidth);
vertics[12] = new Vector3(length, 0, halfWidth);
vertics[13] = new Vector3(length, height, halfWidth);
vertics[18] = new Vector3(length, height, halfWidth);
vertics[19] = new Vector3(length, height, -halfWidth);
vertics[22] = new Vector3(length, 0, -halfWidth);
vertics[23] = new Vector3(length, 0, halfWidth);
mesh.vertices = vertics;
mesh.triangles = triangles;
mesh.uv = UVs;
mesh.RecalculateNormals();
curObj.AddComponent<BoxCollider>();
curObj = null;
isStartCreate = false;
}
}
}
墙体Shader:https://download.csdn.net/download/qq_39353597/52010659 参考资料:https://docs.unity.cn/cn/2019.4/Manual/UsingtheMeshClass.html
|