已知条件是:Point1、Point2
间接已知条件:这两个点的垂直面Plane1
这个时候计算Plane1的法线即可。
根据Point1和Point2获取垂直点,高度可以自定义
private static Vector3 GetUpPoint(Vector3 point, float m_height)
{
return new Vector3(point.x, point.y + m_height, point.z);
}
Vector3 Point3 = GetUpPoint(m_point1, m_height) - m_point1;//p1p2的垂直向量
暂时定义这个点为Point3
根据P1P2向量和P1P3的向量叉乘之后获取垂直向量,这个向量就是我们想要的水平面的一个点
private static Vector3 GetCorner(Vector3 v1, Vector3 v2, Vector3 startPoint, float m_width)
{
Vector3 forward = (Vector3.Cross(v1, v2).normalized * m_width + startPoint);
return forward;
}
然后根据向量的方向,依次算出水平面的四个点
Vector3 xl10 = m_point2 - m_point1;//p1p2向量
Vector3 xl20 = GetUpPoint(m_point1, m_height) - m_point1;//p1p2的垂直向量
Vector3 result1 = GetCorner(xl10, xl20, m_point1, m_width);
Vector3 xl11 = m_point1 - m_point2;//p2p1向量
Vector3 xl21 = GetUpPoint(m_point1, m_height) - m_point1;//p2p1在p1上的垂直向量
Vector3 result2 = GetCorner(xl11, xl21, m_point1, m_width);
Vector3 xl12 = m_point1 - m_point2;//p2p1向量
Vector3 xl22 = GetUpPoint(m_point2, m_height) - m_point2;//p2p1在p2上的的垂直向量
Vector3 result3 = GetCorner(xl12, xl22, m_point2, m_width);
Vector3 xl13 = m_point2 - m_point1;//p1p2向量
Vector3 xl23 = GetUpPoint(m_point2, m_height) - m_point2;//p1p2在p2上的垂直向量
Vector3 result4 = GetCorner(xl13, xl23, m_point2, m_width);
再根据这四个点绘制平面即可
private static void DrawPlane(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Transform parent, string name, bool isClockwise = false)
{
List<Vector3> vector3s = new List<Vector3>();
vector3s.Add(v1);
vector3s.Add(v2);
vector3s.Add(v3);
vector3s.Add(v4);
GameObject plane1 = new GameObject(name);
plane1.AddComponent<MeshFilter>().mesh = CreateMesh(vector3s, isClockwise);
plane1.AddComponent<MeshRenderer>().material = new Material(Shader.Find("Standard"));
plane1.transform.parent = parent;
}
public static Mesh CreateMesh(List<Vector3> points, bool isClockwise = false)
{
Mesh mesh = new Mesh();
Vector3[] vertices = new Vector3[4]{
points[0],
points[1],
points[2],
points[3],
};
int[] triangles;
if (!isClockwise)
{
triangles = new int[2 * 3]{
0, 1, 2, 2, 3, 0
};
}
else
{
triangles = new int[2 * 3]{
1, 0, 3, 3, 2, 1
};
}
Vector2[] uv = new Vector2[4]{
new Vector2(1, 1),
new Vector2(1, 0),
new Vector2(0, 0),
new Vector2(0, 1)
};
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uv;
return mesh;
}
这个问题可以解决给LineRenderer的添加Collider的问题,然后出现很多小的Mesh,在网上找了个合并Mesh的方法。
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
public class MergeUtils
{
/// <summary>
/// 合并网格
/// </summary>
private static void MergeMesh2(GameObject parent, bool mergeSubMeshes = false)
{
MeshRenderer[] meshRenderers = parent.GetComponentsInChildren<MeshRenderer>();
Material[] materials = new Material[meshRenderers.Length];
for (int i = 0; i < meshRenderers.Length; i++)
{
materials[i] = meshRenderers[i].sharedMaterial;
}
MeshFilter[] meshFilters = parent.GetComponentsInChildren<MeshFilter>(); //获取 所有子物体的网格
CombineInstance[] combineInstances = new CombineInstance[meshFilters.Length]; //新建一个合并组,长度与 meshfilters一致
for (int i = 0; i < meshFilters.Length; i++) //遍历
{
combineInstances[i].mesh = meshFilters[i].sharedMesh; //将共享mesh,赋值
combineInstances[i].transform = meshFilters[i].transform.localToWorldMatrix; //本地坐标转矩阵,赋值
GameObject.DestroyImmediate(meshFilters[i].gameObject);
}
Mesh newMesh = new Mesh(); //声明一个新网格对象
newMesh.CombineMeshes(combineInstances, mergeSubMeshes, true); //将combineInstances数组传入函数
parent.AddComponent<MeshFilter>().sharedMesh = newMesh; //给当前空物体,添加网格组件;将合并后的网格,给到自身网格
parent.AddComponent<MeshRenderer>().sharedMaterials = materials;
}
public static GameObject[] MergeMesh(GameObject parent, bool mergeAll = true, bool deleteChildren = false, bool mergeSubMeshes = false)
{
List<GameObject> list = new List<GameObject>();
int verts = 0;
//存放要合并的父物体
Dictionary<int, GameObject> NewParent = new Dictionary<int, GameObject>();
//获取所有网格过滤器;
MeshFilter[] meshFilters = parent.GetComponentsInChildren<MeshFilter>();
for (int i = 0; i < meshFilters.Length; i++)
{
verts += meshFilters[i].mesh.vertexCount;
if (NewParent.ContainsKey((verts / 65536) + 1))
{
meshFilters[i].transform.parent = NewParent[(verts / 65536) + 1].transform;
}
else
{
GameObject wx = new GameObject("Combine");
wx.transform.parent = parent.transform;
NewParent.Add((verts / 65536) + 1, wx);
meshFilters[i].transform.parent = NewParent[(verts / 65536) + 1].transform;
}
}
foreach (var item in NewParent)
{
list.Add(MergeUtils.MergeMesh3(item.Value, true, true));
}
if (deleteChildren)
{
//合并完成后删除子项
for (int i = parent.transform.childCount - 1; i >= 0; i--)
{
if (parent.transform.GetChild(i).name != "Combine")
{
GameObject.Destroy(parent.transform.GetChild(i).gameObject);
}
}
}
return list.ToArray();
}
public static GameObject MergeMesh3(GameObject parent, bool mergeAll = true, bool deleteChildren = false, bool mergeSubMeshes = false)
{
//获取所有网格过滤器;
MeshFilter[] meshFilters = parent.GetComponentsInChildren<MeshFilter>();
//存放不同的材质球,相同的就存一个;
Dictionary<string, Material> materials = new Dictionary<string, Material>();
//存放要合并的网格对象;
Dictionary<string, List<CombineInstance>> combines = new Dictionary<string, List<CombineInstance>>();
for (int i = 0; i < meshFilters.Length; i++)
{
//构造一个网格合并结构体;
CombineInstance combine = new CombineInstance();
//给结构体的mesh赋值;
combine.mesh = meshFilters[i].sharedMesh;
combine.transform = meshFilters[i].transform.localToWorldMatrix;
MeshRenderer renderer = meshFilters[i].GetComponent<MeshRenderer>();
if (renderer == null)
{
continue;
}
Material mat = renderer.sharedMaterial;
if (!materials.ContainsKey(mat.name))
{
materials.Add(mat.name, mat);
}
if (combines.ContainsKey(mat.name))
{
combines[mat.name].Add(combine);
}
else
{
List<CombineInstance> coms = new List<CombineInstance>();
coms.Add(combine);
combines[mat.name] = coms;
}
//Destroy(meshFilters[i].gameObject);
}
GameObject combineObj = new GameObject("Combine");
combineObj.transform.parent = parent.transform;
foreach (KeyValuePair<string, Material> mater in materials)
{
GameObject obj = new GameObject(mater.Key);
obj.transform.parent = combineObj.transform;
MeshFilter combineMeshFilter = obj.AddComponent<MeshFilter>();
combineMeshFilter.mesh = new Mesh();
//将引用相同材质球的网格合并;
combineMeshFilter.sharedMesh.CombineMeshes(combines[mater.Key].ToArray(), true, true);
Debug.LogError("网格定点数" + combineMeshFilter.sharedMesh.vertices);
MeshRenderer rend = obj.AddComponent<MeshRenderer>();
//指定材质球;
rend.sharedMaterial = mater.Value;
rend.shadowCastingMode = ShadowCastingMode.Off;
rend.receiveShadows = true;
}
if (mergeAll)
{
MergeMesh2(combineObj);
//Combine(combineObj)
}
if (deleteChildren)
{
//合并完成后删除子项
for (int i = parent.transform.childCount - 1; i >= 0; i--)
{
if (parent.transform.GetChild(i).name != "Combine")
{
GameObject.Destroy(parent.transform.GetChild(i).gameObject);
}
}
}
return combineObj;
}
public static GameObject MergeMesh4(GameObject parent, bool mergeAll = true, bool deleteChildren = false, bool mergeSubMeshes = false)
{
//获取所有网格过滤器;
MeshFilter[] meshFilters = parent.GetComponentsInChildren<MeshFilter>();
//存放不同的材质球,相同的就存一个;
Dictionary<string, Material> materials = new Dictionary<string, Material>();
//存放要合并的网格对象;
Dictionary<string, List<CombineInstance>> combines = new Dictionary<string, List<CombineInstance>>();
for (int i = 0; i < meshFilters.Length; i++)
{
//构造一个网格合并结构体;
CombineInstance combine = new CombineInstance();
//给结构体的mesh赋值;
combine.mesh = meshFilters[i].sharedMesh;
combine.transform = meshFilters[i].transform.localToWorldMatrix;
MeshRenderer renderer = meshFilters[i].GetComponent<MeshRenderer>();
if (renderer == null)
{
continue;
}
Material mat = renderer.sharedMaterial;
if (!materials.ContainsKey(mat.name))
{
materials.Add(mat.name, mat);
}
if (combines.ContainsKey(mat.name))
{
combines[mat.name].Add(combine);
}
else
{
List<CombineInstance> coms = new List<CombineInstance>();
coms.Add(combine);
combines[mat.name] = coms;
}
//Destroy(meshFilters[i].gameObject);
}
GameObject combineObj = new GameObject("Combine");
combineObj.transform.parent = parent.transform;
foreach (KeyValuePair<string, Material> mater in materials)
{
GameObject obj = new GameObject(mater.Key);
obj.transform.parent = combineObj.transform;
MeshFilter combineMeshFilter = obj.AddComponent<MeshFilter>();
combineMeshFilter.mesh = new Mesh();
//将引用相同材质球的网格合并;
combineMeshFilter.sharedMesh.CombineMeshes(combines[mater.Key].ToArray(), true, true);
Debug.LogError("网格定点数" + combineMeshFilter.sharedMesh.vertices);
MeshRenderer rend = obj.AddComponent<MeshRenderer>();
//指定材质球;
rend.sharedMaterial = mater.Value;
rend.shadowCastingMode = ShadowCastingMode.Off;
rend.receiveShadows = true;
}
if (mergeAll)
{
MergeMesh2(combineObj);
//Combine(combineObj)
}
if (deleteChildren)
{
//合并完成后删除子项
for (int i = parent.transform.childCount - 1; i >= 0; i--)
{
if (parent.transform.GetChild(i).name != "Combine")
{
GameObject.Destroy(parent.transform.GetChild(i).gameObject);
}
}
}
return combineObj;
}
}
之后再给这个合并的Mesh添加触发器就可以完美的添加Collider