Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  RuntimeRopeGenerator basic questions
#1
Hi! 

I had to upgrade Obi Rope from version 3 to 7 because I bought Obi SoftBody as well, and unfortunately, they don't work on separate versions. 

I’m not quite familiar with this version yet. 

How can I generate a ropes that always has the same length? 
Currently, it generates the rope based on the distance between the Start and End points, but I don’t want that. I tried using "controlPoints.Add(Vector3.down * ropeLength);" like in the old version but it's does not work anymore. 

Code:
public Transform startp;
public Transform endp;

public Material material;

private ObiRope rope;
public ObiSolver solver;
public ObiRopeBlueprint ropeBlueprint;
private ObiRopeCursor cursor;

public void createropeline()

  {

      solver = GameObject.Find("Obi Solver").GetComponent<ObiSolver>();    
      GameObject ropeObject = new GameObject("ObiRope");
      ropeObject.transform.SetParent(solver.transform);   
      rope = ropeObject.AddComponent<ObiRope>();

      var pinConstraints = rope.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
      pinConstraints.Clear();
     
      var ropeRenderer = ropeObject.AddComponent<ObiRopeLineRenderer>();
      ropeRenderer.uvScale = new Vector2(1, 5);
      ropeRenderer.material = material;

     
      rope.bendConstraintsEnabled = false;
      rope.stretchingScale = 0.5f;
      rope.aerodynamicsEnabled = false;

     
      int filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything, 0);


      ropeBlueprint.path.Clear();
      ropeBlueprint.path.AddControlPoint(startp.position, Vector3.zero, Vector3.zero, Vector3.zero, 0.05f, 0.05f, 0.3f, filter, Color.white, "Start");
      ropeBlueprint.path.AddControlPoint(endp.position, Vector3.zero, Vector3.zero, Vector3.zero, 0.05f, 0.05f, 0.3f, filter, Color.white, "End");
      ropeBlueprint.path.FlushEvents();

     
      rope.ropeBlueprint = ropeBlueprint;
     
    
      AttachRopeEnds();

     
  }
  public void AttachRopeEnds()
  {
      if (rope == null || ropeBlueprint == null)
          return;

      var attachmentA = rope.gameObject.AddComponent<ObiParticleAttachment>();
      attachmentA.target = startp;
      attachmentA.particleGroup = ropeBlueprint.groups[0];
      attachmentA.attachmentType = ObiParticleAttachment.AttachmentType.Dynamic;

      var attachmentB = rope.gameObject.AddComponent<ObiParticleAttachment>();
      attachmentB.target = endp;
      attachmentB.particleGroup = ropeBlueprint.groups[ropeBlueprint.groups.Count - 1];
      attachmentB.attachmentType = ObiParticleAttachment.AttachmentType.Dynamic;

   
     
  }

If i switch startp.position, endp.position to Vector3.zero, Vector3.one Then nothing happens when i create the rope.

This is the script I’m currently using, and it works well, but compared to the ExtendableGrapplingHook.cs, it seems quite incomplete.
Could it cause any issues that I’m not using a Coroutine or that "var batch = new ObiPinConstraintsBatch();" section?

Or could it be that the missing parts are exactly why my rope isn't generating properly when I use Vector3.zero, Vector3.one instead of my Transforms?

I know my questions are very basic but i didn't find a normal "Runtime Rope Generator" example.   Indeciso

Thank you in advance. Sonrisa
Reply
#2
Dedo arriba 
In the meantime, the solution has been found, here’s the script in case someone else needs it.  Tímido

In this script, the distance between the objects doesn't matter — the rope will always have a fixed length.

Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Obi;


public class FixedLenghtRope : MonoBehaviour
{
    public ObiSolver solver;
    public ObiCollider character;
    public ObiCollider fixedHookTarget;

    public Material material;
    public ObiRopeSection section;

   

    public float RopeLenght;
    public float Streched;
    public float hookResolution = 0.5f;
   
    public int particlePoolSize = 100;

    private ObiRope rope;
    private ObiRopeBlueprint blueprint;
    private ObiRopeLineRenderer ropeRenderer;

   

   
    private bool attached = false;
    public float fixedRopeLength = 5f;

    void Awake()
    {
       
    }

    private void OnDestroy()
    {
        DestroyImmediate(blueprint);
    }

   
   
    private void LaunchHook()
    {
       
        GameObject ropeObject = new GameObject("ObiRope");
        ropeObject.transform.SetParent(solver.transform);
        rope = ropeObject.AddComponent<ObiRope>();
        ropeRenderer = rope.gameObject.AddComponent<ObiRopeLineRenderer>();

        ropeRenderer.uvScale = new Vector2(1, 4);
        ropeRenderer.normalizeV = false;
        ropeRenderer.uvAnchor = 1;
        ropeRenderer.material = material;

        // Setup a blueprint for the rope:
        blueprint = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
        blueprint.resolution = 0.5f;
        blueprint.pooledParticles = particlePoolSize;

        // Tweak rope parameters:
        rope.maxBending = 0.02f;

       
        StartCoroutine(AttachHook());
       
    }

   

    private IEnumerator AttachHook()
    {
        yield return null;

        // Clear pin constraints:
        var pinConstraints = rope.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
        pinConstraints.Clear();

       

        Vector3 targetPosition = fixedHookTarget.transform.position;
        Vector3 localTargetPosition = rope.transform.InverseTransformPoint(targetPosition);

        // Procedurally generate the rope path (a straight line with fixed length):
        int filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything, 0);
        blueprint.path.Clear();
        blueprint.path.AddControlPoint(Vector3.zero, Vector3.zero, Vector3.zero, Vector3.up, 0.1f, 0.1f, 1, filter, Color.white, "Hook start");
        blueprint.path.AddControlPoint(localTargetPosition.normalized * fixedRopeLength, Vector3.zero, Vector3.zero, Vector3.up, 0.1f, 0.1f, 1, filter, Color.white, "Hook end");
        blueprint.path.FlushEvents();

        // Generate the particle representation of the rope (wait until it has finished):
        yield return blueprint.Generate();

        // Set the blueprint (this adds particles/constraints to the solver and starts simulating them).
        rope.ropeBlueprint = blueprint;
     
        // wait for the solver to load the rope, after the next physics step:
        yield return new WaitForFixedUpdate();
        yield return null;

        // Pin both ends of the rope:
        var batch = new ObiPinConstraintsBatch();
        batch.AddConstraint(rope.elements[0].particle1, character, transform.localPosition, Quaternion.identity, 0, 0, float.PositiveInfinity);
        batch.AddConstraint(rope.elements[rope.elements.Count - 1].particle2, fixedHookTarget,
                            fixedHookTarget.transform.InverseTransformPoint(fixedHookTarget.transform.position), Quaternion.identity, 0, 0, float.PositiveInfinity);
        batch.activeConstraintCount = 2;
        pinConstraints.AddBatch(batch);

        rope.SetConstraintsDirty(Oni.ConstraintType.Pin);
        attached = true;
    }

    private void DetachHook()
    {
        // Set the rope blueprint to null (automatically removes the previous blueprint from the solver, if any).
        Destroy(rope.gameObject);
        // rope.GetComponent<ObiRopeLineRenderer>().enabled = false;
        attached = false;
    }


    void Update()
    {
        if (attached == true)
        {
            RopeLenght = rope.CalculateLength();
            Streched = rope.CalculateLength() / rope.restLength;
        }
       
        if (Input.GetMouseButtonDown(0))
        {
           
                LaunchHook();
           
        }
        if (Input.GetMouseButtonDown(1))
        {

            DetachHook();

        }

    }
}
Reply