private IEnumerator CheckIfStillInsideMesh(CanBeChopped comp, Collider sharpArea, Collider other) { yield return(new WaitForSeconds(canChopRef.intersectionCheckCooldown)); if (!sharpArea.bounds.Intersects(other.bounds)) { comp.BeginSlice(transform.position, transform.up); if (comp.spawnFluid) { canChopRef.fluidEmitterRef.transform.position = other.transform.position; _obiParticleRenderer.particleColor = comp.spawnFluidColor; StartCoroutine(FluidSpawn()); } } }
private void OnTriggerExit(Collider other) { CanBeChopped comp = other.gameObject.GetComponent <CanBeChopped>(); if (CheckConditions(other, comp)) { //Kinda hack. If knife is not at a state that it can slice the object(e.g, hand is holding it on reverse, or player is trying to cut object with non - sharp area), do not cut the object. Vector3 meshCenter = other.GetComponent <Renderer>().bounds.center; // Get mesh's center position in world coordinates if (Vector3.Distance(sharpAreaRef.transform.position, meshCenter) < Vector3.Distance(nonSharpAreaRef.transform.position, meshCenter)) { return; } //Check if knife is still intersecting with victim mesh after a cooldown. Then, slice the mesh if conditions are met. StartCoroutine(CheckIfStillInsideMesh(comp, GetComponent <Collider>(), other)); } }
private bool CheckConditions(Collider other, CanBeChopped comp) { return(comp && canChopRef.IsToolAvailable() && comp.ChopAvailability()); }
public virtual IEnumerator Cut() { // Jump to main thread for running UNITY API calls yield return(Ninja.JumpToUnity); // set the blade relative to victim _blade = new Plane(gameObject.transform.InverseTransformDirection(-_normalDirection), gameObject.transform.InverseTransformPoint(_anchorPoint)); // get the victims mesh _victim_mesh = gameObject.GetComponent <MeshFilter>().mesh; Vector3[] victim_vertices = _victim_mesh.vertices; Vector3[] victim_normals = _victim_mesh.normals; Vector2[] victim_uvs = _victim_mesh.uv; Vector4[] victim_tangents = _victim_mesh.tangents; int subMeshCount = _victim_mesh.subMeshCount; // Jump back to background thread to do heavy processes. yield return(Ninja.JumpBack); // reset values _new_vertices.Clear(); _leftSide = new Mesh_Maker(); _rightSide = new Mesh_Maker(); bool[] sides = new bool[3]; int[] indices; int p1, p2, p3; // go throught the submeshes for (int sub = 0; sub < subMeshCount; sub++) { yield return(Ninja.JumpToUnity); indices = _victim_mesh.GetTriangles(sub); yield return(Ninja.JumpBack); for (int i = 0; i < indices.Length; i += 3) { p1 = indices[i]; p2 = indices[i + 1]; p3 = indices[i + 2]; sides[0] = _blade.GetSide(victim_vertices[p1]); sides[1] = _blade.GetSide(victim_vertices[p2]); sides[2] = _blade.GetSide(victim_vertices[p3]); // whole triangle if (sides[0] == sides[1] && sides[0] == sides[2]) { if (sides[0]) { // left side _leftSide.AddTriangle( new Vector3[] { victim_vertices[p1], victim_vertices[p2], victim_vertices[p3] }, new Vector3[] { victim_normals[p1], victim_normals[p2], victim_normals[p3] }, new Vector2[] { victim_uvs[p1], victim_uvs[p2], victim_uvs[p3] }, new Vector4[] { victim_tangents[p1], victim_tangents[p2], victim_tangents[p3] }, sub); } else { _rightSide.AddTriangle( new Vector3[] { victim_vertices[p1], victim_vertices[p2], victim_vertices[p3] }, new Vector3[] { victim_normals[p1], victim_normals[p2], victim_normals[p3] }, new Vector2[] { victim_uvs[p1], victim_uvs[p2], victim_uvs[p3] }, new Vector4[] { victim_tangents[p1], victim_tangents[p2], victim_tangents[p3] }, sub); } } else { // cut the triangle Cut_this_Face( new Vector3[] { victim_vertices[p1], victim_vertices[p2], victim_vertices[p3] }, new Vector3[] { victim_normals[p1], victim_normals[p2], victim_normals[p3] }, new Vector2[] { victim_uvs[p1], victim_uvs[p2], victim_uvs[p3] }, new Vector4[] { victim_tangents[p1], victim_tangents[p2], victim_tangents[p3] }, sub); } } } ///////////////////// Jump to main thread for running UNITY API calls yield return(Ninja.JumpToUnity); // The capping Material will be at the end Material[] mats = gameObject.GetComponent <MeshRenderer>().sharedMaterials; if (mats[mats.Length - 1].name != capMaterial.name) { Material[] newMats = new Material[mats.Length + 1]; mats.CopyTo(newMats, 0); newMats[mats.Length] = capMaterial; mats = newMats; } _capMatSub = mats.Length - 1; // for later use yield return(Ninja.JumpBack); // cap the opennings Capping(); yield return(Ninja.JumpToUnity); // Left Mesh Mesh left_HalfMesh = _leftSide.GetMesh(); left_HalfMesh.name = "Split Mesh Left"; // Right Mesh Mesh right_HalfMesh = _rightSide.GetMesh(); right_HalfMesh.name = "Split Mesh Right"; // assign the game objects gameObject.name = "left_side"; gameObject.GetComponent <MeshFilter>().mesh = left_HalfMesh; GameObject leftSideObj = gameObject; // Clone left side's components to right side. GameObject rightSideObj = GameObject.Instantiate(leftSideObj); rightSideObj.transform.position = gameObject.transform.position; rightSideObj.transform.rotation = gameObject.transform.rotation; rightSideObj.GetComponent <MeshFilter>().mesh = right_HalfMesh; rightSideObj.name = "right_side"; if (gameObject.transform.parent != null) { rightSideObj.transform.parent = gameObject.transform.parent; } rightSideObj.transform.localScale = gameObject.transform.localScale; // Check for fried object material assign if (GetComponent <FoodStatus>().GetIsFried()) { mats[0] = GetComponent <CanBeFried>().friedMaterial; } // // assign mats leftSideObj.GetComponent <MeshRenderer>().materials = mats; rightSideObj.GetComponent <MeshRenderer>().materials = mats; // Handle new colliders of left & right pieces HandleCollisions(leftSideObj); HandleCollisions(rightSideObj); CanBeChopped cbc = rightSideObj.GetComponent <CanBeChopped>(); cbc.SetRootObject(_rootObject); // Update maximum chopping action counts this.maximumChopCount -= 1; cbc.maximumChopCount = this.maximumChopCount; foreach (CanBeChopped child in this.transform.parent.GetComponentsInChildren <CanBeChopped>()) { child.maximumChopCount = this.maximumChopCount; } // Finally, mark them as chopped pieces leftSideObj.GetComponent <FoodStatus>().SetIsChoppedPiece(true); SimulationController sc = GameObject.Find("Simulation Controller").GetComponent <SimulationController>(); rightSideObj.GetComponent <FoodStatus>().OperationDone += sc.OnOperationDone; rightSideObj.GetComponent <FoodStatus>().SetIsChoppedPiece(true); /////////////////// // End thread yield return(Ninja.JumpBack); yield break; }