08-09-2023, 01:03 PM
I'm working on a 2.5D game with rope swinging/climbing. I've tried a few different approaches to dealing with the climbing, but haven't gotten anything that QUITE works. So far my implementation is:
For climbing, it gets trickier. The best version I've found is:
https://youtu.be/_TBW25ytktI
Any tips on avoiding this? I tried looking into the following two approaches, but I couldn't find a way to make them work:
1) Move the player independently of the obi rope and then somehow find the closest appropriate particle to attach and move it to the attach point.
OR
2) After attaching, move the player down further if necessary to reach what would be the resting length of the rope at that point. Is there a way to find out how far the attached particle is from the top of the rope?
And in general, do you have any tips on best practices for getting a solid climbing setup? Does my implementation seem reasonable, or will I run into issues in the future that I might not have anticipated? (For example, I don't have climbing animations set up yet, and I could imagine that this could introduce some future headaches that I haven't seen coming...)
The main code used for moving the player is:
- The actual game mechanics are the character swinging on a hinge joint that's independent of the obi rope. The obi rope is just used for visuals and collision detection, not the swinging rope movement.
- When you jump on to a rope, a new particle group is created and attached to the character's hand when the collision box hits
For climbing, it gets trickier. The best version I've found is:
- When you climb up and down, each "step" attaches to the next particle up/down
- Your attachment to the hinge joint is then re-established based on your new location
https://youtu.be/_TBW25ytktI
Any tips on avoiding this? I tried looking into the following two approaches, but I couldn't find a way to make them work:
1) Move the player independently of the obi rope and then somehow find the closest appropriate particle to attach and move it to the attach point.
OR
2) After attaching, move the player down further if necessary to reach what would be the resting length of the rope at that point. Is there a way to find out how far the attached particle is from the top of the rope?
And in general, do you have any tips on best practices for getting a solid climbing setup? Does my implementation seem reasonable, or will I run into issues in the future that I might not have anticipated? (For example, I don't have climbing animations set up yet, and I could imagine that this could introduce some future headaches that I haven't seen coming...)
The main code used for moving the player is:
Code:
public void AttachNewParticleIndex(int indexChangeAmount)
{
// Get the new particle index that you're climbing towards
int newParticleIndex = GetParticleNeighborIndex(indexChangeAmount);
// Get new position to move to
Vector3 newPos = solver.positions[newParticleIndex];
newPos += transform.position; // Adds the rope's position because the position of the particle is relative to the rope
newPos -= attachedRopeChar.attachTransform.localPosition; // newPos offsets the char's position so that the attach point is aligned with the rope particle
// Detatch char from old position and move towards new one
Destroy(attachment);
Vector3 newCharRotation = new Vector3(0, attachedRopeChar.transform.rotation.eulerAngles.y, attachedRopeChar.transform.rotation.eulerAngles.z);
attachedRopeChar.transform.rotation = Quaternion.Euler(newCharRotation); // reset char rotation
attachedRopeChar.transform.Translate(newPos - attachedRopeChar.transform.position, Space.World); // Move char to the new particle pos
// Create new attachment
attachment = obiRope.gameObject.AddComponent<ObiParticleAttachment>();
attachment.target = attachedRopeChar.attachTransform;
// Create a new particle group and assign it the particle that you are moving to
var group = ScriptableObject.CreateInstance<ObiParticleGroup>();
group.particleIndices.Add(newParticleIndex); // index of the particle in the actor
attachment.particleGroup = group;
}