(08-12-2022, 10:02 AM)josemendez Wrote: Hi!
The code has some important problems, let's go over them one at a time:
This will cause a large amount of jitter right off the bat. You're moving the object a constant distance every frame, but this is not what you want: you want it to move at a constant speed.
Frames have different duration: sometimes you get 50 frames in a second, sometimes you get 40, sometimes 63, etc... moving the same distance each frame means sometimes you'll move 50 units per second, sometimes 40, sometimes 63, and so on, this will cause the character to jump forward and backward along the rope as you move it. Worse still: on computers that run the game faster, your character will move faster, and on computers that have trouble running the game, the character will move slower.
Since each frame has a different duration, you can calculate the distance you want to move each frame by knowing that velocity = space / time, so space = time * velocity:
Code:currentPositionOnPath += Time.deltaTime * velocity; // velocity units are % of rope per second.
Note this is the basic way to move objects at a constant speed in any software, not just when using Obi/Unity.
This method doesn't find the closest particle in the rope, most of the time, it will return either a random point in the rope or throw an out of bounds exception. The problem is that you're iterating over path frames, getting the index of the closest one, then using its index to get the position of a particle. In general the number of rendered path frames is not the same as the number of particles: there may be less path frames (if the rope is decimated) or more (if the rope is smoothed), so this code might access data outside the particle arrays. Also path frames are not sorted the same way particles are, so if you happen to fall within the solverIndices array it may return a random index.
To get the closest particle in the rope, iterate trough its active particles directly:
Code:for (int i = 0; i < rope.activeParticleCount; ++i)
{
// get position of particle i in world space:
ar pos = pathSmoother.transform.TransformPoint(ropeComp.solver.positions[ropeComp.solverIndices[i]]);
// compare it to the character's position
float distance = Vector3.Distance(m_Character.transform.position, pos);
if (distance < closestIndexDistance)
{
// update closest particle
}
}
With these corrections, movement along the rope is buttery smooth as long as the rope is not decimated (path smoother decimation set to zero). This is important because if your rope is decimated, the number and location of path frames will adaptively change as the rope curvature changes (more frames where curvature is larger, less frames where the rope is straight), so you no longer can use path frames to position the object along the rope. If this is your case, you must use elements instead. Here's how the StickToRope function would look like when using elements:
Code:void StickToRope (float ropePosition)
{
// calculate length along the rope in meters:
var rope = ropeComp as ObiRope;
float length = rope.CalculateLength() * ropePosition;
// iterate trough elements, subtracting the length of each element until we find the one that
// contains the point we are interested in:
for (int i = 0; i < rope.elements.Count; ++i)
{
var pos1 = rope.solver.transform.TransformPoint(rope.solver.positions[rope.elements[i].particle1]);
var pos2 = rope.solver.transform.TransformPoint(rope.solver.positions[rope.elements[i].particle2]);
var elmLength = Vector3.Distance(pos1, pos2);
if (length - elmLength < 0)
{
// found the element we were looking for, just interpolate its ends:
m_Character.transform.position = Vector3.Lerp(pos1, pos2, length / elmLength);
return;
}
length -= elmLength;
}
}
let me know if you need further help,
kind regards
Thanks I've got a lot to learn.
So things that are puzzling,
Code:
var pos = pathSmoother.transform.TransformPoint(ropeComp.solver.positions[ropeComp.solverIndices[i]]);
Seem to still be returning local coordinates.
Code:
Hand pos:(-0.11, 4.48, -3.79)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:135)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:0 position:(0.92, 3.46, 0.14) Magnatued:4.188713
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:0 At pos:(0.92, 3.46, 0.14)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:1 position:(0.96, 3.47, 0.09) Magnatued:4.15387
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:1 At pos:(0.96, 3.47, 0.09)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:2 position:(1.50, 3.23, 0.08) Magnatued:4.370043
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:3 position:(2.04, 3.00, 0.11) Magnatued:4.697079
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:4 position:(2.60, 2.79, 0.21) Magnatued:5.113725
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:5 position:(3.16, 2.66, 0.35) Magnatued:5.57721
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:6 position:(3.72, 2.65, 0.48) Magnatued:6.021061
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:7 position:(4.28, 2.73, 0.58) Magnatued:6.433954
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:8 position:(4.83, 2.91, 0.62) Magnatued:6.808742
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:9 position:(5.37, 3.13, 0.62) Magnatued:7.164061
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:10 position:(5.95, 3.36, 0.56) Magnatued:7.544006
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:11 position:(6.52, 3.61, 0.50) Magnatued:7.948319
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:12 position:(7.08, 3.90, 0.44) Magnatued:8.36546
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:13 position:(7.62, 4.22, 0.38) Magnatued:8.790097
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:14 position:(8.03, 4.57, 0.33) Magnatued:9.118522
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:15 position:(8.39, 4.96, 0.26) Magnatued:9.431477
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:16 position:(8.72, 5.38, 0.18) Magnatued:9.724949
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:17 position:(9.37, 5.73, 0.03) Magnatued:10.29199
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:18 position:(10.01, 5.35, -0.04) Magnatued:10.82423
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
Closest:1 position on path:0.05263158
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:170)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
But The probe / m_Character is in the centre of the rope, and it keeps finding the first particle in the list. Not sure why. Local vs World co-ordinates?
it was a direct copy paste of your code.
but if I use:
Code:
pos = ropeComp.GetParticlePosition(ropeComp.solverIndices[i]);
output is this:
Code:
Hand pos:(-0.11, 4.48, -3.79)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:135)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:0 position:(0.55, 2.91, 0.31) Magnatued:4.433905
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:0 At pos:(0.55, 2.91, 0.31)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:1 position:(0.50, 2.93, 0.27) Magnatued:4.384596
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:1 At pos:(0.50, 2.93, 0.27)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:2 position:(0.30, 2.65, -0.28) Magnatued:3.976799
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:2 At pos:(0.30, 2.65, -0.28)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:3 position:(0.16, 2.36, -0.85) Magnatued:3.629177
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:3 At pos:(0.16, 2.36, -0.85)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:4 position:(0.11, 2.12, -1.46) Magnatued:3.32097
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:4 At pos:(0.11, 2.12, -1.46)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:5 position:(0.13, 1.99, -2.09) Magnatued:3.024831
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:5 At pos:(0.13, 1.99, -2.09)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:6 position:(0.22, 2.01, -2.72) Magnatued:2.714578
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:6 At pos:(0.22, 2.01, -2.72)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:7 position:(0.34, 2.17, -3.31) Magnatued:2.401109
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:7 At pos:(0.34, 2.17, -3.31)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:8 position:(0.46, 2.44, -3.87) Magnatued:2.119863
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:8 At pos:(0.46, 2.44, -3.87)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:9 position:(0.57, 2.77, -4.39) Magnatued:1.930964
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:9 At pos:(0.57, 2.77, -4.39)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:10 position:(0.63, 3.20, -4.93) Magnatued:1.86834
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
current Postion:10 At pos:(0.63, 3.20, -4.93)
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:162)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:11 position:(0.66, 3.61, -5.47) Magnatued:2.038882
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:12 position:(0.66, 4.01, -6.02) Magnatued:2.409439
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:13 position:(0.64, 4.37, -6.60) Magnatued:2.910936
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:14 position:(0.60, 4.60, -7.13) Magnatued:3.417766
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:15 position:(0.56, 4.80, -7.67) Magnatued:3.954642
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:16 position:(0.52, 4.94, -8.24) Magnatued:4.515073
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:17 position:(0.45, 4.78, -8.99) Magnatued:5.239684
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
point:18 position:(0.39, 4.25, -9.62) Magnatued:5.860329
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:152)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
Closest:10 position on path:0.5263158
UnityEngine.Debug:Log (object)
FindClimbObiRope:FindClosestRopeParticle () (at Assets/Scripts/FindClimbObiRope.cs:170)
FindClimbObiRope:LateUpdate () (at Assets/Scripts/FindClimbObiRope.cs:55)
Which looks correct to me. Just wondering if there is some disconnect with my logic or it's a bug or something OSx unity..
Not even sure how to test this. Sorry for being so dumb, working hard to get smarter. Hahaha!