private static void Build(MeshBuilder builder, Decal decal, GameObject gameObject) { MeshFilter filter = decal.GetComponent <MeshFilter>() ?? decal.gameObject.AddComponent <MeshFilter>(); MeshRenderer renderer = decal.GetComponent <MeshRenderer>() ?? decal.gameObject.AddComponent <MeshRenderer>(); if (filter.sharedMesh != null && !filter.sharedMesh.isReadable) { return; } if (decal.material == null) { Object.DestroyImmediate(filter.sharedMesh); filter.sharedMesh = null; renderer.sharedMaterial = null; return; } Build(builder, decal, gameObject.GetComponent <MeshFilter>()); builder.Push(decal.pushDistance); if (filter.sharedMesh == null) { filter.sharedMesh = new Mesh(); filter.sharedMesh.name = "Decal"; } builder.ToMesh(filter.sharedMesh); filter.sharedMesh.UploadMeshData(true); renderer.sharedMaterial = decal.material; }
protected void Splat(Collision collision) { //old splash-mechanic with particles //SplatParticle splatParticle = new SplatParticle(); //splatParticle.position = collision.contacts[0].point; //splatParticle.position += collision.contacts[0].normal * 0.001f; //splatParticle.rotation = Quaternion.LookRotation(collision.contacts[0].normal).eulerAngles; //splatParticle.rotation.z = UnityEngine.Random.Range(0.0f, 360.0f); //splatParticle.size = UnityEngine.Random.Range(splatMinSize, splatMaxSize); //splatParticle.color = meshRenderer.material.color; //splatParticleSystem.AddSplatParticle(splatParticle); //new splash-mechanic with decals ("SimpleDecalSystem" from DENI35 is used (Unity Asset Store)) //splat needs an empty gameobject as parent for scaling GameObject parentSplat = decalPool.SpawnDecal(); parentSplat.transform.position = collision.contacts[0].point; parentSplat.transform.rotation = Quaternion.identity; parentSplat.transform.parent = collision.gameObject.transform; GameObject splat = parentSplat.transform.GetChild(0).gameObject; float newX = 0; _Decal.Decal decal = splat.GetComponent <_Decal.Decal>(); if (decal) { decal.transform.forward = -collision.contacts[0].normal; decal.material = splatMaterial; decal.maxAngle = 1; //randomize x, scale accordingly newX = UnityEngine.Random.Range(splatMinSize, splatMaxSize); Vector3 scale = new Vector3(newX, newX / (decal.sprite.rect.width / decal.sprite.rect.height), splat.transform.localScale.z); splat.transform.localScale = scale; //randomize z-angle Vector3 euler = splat.transform.eulerAngles; euler.z = UnityEngine.Random.Range(0f, 360f); splat.transform.eulerAngles = euler; _Decal.DecalBuilder.BuildAndSetDirty(decal); } parentSplat.transform.position += collision.contacts[0].normal * ZFighting.ZFightingDistanceStart; ZFighting.ZFightingDistanceStart += ZFighting.ZFightingDistanceStep; dropletParticleSystem.gameObject.transform.position = collision.contacts[0].point; dropletParticleSystem.gameObject.transform.rotation = Quaternion.LookRotation(collision.contacts[0].normal); ParticleSystem.ShapeModule shapeModule = dropletParticleSystem.shape; shapeModule.radius = 0.25f * newX; //shapeModule.radius = 0.25f * splatParticle.size; ParticleSystem.MainModule mainModule = dropletParticleSystem.main; mainModule.startColor = meshRenderer.material.color; dropletParticleSystem.Emit(UnityEngine.Random.Range(3, 6)); }
public override void OnInspectorGUI() { Decal decal = (Decal)target; decal.material = GUIUtils.DrawMaterialChooser(decal.material, materialPaths); if (decal.texture != null) { EditorGUILayout.Separator(); decal.sprite = GUIUtils.DrawSpriteList(decal.sprite, LoadSprites(decal.texture)); decal.sprite = GUIUtils.AssetField("Sprite", decal.sprite); } if (decal.sprite != null && decal.sprite.texture != decal.texture) { decal.sprite = null; } EditorGUILayout.Separator(); decal.maxAngle = EditorGUILayout.FloatField("Max Angle", decal.maxAngle); decal.maxAngle = Mathf.Clamp(decal.maxAngle, 1, 180); decal.pushDistance = EditorGUILayout.FloatField("Push Distance", decal.pushDistance); decal.pushDistance = Mathf.Clamp(decal.pushDistance, 0.01f, 0.1f); decal.affectedLayers = GUIUtils.LayerMaskField("Affected Layers", decal.affectedLayers); EditorGUILayout.Separator(); if (GUILayout.Button("Build")) { GUI.changed = true; } if (affectedObjects != null && affectedObjects.Length > 0) { EditorGUILayout.Separator(); EditorGUILayout.Separator(); GUILayout.Label("Affected Objects"); foreach (GameObject go in affectedObjects) { EditorGUILayout.ObjectField(go, typeof(GameObject), true); } } EditorGUILayout.Separator(); EditorGUILayout.Separator(); EditorGUILayout.HelpBox("Left Ctrl + Left Mouse Button - put decal on surface", MessageType.Info); if (GUI.changed) { affectedObjects = DecalBuilder.BuildAndSetDirty(decal); } }
void OnSceneGUI() { Decal decal = (Decal)target; if (Event.current.control) { HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); } if (Event.current.control && Event.current.type == EventType.MouseDown) { Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); RaycastHit hit = new RaycastHit(); if (Physics.Raycast(ray, out hit, 50)) { decal.transform.position = hit.point; decal.transform.forward = -hit.normal; } } Vector3 scale = decal.transform.localScale; Sprite sprite = decal.sprite; if (sprite != null) { float ratio = sprite.rect.width / sprite.rect.height; if (!Mathf.Approximately(oldScale.x, scale.x)) { scale.y = scale.x / ratio; } if (!Mathf.Approximately(oldScale.y, scale.y)) { scale.x = scale.y * ratio; } if (!Mathf.Approximately(scale.x / scale.y, ratio)) { scale.x = scale.y * ratio; } } decal.transform.localScale = scale; oldScale = scale; if (decal.transform.hasChanged) { decal.transform.hasChanged = false; affectedObjects = DecalBuilder.BuildAndSetDirty(decal); } }
public static MeshFilter[] GetAffectedObjects(Decal decal) { Bounds bounds = GetBounds( decal.transform ); return GameObject.FindObjectsOfType<MeshRenderer>() .Where( obj => obj.gameObject.isStatic ) .Where( obj => HasLayer( decal.affectedLayers, obj.gameObject.layer ) ) .Where( obj => obj.GetComponent<Decal>() == null ) .Where( obj => bounds.Intersects( obj.bounds ) ) .Select( obj => obj.GetComponent<MeshFilter>() ) .Where( obj => obj != null && obj.sharedMesh != null ) .ToArray(); }
private static void AddTriangle(MeshBuilder builder, Decal decal, Vector3 v1, Vector3 v2, Vector3 v3) { Rect uvRect = To01(decal.sprite.textureRect, decal.sprite.texture); Vector3 normal = Vector3.Cross(v2 - v1, v3 - v1).normalized; if (Vector3.Angle(Vector3.forward, -normal) <= decal.maxAngle) { var poly = PolygonClippingUtils.Clip(v1, v2, v3); if (poly.Length > 0) { builder.AddPolygon(poly, normal, uvRect); } } }
public static GameObject[] BuildAndSetDirty(Decal decal) { var affectedObjects = Build(builder, decal); if (decal.gameObject.scene.IsValid()) { if (!EditorApplication.isPlaying) { EditorSceneManager.MarkSceneDirty(decal.gameObject.scene); } } else { EditorUtility.SetDirty(decal.gameObject); } return(affectedObjects); }
private static GameObject[] Build(MeshBuilder builder, Decal decal) { MeshFilter filter = decal.GetComponent <MeshFilter>() ?? decal.gameObject.AddComponent <MeshFilter>(); MeshRenderer renderer = decal.GetComponent <MeshRenderer>() ?? decal.gameObject.AddComponent <MeshRenderer>(); if (filter.sharedMesh != null && !filter.sharedMesh.isReadable) { return(null); } if (decal.material == null || decal.sprite == null) { Object.DestroyImmediate(filter.sharedMesh); filter.sharedMesh = null; renderer.sharedMaterial = null; return(null); } var objects = DecalUtils.GetAffectedObjects(decal); foreach (var obj in objects) { Build(builder, decal, obj); } builder.Push(decal.pushDistance); if (filter.sharedMesh == null) { filter.sharedMesh = new Mesh(); filter.sharedMesh.name = "Decal"; } builder.ToMesh(filter.sharedMesh); renderer.sharedMaterial = decal.material; return(objects.Select(i => i.gameObject).ToArray()); }
private static void Build(MeshBuilder builder, Decal decal, MeshFilter @object) { Matrix4x4 objToDecalMatrix = decal.transform.worldToLocalMatrix * @object.transform.localToWorldMatrix; Mesh mesh = @object.sharedMesh; Vector3[] vertices = mesh.vertices; int[] triangles = mesh.triangles; 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 = objToDecalMatrix.MultiplyPoint(vertices[i1]); Vector3 v2 = objToDecalMatrix.MultiplyPoint(vertices[i2]); Vector3 v3 = objToDecalMatrix.MultiplyPoint(vertices[i3]); AddTriangle(builder, decal, v1, v2, v3); } }
public static void BuildAndSetDirty(Decal decal, GameObject gameObject) { Build(builder, decal, gameObject); }
public static GameObject[] BuildAndSetDirty(Decal decal) { var affectedObjects = Build(builder, decal); return(affectedObjects); }