/// <summary>
    /// Creates a straight rope anchored to a transform at the top.
    /// Transform may or may not move around and may or may not have a rigidbody.
    /// When you call this the rope will appear in the scene and immediately interact with gravity and objects with ObiColliders.
    /// Called from anywhere (main thread only)
    /// </summary>
    public IEnumerator MakeRope(Transform anchoredTo, Vector3 attachmentOffset, float ropeLength)
    {
        // create a new GameObject with the required components: a solver, a rope, and a curve.
        // we also throw a cursor in to be able to change its length.
        GameObject ropeObject = new GameObject("rope", typeof(ObiSolver),
                                               typeof(ObiRope),
                                               typeof(ObiCatmullRomCurve),
                                               typeof(ObiRopeCursor));

        // get references to all components:
        rope   = ropeObject.GetComponent <ObiRope>();
        cursor = ropeObject.GetComponent <ObiRopeCursor>();
        solver = ropeObject.GetComponent <ObiSolver>();
        ObiCatmullRomCurve path = ropeObject.GetComponent <ObiCatmullRomCurve>();

        // set up component references (see ObiRopeHelper.cs)
        rope.Solver   = solver;
        rope.ropePath = path;
        rope.section  = Resources.Load <ObiRopeSection>("DefaultRopeSection");

        // set path control points (duplicate end points, to set curvature as required by CatmullRom splines):
        path.controlPoints.Clear();
        path.controlPoints.Add(Vector3.zero);
        path.controlPoints.Add(Vector3.zero);
        path.controlPoints.Add(Vector3.down * ropeLength);
        path.controlPoints.Add(Vector3.down * ropeLength);

        rope.pooledParticles = 2000;

        // parent the rope to the anchor transform:
        rope.transform.SetParent(anchoredTo, false);
        rope.transform.localPosition = attachmentOffset;

        // generate particles/constraints and add them to the solver (see ObiRopeHelper.cs)
        yield return(rope.StartCoroutine(rope.GeneratePhysicRepresentationForMesh()));

        rope.AddToSolver(null);

        // get the last particle in the rope at its rest state.
        pinnedParticle = rope.UsedParticles - 1;

        // add a tethers batch:
        ObiTetherConstraintBatch tetherBatch = new ObiTetherConstraintBatch(true, false, 0, 1);

        rope.TetherConstraints.AddBatch(tetherBatch);
        //UpdateTethers();

        // fix first particle in place (see http://obi.virtualmethodstudio.com/tutorials/scriptingparticles.html)
        rope.invMasses[0] = 0;
        Oni.SetParticleInverseMasses(solver.OniSolver, new float[] { 0 }, 1, rope.particleIndices[0]);
    }
Пример #2
0
    private void UpdateTethers()
    {
        rope.TetherConstraints.RemoveFromSolver(null);
        ObiTetherConstraintBatch batch = (ObiTetherConstraintBatch)rope.TetherConstraints.GetFirstBatch();

        batch.Clear();

        ObiDistanceConstraintBatch dbatch = rope.DistanceConstraints.GetFirstBatch();

        for (int i = 0; i < dbatch.ConstraintCount; ++i)
        {
            batch.AddConstraint(0, dbatch.springIndices[i * 2 + 1], rope.InterparticleDistance * i, 1, 1);
        }

        batch.Cook();
        rope.TetherConstraints.AddToSolver(null);
    }