Пример #1
0
    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());
            }
        }
    }
Пример #2
0
    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));
        }
    }
Пример #3
0
 private bool CheckConditions(Collider other, CanBeChopped comp)
 {
     return(comp && canChopRef.IsToolAvailable() && comp.ChopAvailability());
 }
Пример #4
0
    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;
    }