Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Rope "drag" and PullDataFromSolver
#1
Hi!

I'm using Obi for a 3D grappling hook function (similar to you 2D example, but in 3D).

I have tweaked the values for the weight of my player rigidbody, for the rope and for the ObiSolver a lot, and I'm beginning to be pretty happy with the result. I still have one big problem:

If my player comes with some speed and shoots the rope in front of her, she still has some speed forward. This means she moves a bit while the rope is generated (whic takes around 3 frames on my computer). This I've tried to compensate for by creating a proportionally smaller rope. Also the rope is generated still (i.e. with no velocity), while she is in movement. The result is that the rope, when it appears, is formning a backward bend, behind her, and starts to slow her down from some kind of drag.

I first guessed this drag was because of some constraints, so I minimized bend constraint and increased "slack" to maximum. This made the rope a bit more "ugly", because it bent too much, but still no huge improvement. So I thought perhaps the player had too little mass to drag the rope. I increased the mass from 1 to 10, and it helped a bit, but instead the rope acted more elastic. Also, I want other objects to be much heavier than the player, so I don't like to have her too heavy. I changed that back, and came up with the idea, that perhaps I just need to set the particles start speed to the same as the player from the beginning! This way, they shouldn't drag behind her and slow her down.

The problem is that this seems to cause som unpredicted results. For one, the whole rope seemed to get a little bit crazy (but perhaps this is something I can tweak). But the other problem is that the fixed particle which keeps the far end of the rope in place, starts moving too. I read on this forum that this may be because even a particle with inverse mass 0 will move, if you set its velocity to some value. So I tried to exclude this particle, by getting the mass of all particles and avoid giving velocity to the one with inverseMass > 0.

Strangely, if I Debug.Log () all the particle masses I don't get any one with a different mass. They all have mass 10.


Code:
float[] masses = new float[1];
masses[0] = 0;
Oni.SetParticleInverseMasses (rope.Solver.OniSolver, masses, 1, rope.particleIndices[rope.UsedParticles - 1]);
// The above part works in game!

rope.TetherConstraints.RemoveFromSolver (null);
rope.GenerateTethers (ObiActor.TetherType.AnchorToFixed);
rope.TetherConstraints.AddToSolver (null);
// The above part, I'm not sure if it works. Sometimes the rope does not seem to be thethered. Is it correct? I can't see tethers in the editor.

// Set start velocity of particles:
Vector3 velocity = GetCurrentVelocity ();

yield return 0; // I added this row, just in case the SetParticleInverseMasses needs a frame to take effect.

rope.PullDataFromSolver(ParticleData.VELOCITIES | ParticleData.INV_MASSES);

if (rope.isActiveAndEnabled && rope.InSolver)

for (int i = 0; i < rope.velocities.Length; i++) // (I noticed you use ++i - why? Does that not increment before running the first loop?)
  {
  if (rope.invMasses[i] > 0.01)
   rope.velocities[i] = velocity;
   Debug.Log ("Particle " + i + " has mass " + rope.invMasses[i]);
  }
rope.PushDataToSolver(ParticleData.VELOCITIES);
}


For a short rope, with just 3 particles, this gives the result:

Code:
Particle 0 has mass 10
Particle 1 has mass 10
Particle 2 has mass 10
Particle 3 has mass 10
Particle 4 has mass 10
Particle 5 has mass 10
Particle 6 has mass 10
Particle 7 has mass 10
Particle 8 has mass 10
Particle 9 has mass 10
Particle 10 has mass 10
Particle 11 has mass 10
Particle 12 has mass 10

I guess the 10 extra particles are the pooled ones, not in use at the moment? But why is there no one with another mass?

As you see in my code, I even tried adding a "yield return 0", just in case it takes a frame for the fixed particles mass-change to take effect.

The fixed particle does work as expected and is completely still in the game, so the player can hang from it. If I visualize it in the editor (during paused game), however, it says it has a mass of 0.1.

I can't get my head around this! Do you have any idea?

Perhaps another solution would be to lower the mass of all particles to 0,01? But I do think giving them a start speed would work best, and be most realistic. Perhaps a start speed which varies gradually from the players speed in the player-end and 0 in the stuck end. Or do you have another idea for how to prevent this?

Cheers,
Rasmus
Reply
#2
Hi!

I managed to work around it, so no need to read the long post above! The only thing I still don't get is why

rope.PullDataFromSolver(ParticleData.VELOCITIES | ParticleData.INV_MASSES);

Gives the same mass for every particle, even though I set the inverse mass to 0 of the end particle of the rope above

Oni.SetParticleInverseMasses (rope.Solver.OniSolver, masses, 1, rope.particleIndices[rope.UsedParticles - 1]);

If you can explain that, it's great, but my game works as intended anyway now, since I worked around it.
Reply