Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Obi Rope How To Get Any Position From Rope
#1
Hi,
I have an object like cube and I want to cube follow the rope in real time. The rope is stretching, sagging etc. but cube should be follow given point in rope every time.
[Image: ndqt5li.png]

An example code to explain what I think:

Code:
float length = obiRope.CalculateLength();
Vector3 targetPosition = obiRope.GetPositionFromFloat(length / 2);
cube.transform.position = targetPosition;

I hope I could explain.
Reply
#2
Hi!

You can use the path’s GetSectionAt() method. This thread will help:
http://obi.virtualmethodstudio.com/forum...-3243.html
Reply
#3
Hi,
thank you for your answer. This is actually what I want. But obi gives me an error when I use this line.

[Image: nzw49lw.PNG]

Code:
Code:
private IEnumerator FlowEffect()
    {
        ObiPathSmoother pathSmoother = obiRope.GetComponent<ObiPathSmoother>();
        float mu = 0;
        while(mu < obiRope.CalculateLength())
        {
            mu += 0.01f;
            ObiPathFrame pos = pathSmoother.GetSectionAt(mu); // This line gives error. Even when mu = 0
            rastgeleBirKup.localPosition = pos.position;
            yield return new WaitForSeconds(0.005f);
        }
        StartCoroutine(FlowEffect());
    }
Reply
#4
(17-01-2022, 01:07 AM)NorkQ Wrote: Hi,
thank you for your answer. This is actually what I want. But obi gives me an error when I use this line.

[Image: nzw49lw.PNG]

Code:
Code:
private IEnumerator FlowEffect()
    {
        ObiPathSmoother pathSmoother = obiRope.GetComponent<ObiPathSmoother>();
        float mu = 0;
        while(mu < obiRope.CalculateLength())
        {
            mu += 0.01f;
            ObiPathFrame pos = pathSmoother.GetSectionAt(mu); // This line gives error. Even when mu = 0
            rastgeleBirKup.localPosition = pos.position;
            yield return new WaitForSeconds(0.005f);
        }
        StartCoroutine(FlowEffect());
    }

Hi there,

I'm unable to reproduce this. The input mu is clamped between 0 and 1, so any mu value should work fine.
-Which Obi version are you using? (asking before there was a bug in this method, fixed in 6.3)
- Are you doing any extra rope processing? (particle reordering, constraint reordering, element-based processing?)

kind regards,
Reply
#5
(17-01-2022, 08:15 AM)josemendez Wrote: Hi there,

I'm unable to reproduce this. The input mu is clamped between 0 and 1, so any mu value should work fine.
-Which Obi version are you using? (asking before there was a bug in this method, fixed in 6.3)
- Are you doing any extra rope processing? (particle reordering, constraint reordering, element-based processing?)

kind regards,

I am using Version 6.3 November 24, 2021.
I am not doing extra processing. I just using these components:

[Image: bcf449l.png]
Reply
#6
Still unable to reproduce it, only thing I can think of is that you're calling this method when the rope is not even initialized yet (such as the Awake() or Start() of a separate object, called by Unity before the rope's).

If that is the case, simplest workaround is to just wait for the first frame to end before calling this coroutine. For instance:

Code:
IEnumerator Start()
    {
        yield return new WaitForEndOfFrame();
        StartCoroutine(FlowEffect());
    }

On a side note, your code has a problem:
Code:
while (mu < obiRope.CalculateLength())

mu is a normalized coordinate, that ranges from 0 (start of the rope) to 1(end of the rope). Comparing it against the rope length (which is expressed in meters) doesn't make much sense. If you want to sweep the entire rope, use while(mu < 1).

Sample component that fixes both issues:

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

public class Test : MonoBehaviour
{

    public ObiRope obiRope;
    public Transform rastgeleBirKup;

    IEnumerator Start()
    {
        yield return new WaitForEndOfFrame();
        StartCoroutine(FlowEffect());
    }

    private IEnumerator FlowEffect()
    {
       
        ObiPathSmoother pathSmoother = obiRope.GetComponent<ObiPathSmoother>();
        float mu = 0;
        while (mu < 1)
        {
            mu += 0.01f;
            ObiPathFrame pos = pathSmoother.GetSectionAt(mu);
            rastgeleBirKup.localPosition = pos.position;
            yield return new WaitForSeconds(0.005f);
        }
        StartCoroutine(FlowEffect());
    }
}
Reply
#7
(17-01-2022, 08:28 PM)josemendez Wrote: Still unable to reproduce it, only thing I can think of is that you're calling this method when the rope is not even initialized yet (such as the Awake() or Start() of a separate object, called by Unity before the rope's).

If that is the case, simplest workaround is to just wait for the first frame to end before calling this coroutine. For instance:

Code:
IEnumerator Start()
    {
        yield return new WaitForEndOfFrame();
        StartCoroutine(FlowEffect());
    }

On a side note, your code has a problem:
Code:
while (mu < obiRope.CalculateLength())

mu is a normalized coordinate, that ranges from 0 (start of the rope) to 1(end of the rope). Comparing it against the rope length (which is expressed in meters) doesn't make much sense. If you want to sweep the entire rope, use while(mu < 1).

Sample component that fixes both issues:

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

public class Test : MonoBehaviour
{

    public ObiRope obiRope;
    public Transform rastgeleBirKup;

    IEnumerator Start()
    {
        yield return new WaitForEndOfFrame();
        StartCoroutine(FlowEffect());
    }

    private IEnumerator FlowEffect()
    {
       
        ObiPathSmoother pathSmoother = obiRope.GetComponent<ObiPathSmoother>();
        float mu = 0;
        while (mu < 1)
        {
            mu += 0.01f;
            ObiPathFrame pos = pathSmoother.GetSectionAt(mu);
            rastgeleBirKup.localPosition = pos.position;
            yield return new WaitForSeconds(0.005f);
        }
        StartCoroutine(FlowEffect());
    }
}

This is true. I added yield return new WaitForEndOfFrame(); and problem solved. Thank u very much !
Reply