public void BuildDecal(DecalBuildInfo decalInfo, string decalAltasName = "DecalDefault") { Material decalMat = null; if (decalInfo.decalMat == null) //没有专门指定材质球 { if (decalAltasName != "" && decalMatPool.ContainsKey(decalAltasName)) { decalMat = decalMatPool[decalAltasName]; } else { Shader decalShader = AssetBundleManager.GetShader("Decal/Default"); decalMat = new Material(decalShader); decalMatPool.Add(decalAltasName, decalMat); } } else { decalMat = decalInfo.decalMat; } decalMat.mainTexture = decalInfo.decalSprite.texture; Decal decal = CreateDecalObj(decalInfo.decalPos, decalInfo.decalEulerAngle, decalInfo.decalScale); decal.SetMaterial(decalMat); decal.DecalSprite = decalInfo.decalSprite; //淡入淡出 decal.decalFadeInTime = decalInfo.decalFadeInTime; decal.decalFadeTime = decalInfo.decalFadeTime; decal.decalFadeOutTime = decalInfo.decalFadeOutTime; BuildDecalMesh(decal); }
private Decal CreateDecalObj(Vector3 position, Vector3 eulerAngle, Vector3 scale) { GameObject decalObj = new GameObject(); decalObj.layer = LayerMask.NameToLayer(Config.LayerIngoreRayCast); Decal decal = decalObj.AddComponent <Decal>(); decal.m_Filter = decalObj.GetComponent <MeshFilter>(); decal.m_Render = decalObj.GetComponent <MeshRenderer>(); decal.transform.position = position; decal.transform.eulerAngles = eulerAngle; decal.transform.localScale = scale; decal.affectedLayers = 1 << LayerMask.NameToLayer(Config.LayerBuilding); decal.affectedLayers = decal.affectedLayers & (~(1 << decalObj.layer)); return(decal); }
private void BuildDecalMesh(Decal decal) { GameObject[] affectedObjects = GetAffectedObjects(decal.GetBounds(), decal.affectedLayers); foreach (GameObject go in affectedObjects) { DecalBuilder.BuildDecalForObject(decal, go); } DecalBuilder.Push(decal.pushDistance); Mesh mesh = DecalBuilder.CreateMesh(); if (mesh != null) { mesh.name = "DecalMesh"; decal.m_Filter.mesh = mesh; } }
public static void BuildDecalForObject(Decal decal, GameObject affectedObject) { Mesh affectedMesh = affectedObject.GetComponent <MeshCollider>().sharedMesh; affectedMesh.MarkDynamic(); if (affectedMesh == null) { return; } float maxAngle = decal.maxAngle; Plane right = new Plane(Vector3.right, Vector3.right / 2f); Plane left = new Plane(-Vector3.right, -Vector3.right / 2f); Plane top = new Plane(Vector3.up, Vector3.up / 2f); Plane bottom = new Plane(-Vector3.up, -Vector3.up / 2f); Plane front = new Plane(Vector3.forward, Vector3.forward / 2f); Plane back = new Plane(-Vector3.forward, -Vector3.forward / 2f); Vector3[] vertices = affectedMesh.vertices; int[] triangles = affectedMesh.triangles; int startVertexCount = bufVertices.Count; Matrix4x4 matrix = decal.transform.worldToLocalMatrix * affectedObject.transform.localToWorldMatrix; for (int i = 0; i < triangles.Length; i += 3) { int i1 = triangles[i]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; Vector3 v1 = matrix.MultiplyPoint(vertices[i1]); Vector3 v2 = matrix.MultiplyPoint(vertices[i2]); Vector3 v3 = matrix.MultiplyPoint(vertices[i3]); Vector3 side1 = v2 - v1; Vector3 side2 = v3 - v1; Vector3 normal = Vector3.Cross(side1, side2).normalized; if (Vector3.Angle(-Vector3.forward, normal) >= maxAngle) { continue; } DecalPolygon poly = new DecalPolygon(v1, v2, v3); poly = DecalPolygon.ClipPolygon(poly, right); if (poly == null) { continue; } poly = DecalPolygon.ClipPolygon(poly, left); if (poly == null) { continue; } poly = DecalPolygon.ClipPolygon(poly, top); if (poly == null) { continue; } poly = DecalPolygon.ClipPolygon(poly, bottom); if (poly == null) { continue; } poly = DecalPolygon.ClipPolygon(poly, front); if (poly == null) { continue; } poly = DecalPolygon.ClipPolygon(poly, back); if (poly == null) { continue; } AddPolygon(poly, normal); } GenerateTexCoords(startVertexCount, decal.DecalSprite); }