Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Obi Rope Pipe Water Flow Effect
#1
Hi,
I am using Obi Rope as a pipe object. In my game, the water is flowing in the pipe and I want to make a flow effect with Obi Rope.
How can I do this ?
Here is an image about this:

[Image: 1ndpc5f.png]
Reply
#2
Hi,

You can change individual particle radii using the particle API:
http://obi.virtualmethodstudio.com/manua...icles.html

Do this using a sine wave, and displace the sine wave along the rope to get the bumps moving. Like this:

Code:
// accumulate time on a member variable:
time += Time.deltaTime * speed;

for (int i = 0; i < rope.solverIndices.Length; ++i)
{
     int solverIndex = rope.solverIndices[i]:
     rope.principalRadii[solverIndex] = Vector3.one * (baseThickness + Mathf.Max(0,Mathf.Sin(i + time)*bumpThickness));
}

Should be pretty easy to do.

let me know if you need help!
Reply
#3
(27-01-2022, 11:21 AM)josemendez Wrote: Hi,

You can change individual particle radii using the particle API:
http://obi.virtualmethodstudio.com/manua...icles.html

Do this using a sine wave, and displace the sine wave along the rope to get the bumps moving. Like this:

Code:
// accumulate time on a member variable:
time += Time.deltaTime * speed;

for (int i = 0; i < rope.solverIndices.Length; ++i)
{
     int solverIndex = rope.solverIndices[i]:
     rope.principalRadii[solverIndex] = Vector3.one * (baseThickness + Mathf.Max(0,Mathf.Sin(i + time)*bumpThickness));
}

Should be pretty easy to do.

let me know if you need help!

Hi, thank you so much josemendez this is working !
But there are some problems here I guess. When the rope streching, 
swelling is streching also. Here is the video of problem:

Reply
#4
(27-01-2022, 01:40 PM)NorkQ Wrote: Hi, thank you so much josemendez this is working !
But there are some problems here I guess. When the rope streching, 
swelling is streching also. Here is the video of problem:


You can make the sine wave relative to rope length, instead of relative to particle index. This way when particles separate due to stretching, the bulge won't stretch with them.

Simply accumulate the distance from one particle to the next, and use that instead of "i" in "Mathf.Sin(i + time)".

cheers,
Reply
#5
(27-01-2022, 01:44 PM)josemendez Wrote: You can make the sine wave relative to rope length, instead of relative to particle index. This way when particles separate due to stretching, the bulge won't stretch with them.

Simply accumulate the distance from one particle to the next, and use that instead of "i" in "Mathf.Sin(i + time)".

cheers,

Actually I didn't understand what do you mean exactly. I tried the code below and it didn't work.


Code:
float distance = Vector3.Distance(obiRope.GetParticlePosition(solverIndex), obiRope.GetParticlePosition(solverIndex - 1));
solver.principalRadii[solverIndex] = Vector3.one * (baseThickness + Mathf.Max(0, Mathf.Sin(distance + time) * bumpThickness));
Reply
#6
(27-01-2022, 02:08 PM)NorkQ Wrote: Actually I didn't understand what do you mean exactly. I tried the code below and it didn't work.


Code:
float distance = Vector3.Distance(obiRope.GetParticlePosition(solverIndex), obiRope.GetParticlePosition(solverIndex - 1));
solver.principalRadii[solverIndex] = Vector3.one * (baseThickness + Mathf.Max(0, Mathf.Sin(distance + time) * bumpThickness));

You need to accumulate distance as you go, not just grab the distance between the current particle and the previous one. Otherwise the sine value will be basically the same for every particle, instead of varying along the rope.

Like this:

Code:
float distance = 0;

        for (int i = 0; i < rope.solverIndices.Length; ++i)
        {
            int solverIndex = rope.solverIndices[i];

            if (i > 0)
            {
                int previousIndex = rope.solverIndices[i - 1];
                distance += Vector3.Distance(rope.solver.positions[solverIndex],rope.solver.positions[previousIndex]);
            }

            rope.solver.principalRadii[solverIndex] = Vector3.one * (baseThickness + Mathf.Max(0, Mathf.Sin(distance * bulgeScale + time) * bulgeThickness));
        }

I threw a "bulgeScale" multiplier in there, so that you can control the width of the bulges.
Reply
#7
(27-01-2022, 02:19 PM)josemendez Wrote: You need to accumulate distance as you go, not just grab the distance between the current particle and the previous one. Otherwise the sine value will be basically the same for every particle, instead of varying along the rope.

Like this:

Code:
float distance = 0;

        for (int i = 0; i < rope.solverIndices.Length; ++i)
        {
            int solverIndex = rope.solverIndices[i];

            if (i > 0)
            {
                int previousIndex = rope.solverIndices[i - 1];
                distance += Vector3.Distance(rope.solver.positions[solverIndex],rope.solver.positions[previousIndex]);
            }

            rope.solver.principalRadii[solverIndex] = Vector3.one * (baseThickness + Mathf.Max(0, Mathf.Sin(distance * bulgeScale + time) * bulgeThickness));
        }

I threw a "bulgeScale" multiplier in there, so that you can control the width of the bulges.

Yep, this is working properly. But for those who will see this post later, I would like to point out you should increase particle count to get better results.
Reply