Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Make rope into a slingshot to launch a sphere
#1
Hello! I'm trying to use the Rope package in order to make a slingshot to launch a sphere. However, it doesn't work. First the rope wasn't bending enough, so I tried fixing it with the stretching scale value in the Obi Rope class, but then the rope was too loose and it didn't "jump back" to launch the sphere.

The sphere movement is implemented with a RigidBody, and it's using the Obi Collider component for the collision detection. I'd appreciate it if you could help fix the rope so it behaves as expected.

These are the components:

Rope Object:
[Image: 1?ui=2&ik=a599c43578&attid=0.1&permmsgid..._kp1ea8ww0]


Sphere:
[Image: 1?ui=2&ik=a599c43578&attid=0.3&permmsgid..._kp1ea8x81]


Slingshot Blueprint:
[Image: 1?ui=2&ik=a599c43578&attid=0.2&permmsgid..._kp1ea8xb2]


Solver:
[Image: 1?ui=2&ik=a599c43578&attid=0.4&permmsgid..._kp1ea8xh3]


This is what it looks like now:

 https://i.gyazo.com/22466f214ef57e70ad0547e74336160b.mp4  
Reply
#2
Hi there,

None of your screenshots show up, so I can only guess.

Quote:First the rope wasn't bending enough, so I tried fixing it with the stretching scale value in the Obi Rope class, but then the rope was too loose and it didn't "jump back" to launch the sphere.

As the name implies, "stretching scale" scales the amount of stretching in the rope. A value of 1 (100%) will allow the rope to stretch/compress normally. Values larger than 1 will force the rope to stretch beyond its rest length (making it longer) and values less than 1 will force the rope to compress below its rest length (making it shorter). This has nothing to do with bending.

If the rope isn't bending enough, adjust its max bending parameter accordingly. See:
http://obi.virtualmethodstudio.com/tutor...aints.html

Quote:The sphere movement is implemented with a RigidBody, and it's using the Obi Collider component for the collision detection.

Mass plays a very important role here, as it determines how the rope and the ball react to each other. If the ball has more mass than the rope, it will be easier for it to push against the rope and stretch it. If the ball is lighter than the rope, the rope will be largely unaffected by the ball (and will behave close to what you have now).

If you want to make the rope more elastic, slightly increase its stretching compliance, and make sure the mass of the ball is comparable to the mass of the rope particles.
Reply
#3
Thank you for your help!
I tried adjusting max bending and increased the mass of the sphere, and it helped!

I also went into the path editing mode and decreased the mass of each point.
Also, I wondered whether if adding more points would help to make the rope more bendy.

I included the images again to this post. Please let me know if you can see them now.

Thanks! 

Rope Object:
   

[b]Sphere:[/b]
   

[b][b]Slingshot Blueprint:[/b][/b]
   

[b][b][b]Solver:[/b][/b][/b]
   
Reply
#4
Can see the images now, thanks!

-Stretching scale should always be set to 1, unless you're after some special or unusual effect. You have it set to 0.24, which means the rope will try to shrink to 24% of its size. This is not what you want in this case.

None of the "distance constraints" parameters affect bending, and none of the "bending constraints" parameters affect distance/stretching. If you want to adjust bending, use the bending constraint parameters.

-Your ObiCollider has a thickness of 0.25 meters. This is a lot, will leave a huge gap between colliders and particles and also negatively affect performance. Use small values close to zero, eg. 0.001. The default is zero.

-You're using 20 substeps. That's way too many, will just burn CPU cycles for no good reason and result in bad performance. Using 2-6 substeps is more than enough in most cases. The default is 4.

Note: I see you're using the Oni backend. When possible, use the Burst backend. It's slightly more performant, and has better platform compatibility. Oni should only be used as fallback.
Reply
#5
(24-05-2021, 08:48 AM)josemendez Wrote: Can see the images now, thanks!

-Stretching scale should always be set to 1, unless you're after some special or unusual effect. You have it set to 0.24, which means the rope will try to shrink to 24% of its size. This is not what you want in this case.

None of the "distance constraints" parameters affect bending, and none of the "bending constraints" parameters affect distance/stretching. If you want to adjust bending, use the bending constraint parameters.

-Your ObiCollider has a thickness of 0.25 meters. This is a lot, will leave a huge gap between colliders and particles and also negatively affect performance. Use small values close to zero, eg. 0.001. The default is zero.

-You're using 20 substeps. That's way too many, will just burn CPU cycles for no good reason and result in bad performance. Using 2-6 substeps is more than enough in most cases. The default is 4.

Note: I see you're using the Oni backend. When possible, use the Burst backend. It's slightly more performant, and has better platform compatibility. Oni should only be used as fallback.
Thanks a lot for your pointers! I changed what you mentioned and it seems to behave a lot better than before.
However, now the rope seems to be a lot more wobbly, which results in the ball not being able to launch off of it, and the rope to go all over the place, especially up and down.
My current Max bending setting is at 0.005, and stretching scale is at 1 as you recommended.

You can see it in this video: https://i.gyazo.com/68734514524df7e36177...30e6a0.mp4

Edit: Another question if I may;
I decided to launch the ball manually, not by the force applied on it by the rope.
So I detect when the ball collides with the rope with the Solver.OnCollision event.
Then I get the position of the ball in the moment of collision, and set it in initialPosition variable.
After that, when the ball is released (mouse button is not held), I get the position of the ball, then turn the two positions into a direction vector via subtracting the two positions.
Then I get the RigidBody of the ball and put the vector's z axis into the velocity to launch it.

However, there were a couple of issues with this:
First, the player is supposed to be able to move the ball while it's touching the rope.
The problem is, while the ball is touching the rope, the initialPosition variable is getting the new ball position, so subtracting it by the ball position is resulting in Vector3.zero because both positions are the same.

Do you know have an idea of I can get a launch direction vector while moving the ball against the rope?
Reply
#6
Bump. Please, does anyone know?
Reply
#7
Quote:I decided to launch the ball manually, not by the force applied on it by the rope.

Imho this is a bad idea, as it disconnects the visuals from the actual outcome of launching. Will look weird at best.

(26-05-2021, 05:24 PM)Brainiac Wrote: Then I get the position of the ball in the moment of collision, and set it in initialPosition variable.

The problem is, while the ball is touching the rope, the initialPosition variable is getting the new ball position, so subtracting it by the ball position is resulting in Vector3.zero because both positions are the same.

Do you know have an idea of I can get a launch direction vector while moving the ball against the rope?

It doesn't make much sense to get the position of the ball when it first touches the rope, imho. The user might be able to move the rope to a completely different position after that, and you'd get a really bad estimate of launch direction/strength.

I'd store the ball position in initialPosition every frame as long as rope and ball are in contact (just like you're currently doing). Then when the user releases the mouse button, wait for a frame and get a second ball position. Then your velocity estimate would be (secondPos-initialPos)/Time.fixedDeltaTime.
Reply
#8
(26-05-2021, 05:54 PM)josemendez Wrote: Imho this is a bad idea, as it disconnects the visuals from the actual outcome of launching. Will look weird at best.


It doesn't make much sense to get the position of the ball when it first touches the rope, imho. The user might be able to move the rope to a completely different position after that, and you'd get a really bad estimate of launch direction/strength.

I'd store the ball position in initialPosition every frame as long as rope and ball are in contact (just like you're currently doing). Then when the user releases the mouse button, wait for a frame and get a second ball position. Then your velocity estimate would be (secondPos-initialPos)/Time.fixedDeltaTime.

Thank you for your response Sonrisa

Quote:Imho this is a bad idea, as it disconnects the visuals from the actual outcome of launching. Will look weird at best.

I do that because the player is supposed to be able to decide the direction the ball will launch in.
The player can rotate the ball on its Y axis, and the force is applied on the ball's forward direction.

Quote:It doesn't make much sense to get the position of the ball when it first touches the rope, imho. The user might be able to move the rope to a completely different position after that, and you'd get a really bad estimate of launch direction/strength.

I'd store the ball position in initialPosition every frame as long as rope and ball are in contact (just like you're currently doing). Then when the user releases the mouse button, wait for a frame and get a second ball position. Then your velocity estimate would be (secondPos-initialPos)/Time.fixedDeltaTime.

I already do pretty much that except the waiting one frame.

Getting initialPosition:
Code:
var world = ObiColliderWorld.GetInstance();

// just iterate over all contacts in the current frame:
foreach (Oni.Contact contact in e.contacts)
{
    // if this one is an actual collision:
    if (contact.distance < 0.01)
    {
        ObiColliderBase col = world.colliderHandles[contact.bodyB].owner;
        if (col != null)
        {
            hookBallPosition = transform.position;
        }
    }
}

On mouse release:
Code:
private void OnMouseUp()
{
    StartCoroutine(Launch());
}

private IEnumerator Launch()
{
    // Wait 1 frame
    yield return null;

    // Get current ball position
    Vector3 secondPosition = transform.position;

    // Get launch vector
    Vector3 direction = hookBallPosition - secondPosition;

    // Launch ball in vector
    rigidBody.velocity = direction / Time.deltaTime;
}

The only issue now is the rope is too loose and stretchy.

It sometimes even gets stuck under the ground and won't come back up.
You can see it in this video: https://i.gyazo.com/68734514524df7e36177...30e6a0.mp4
Reply
#9
Your rope seems to be at maximum resolution, judging from the amount of particles in it. Have you tried reducing resolution a bit (0.25-0.5 should be enough)? That would result in faster simulation that's also less stretchy, since there's less constraints to enforce.
Reply
#10
(27-05-2021, 03:00 PM)josemendez Wrote: Your rope seems to be at maximum resolution, judging from the amount of particles in it. Have you tried reducing resolution a bit (0.25-0.5 should be enough)? That would result in faster simulation that's also less stretchy, since there's less constraints to enforce.

I changed the blueprint's resolution, to -0.3 and the rope is no longer behaving like a jelly.

However, the rope is slipping up and down the sphere which makes it impossible to move the ball when in contact with the rope to position the ball.
That's also why I increased the resolution in the first place.
Reply