I have a problem regarding moving platforms and making the player follow along with them. I want the player (linkedRbs[i] in this case) to basically ‘stick’ to the object and maintain its relative position on the object as it moves - this works in a sense, the problem comes when setting the position of the RigidBody, the relative position gets inverted (diagram below for reference). If the player is relatively at the front of the object, the next physics update it will move the the back, then to the front, vice versa. I really can not find a way to fix this and keep it in the same relative position without the back forward motion - any help? It seems like a simple error that I’ve glossed over on my end but I’ve been trying to fix this for hours.
I move my rigidbodys with the moving platform as follows:
List<Rigidbody> linkedRbs = new List<Rigidbody>();
List<Vector3> linkedRbsRelativePos = new List<Vector3>();
private void FixedUpdate()
{
for (int i = 0; i < linkedRbs.Count; i++) // "linkedRbs" are the rbs touching the moving object
{
if (GetRelativePos(linkedRbs[i]) != linkedRbsRelativePos[i]) // RB is not in the same place as it was the last physics update
{
Vector3 lastRBPos = linkedRbsRelativePos[i];
linkedRbsRelativePos[i] = GetRelativePos(linkedRbs[i]);
Vector3 worldRelativePos = transform.position - linkedRbsRelativePos[i];
Vector3 newPos = lastRBPos + worldRelativePos;
//Debug.Log($"Dir={worldRelativePos},lastPos={lastRBPos},newerPos={newer}");
linkedRbs[i].MovePosition(new Vector3(newPos.x, linkedRbs[i].position.y, newPos.z));
}
}
}
private Vector3 GetRelativePos(Rigidbody rb)
{
Vector3 playerRelative = rb.transform.InverseTransformPoint(transform.position);
return playerRelative;
}
private void OnCollisionEnter(Collision collision)
{
Collider collider = collision.collider;
if(collider.TryGetComponent<PlayerColliderReference>(out PlayerColliderReference pcr))
{
Rigidbody _rb = pcr.GetComponentInParent<Rigidbody>();
linkedRbs.Add(_rb);
linkedRbsRelativePos.Add(GetRelativePos(_rb));
}
}
private void OnCollisionExit(Collision collision)
{
Collider collider = collision.collider;
if (collider.TryGetComponent<PlayerColliderReference>(out PlayerColliderReference pcr))
{
Rigidbody _rb = pcr.GetComponentInParent<Rigidbody>();
for (int i = 0; i < linkedRbs.Count; i++)
{
if (linkedRbs[i] == _rb)
{
linkedRbs.Remove(linkedRbs[i]);
linkedRbsRelativePos.Remove(linkedRbsRelativePos[i]);
}
}
}
}
Simply inverting the relativePos values obviously sends me somewhere far away, inverting the relativePos values in relative space also doesn't fix the issue since the relative position still gets inverted every physics update just the other way around.
Not sure if I understood your question correctly, but if you just want a player to move along with a platform, than you can add the amount by which the position of the platform changed to the position of the player (or the linkedRbs). In that case you don't need to mess with weird relative positions. Here's some example code that should work:
public List<Rigidbody> linkedRbs = new List<Rigidbody>();
Vector3 lastPosition;
private void Start()
{
lastPosition = transform.position;
}
private void FixedUpdate()
{
if (lastPosition != transform.position)
{
Vector3 changeInPosition = transform.position - lastPosition;
changeInPosition.y = 0;
for (int i = 0; i < linkedRbs.Count; i++)
{
linkedRbs[i].position += changeInPosition;
}
lastPosition = transform.position;
}
} // plus all of your collision code
In my testing that code did what I thought your code was supposed to do.