public static GameObject Cut(GameObject _originalGameObject, Vector3 _contactPoint, Vector3 _direction, Material _cutMaterial = null, bool fill = true, bool _addRigigibody = false) { if (currentlyCutting) { return(null); } currentlyCutting = true; // set the cutter relative to victim Plane plane = new Plane(_originalGameObject.transform.InverseTransformDirection(-_direction), _originalGameObject.transform.InverseTransformPoint(_contactPoint)); //get the victims mesh originalMesh = _originalGameObject.GetComponent <MeshFilter>() ? _originalGameObject.GetComponent <MeshFilter>().mesh : _originalGameObject.GetComponent <SkinnedMeshRenderer>().sharedMesh; //List for added vertices List <Vector3> addedVertices = new List <Vector3>(); //Create two new meshes GeneratedMesh leftMesh = new GeneratedMesh(); GeneratedMesh rightMesh = new GeneratedMesh(); int[] submeshIndices; int triangleIndexA, triangleIndexB, triangleIndexC; for (int i = 0; i < originalMesh.subMeshCount; i++) { //Fetches the triangle list for the specified sub-mesh on the victim submeshIndices = originalMesh.GetTriangles(i); for (int j = 0; j < submeshIndices.Length; j += 3) { triangleIndexA = submeshIndices[j]; triangleIndexB = submeshIndices[j + 1]; triangleIndexC = submeshIndices[j + 2]; MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i); // Get vertices sides bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]); bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]); bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]); if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide)// left side { leftMesh.AddTriangle(currentTriangle); } else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide)// right side { rightMesh.AddTriangle(currentTriangle); } else // Cut the triangle { CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices); } } } // Get Materials to apply to the new objects Material[] mats; if (_originalGameObject.GetComponent <MeshRenderer>()) { mats = _originalGameObject.GetComponent <MeshRenderer>().sharedMaterials; } else { mats = _originalGameObject.GetComponent <SkinnedMeshRenderer>().sharedMaterials; } // if there is a material to fill the cut add it to materials list if (_cutMaterial) { if (mats[mats.Length - 1].name != _cutMaterial.name) { Material[] newmats = new Material[mats.Length + 1]; mats.CopyTo(newmats, 0); newmats[mats.Length] = _cutMaterial; mats = newmats; } } int submeshCount = mats.Length - 1; if (fill) { // fill the opennings FillCut(addedVertices, plane, leftMesh, rightMesh, submeshCount); } //// Left Mesh Mesh left_HalfMesh = leftMesh.GetMesh(); left_HalfMesh.name = "Split Mesh Left"; //// Right Mesh Mesh right_HalfMesh = rightMesh.GetMesh(); right_HalfMesh.name = "Split Mesh Right"; //// assign the game objects if (_originalGameObject.GetComponent <MeshFilter>()) { _originalGameObject.GetComponent <MeshFilter>().mesh = left_HalfMesh; } else { _originalGameObject.GetComponent <SkinnedMeshRenderer>().sharedMesh = left_HalfMesh; } GameObject leftSideObj = _originalGameObject; GameObject rightSideObj = null; if (_originalGameObject.GetComponent <MeshRenderer>()) { rightSideObj = new GameObject("right side", typeof(MeshFilter), typeof(MeshRenderer)); rightSideObj.transform.position = _originalGameObject.transform.position; rightSideObj.transform.rotation = _originalGameObject.transform.rotation; rightSideObj.GetComponent <MeshFilter>().mesh = right_HalfMesh; } else if (_originalGameObject.GetComponent <SkinnedMeshRenderer>()) { rightSideObj = new GameObject("right side"); SkinnedMeshRenderer skinMesh = rightSideObj.AddComponent <SkinnedMeshRenderer>(); rightSideObj.transform.position = _originalGameObject.transform.position; rightSideObj.transform.rotation = _originalGameObject.transform.rotation; skinMesh.sharedMesh = right_HalfMesh; } if (_originalGameObject.transform.parent != null) { rightSideObj.transform.parent = _originalGameObject.transform.parent; } rightSideObj.transform.localScale = _originalGameObject.transform.localScale; //Add rigibody to the new object if (_addRigigibody) { var rigibody = rightSideObj.AddComponent <Rigidbody>(); rigibody = _originalGameObject.GetComponent <Rigidbody>(); } // assign materials if (_originalGameObject.GetComponent <MeshRenderer>()) { leftSideObj.GetComponent <MeshRenderer>().materials = mats; rightSideObj.GetComponent <MeshRenderer>().materials = mats; } else if (_originalGameObject.GetComponent <SkinnedMeshRenderer>()) { leftSideObj.GetComponent <SkinnedMeshRenderer>().materials = mats; rightSideObj.GetComponent <SkinnedMeshRenderer>().materials = mats; } return(rightSideObj); }