My friend found this script and it works pretty well but there’s some framedrops so i wanted to ask if you guys have any ideas on how to improve it’s performance.
We’re using this script + OnTriggerEnter on our enemies so they explode when the player dashes through them. The enemy is shattered into many pieces(±900) and that causes performance issues, especially on the CPU with physics.processing, i think shattering in 100 pieces would be better but not sure how to make that work.
+Edit: I now set Time.timeScale to 0.1f at the start and back to 1 at the end and this seems to help a little but i’m still stuck at reducing the amount of triangles
IEnumerator SplitMesh()
{
MeshFilter MF = GetComponent<MeshFilter>();
MeshRenderer MR = GetComponent<MeshRenderer>();
Mesh M = MF.mesh;
Vector3[] verts = M.vertices;
Vector3[] normals = M.normals;
Vector2[] uvs = M.uv;
for (int submesh = 0; submesh < M.subMeshCount; submesh++)
{
int[] indices = M.GetTriangles(submesh);
for (int i = 0; i < indices.Length; i += 3)
{
Vector3[] newVerts = new Vector3[3];
Vector3[] newNormals = new Vector3[3];
Vector2[] newUvs = new Vector2[3];
for (int n = 0; n < 3; n++)
{
int index = indices[i + n];
newVerts[n] = verts[index];
newUvs[n] = uvs[index];
newNormals[n] = normals[index];
}
Mesh mesh = new Mesh();
mesh.vertices = newVerts;
mesh.normals = newNormals;
mesh.uv = newUvs;
mesh.triangles = new int[] { 0, 1, 2, 2, 1, 0 };
GameObject GO = new GameObject("Triangle " + (i / 3));
GO.transform.position = transform.position;
GO.transform.rotation = transform.rotation;
//GO.AddComponent<MeshRenderer>().material = MR.materials[submesh];
GO.AddComponent<MeshRenderer>().materials = MR.materials;
GO.AddComponent<MeshFilter>().mesh = mesh;
GO.AddComponent<BoxCollider>();
GO.AddComponent<Rigidbody>().AddExplosionForce(100, transform.position, 30);
Destroy(GO, 5 + Random.Range(0.0f, 5.0f));
}
}
MR.enabled = false;
Time.timeScale = 1.0f;
yield return new WaitForSeconds(0.8f);
Time.timeScale = 1.0f;
Destroy(gameObject);
}
/*void OnMouseDown()
{
StartCoroutine(SplitMesh());
}*/
}
Thanks in advance
-
Edit2: Here’s the full working script:
using UnityEngine;
using System.Collections;public class ShatterScript : MonoBehaviour{
//Change this value to split into bigger pieces
int size = 15;
Vector3 newVerts = new Vector3[3];
Vector3 newNormals = new Vector3[3];
Vector2 newUvs = new Vector2[3];//Check for collision with player or enemy if this is an ally private void OnTriggerEnter(Collider other) { if (this.name == "Virus" && other.name == "Player") { PlayerControl playerControl = other.GetComponent<PlayerControl>(); if (playerControl.boosting) StartCoroutine(SplitMesh()); } else if(this.name == "Drone" && other.name == "Virus") { StartCoroutine(SplitMesh()); } } IEnumerator SplitMesh() { MeshFilter MF = GetComponent<MeshFilter>(); MeshRenderer MR = GetComponent<MeshRenderer>(); Mesh M = MF.mesh; Vector3[] verts = M.vertices; Vector3[] normals = M.normals; Vector2[] uvs = M.uv; //Half timeScale to create a minor slow-mo effect Time.timeScale = 0.5f; for (int submesh = 0; submesh < M.subMeshCount; submesh++) { int[] indices = M.GetTriangles(submesh); for (int i = 0; i < indices.Length; i += size) { for (int n = 0; n < 3; n++) { int index = indices[i + n]; newVerts[n] = verts[index]; newUvs[n] = uvs[index]; newNormals[n] = normals[index]; } Mesh mesh = new Mesh(); mesh.vertices = newVerts; mesh.normals = newNormals; mesh.uv = newUvs; mesh.triangles = new int[] { 0, 1, 2, 2, 1, 0 }; GameObject GO = new GameObject("Triangle " + (i / size)); GO.transform.position = transform.position; GO.transform.rotation = transform.rotation; //GO.AddComponent<MeshRenderer>().material = MR.materials[submesh]; GO.AddComponent<MeshRenderer>().materials = MR.materials; GO.AddComponent<MeshFilter>().mesh = mesh; GO.AddComponent<BoxCollider>(); GO.AddComponent<Rigidbody>().AddExplosionForce(100, transform.position, 75); //Comment to use gravity again GO.GetComponent<Rigidbody>().useGravity = false; Destroy(GO, 2 + Random.Range(0.0f, 3.0f)); } } MR.enabled = false; yield return new WaitForSeconds(0.3f); Time.timeScale = 1.0f; Destroy(gameObject); }
}