Posts: 7
Threads: 2
Joined: May 2021
Reputation:
0
23-05-2021, 09:12 PM
(This post was last modified: 23-05-2021, 09:13 PM by Brainiac.)
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:
Sphere:
Slingshot Blueprint:
Solver:
This is what it looks like now:
https://i.gyazo.com/22466f214ef57e70ad0547e74336160b.mp4
Posts: 6,347
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
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.
Posts: 7
Threads: 2
Joined: May 2021
Reputation:
0
24-05-2021, 08:35 AM
(This post was last modified: 24-05-2021, 08:35 AM by Brainiac.)
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]
Posts: 6,347
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
24-05-2021, 08:48 AM
(This post was last modified: 24-05-2021, 09:01 AM by josemendez.)
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.
Posts: 7
Threads: 2
Joined: May 2021
Reputation:
0
25-05-2021, 09:24 AM
(This post was last modified: 25-05-2021, 03:54 PM by Brainiac.)
(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?
Posts: 7
Threads: 2
Joined: May 2021
Reputation:
0
Bump. Please, does anyone know?
Posts: 6,347
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
26-05-2021, 05:54 PM
(This post was last modified: 26-05-2021, 05:57 PM by josemendez.)
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.
Posts: 7
Threads: 2
Joined: May 2021
Reputation:
0
27-05-2021, 02:57 PM
(This post was last modified: 27-05-2021, 02:59 PM by Brainiac.)
(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
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
Posts: 6,347
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
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.
Posts: 7
Threads: 2
Joined: May 2021
Reputation:
0
(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.
|