Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Rope not colliding with other ObiColliders

I am facing an issue when I generate a ObiRope in script which is used in RopeNet example (please see attached video)

Everything works fine but the generated rope does not collide with the Ground or anything else which has an ObiCollider. 

Normal rope when created in editor collides as expected with the ground. Is there something I'm missing in the settings? Please help.


public void GenerateRope(Vector3 pointA, Vector3 pointB, ObiCollider start, ObiCollider end)
        // Create a rope
        var ropeObject = new GameObject("solver", typeof(ObiRope), typeof(ObiRopeLineRenderer));
        var rope = ropeObject.GetComponent<ObiRope>();
        var ropeRenderer = ropeObject.GetComponent<ObiRopeLineRenderer>();
        rope.GetComponent<MeshRenderer>().material = material;
        rope.GetComponent<ObiPathSmoother>().decimation = 0.1f;
        ropeRenderer.uvScale = new Vector2(1, 5);

        // Setup a blueprint for the rope:
        var blueprint = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
        blueprint.resolution = blueprintResolution;
        blueprint.thickness = blueprintThickness;
        blueprint.pooledParticles = blueprintPooledParticles;

        // convert both points to the rope's local space:
        pointA = rope.transform.InverseTransformPoint(pointA);
        pointB = rope.transform.InverseTransformPoint(pointB);

        // Procedurally generate the rope path (a simple straight line):
        Vector3 direction = (pointB - pointA) * 0.25f;
        blueprint.path.AddControlPoint(pointA, -direction, direction, Vector3.up, 0.1f, 0.1f, 1, 1, Color.white, "A");
        blueprint.path.AddControlPoint(pointB, -direction, direction, Vector3.up, 0.1f, 0.1f, 1, 1, Color.white, "B");

        rope.ropeBlueprint = blueprint;

        rope.transform.parent = solver.transform;

        PinRope(rope, start, end, new Vector3(0, 0.5f, 0), -new Vector3(0, 0.5f, 0));

    private void PinRope(ObiRope rope, ObiCollider bodyA, ObiCollider bodyB, Vector3 offsetA, Vector3 offsetB)
        // Pin both ends of the rope (this enables two-way interaction between character and rope):
        var pinConstraints = rope.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
        var batch = new ObiPinConstraintsBatch();
        batch.AddConstraint(rope.solverIndices[0], bodyA, offsetA, Quaternion.identity, 0, 999, float.PositiveInfinity);
        batch.AddConstraint(rope.solverIndices[rope.activeParticleCount - 1], bodyB, offsetB, Quaternion.identity, 0, 999, float.PositiveInfinity);
        batch.activeConstraintCount = 2;
You need to setup collision filter masks in both the rope and each of your colliders. By default (when creating Obi actors from script), they're all set to zero so nothing colliders.

ObiUtils has a static MakeFilter function for that. Let's say you want your ropes to be in category 0 and your colliders in category 1, then you'd do this:
obiRope.filter = ObiUtils.MakeFilter((1 << 0) | (1 << 1), 0); // put rope in category 0 and make it collide with categories 0 (ropes) and 1 (colliders)
obiCollider.filter = ObiUtils.MakeFilter(1 << 0, 1); // put collider in category 1 and make it collide with category 0 (ropes)

This really seems to be missing in the docs, I had to dig through Obi's code myself to find this. It should be added here:
Also, note that the term "filter" seems to be new. The online version of the API is still at version 6.0 and there it's still called "phases" or so, that also needs updating for sure.
Thanks a lot that worked perfectly  Sonrisa
(08-01-2022, 01:15 PM)pdinklag Wrote: This really seems to be missing in the docs, I had to dig through Obi's code myself to find this. It should be added here:

Thanks for the feedback!

It's explained in the particle scripting page, however the only explanation given is:

Integer value used for collision filtering. Less significat 16 bits contain a collision category (from 0 to 15) and most significant 16 bits contain a collision mask. See collisions.

Which is a bit lackluster indeed. While you could build a filter yourself using bitwise operators with this info, no mention of the helper stuff (MakeFilter(), CollideWithEverything, & co) was made. I've just added a section at the end of the scripting collisions page that explains these in greater detail and provides some examples.

Also linked to it from the scripting actors page, so that it's easier to find when you're looking for info on creating ropes at runtime. Let me know if you have any input about this! Sonrisa