Player shaking on moving platform

I made a moving platform that has a dynamic rigidbody2D, a platform effector 2D and that becomes the player´s parent once it steps on it. The platform moves vertically from one point to another usinga lever, and I have encountered many bugs with it.

  1. My player continously bounces when the platform is moving, going from having a parent to having no parent constantly.
  2. When my platform Rigidbody2D is set to kinematic, the bounciness just gets stronger.
  3. When the platform is set to dynamic, it also becomes slightly heavier when my player steps on it.
  4. In some instances my platform just starts shaking constantly once it has reached its destiny and the player is no longer on it.

This is my code in the lever:

 void Update()
    {
        if (canWork)
        {
            if (Input.GetKeyDown(KeyCode.E))
            {
                isOn = !isOn;
            }
        }

        if(isOn)
        {
            if(obj.transform.position != endPos)
            {
                obj.GetComponent<Rigidbody2D>().MovePosition(Vector3.MoveTowards(obj.transform.position, endPos, objSpd * Time.deltaTime));
            } else
            {
                obj.transform.position = endPos;
            }
        }
        else
        {
            if (obj.transform.position != initPos)
            {
                obj.GetComponent<Rigidbody2D>().MovePosition(Vector3.MoveTowards(obj.transform.position, initPos, objSpd * Time.deltaTime));
            }
            else
            {
                obj.transform.position = initPos;
            }
        }
    }

This is my code in the platform:

 private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.layer == LayerMask.NameToLayer("Player"))
        {
            if (collision.gameObject.GetComponent<PlayerControls>().isGrounded)
            {
                collision.transform.SetParent(transform);
            }
        }
    }

    private void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.gameObject.layer == LayerMask.NameToLayer("Player"))
        {
            collision.gameObject.transform.SetParent(null);
        }
    }

This is my code in the player:

void Update()
    {
        //Movimiento
        if (!isCrouching)
        {
            rb.velocity = new Vector2(Input.GetAxisRaw("Horizontal") * spd, rb.velocity.y);
            anim.SetFloat("speed", Mathf.Abs(rb.velocity.x));
            rb.drag = 0;
        } else
        {
            if (Input.GetAxisRaw("Horizontal") != 0)
            {
                rb.drag = crouchFriction;
            }
            else
            {
                rb.drag = 0;
                rb.velocity = new Vector2(0, rb.velocity.y);
            }
        }

        //Flip
        Flip();

        //GroundCheck
        GroundCheck();

        //Saltar
        if (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W))
        {
            if (!isCrouching)
            {
                jumpBuffCount = jumpBuffTime;
            }
        } else
        {
            jumpBuffCount -= Time.deltaTime;
        }

        if (jumpBuffCount > 0)
        { 
            if (coyoteTimeCount > 0)
            {
                rb.velocity = new Vector2(rb.velocity.x, jumpForce);
                jumpBuffCount = 0;
            }
        }

        if ((Input.GetKeyUp(KeyCode.UpArrow) || Input.GetKeyUp(KeyCode.W)) && isGrounded)
        {
            coyoteTimeCount = 0;
        }

        if (!isGrounded)
        {
            if (transform.parent == null || transform.parent != null && !transform.parent.CompareTag("FallingPlatform"))
            {
                if (rb.velocity.y > 0.1f)
                {
                    anim.SetBool("isJumping", true);
                    anim.SetBool("isFalling", false);
                }
                else
                {
                    anim.SetBool("isJumping", false);
                    anim.SetBool("isFalling", true);
                }
            }
        } else
        {
            anim.SetBool("isJumping", false);
            anim.SetBool("isFalling", false);
        }

        //Agacharse
        Crouch();

        anim.SetBool("isCrouching", isCrouching);
    }

    private void GroundCheck()
    {
        //Collider2D hit = Physics2D.OverlapCircle(new Vector2(transform.position.x, transform.position.y - 0.3f), 0.4f, colision);
        Collider2D hit = Physics2D.OverlapBox(new Vector2(transform.position.x, transform.position.y - 0.5f), new Vector2(0.96f, 0.1f), 0, colision);
        isGrounded = hit;

        if (isGrounded)
        {
            coyoteTimeCount = coyoteTime;
        }
        else
        {
            coyoteTimeCount -= Time.deltaTime;
        }
    }

Ive tried multiple solutions, including adding a physics material 2D without friction nor bounciness, manually changing the player position through code rather than using parent (although that just resulted in even more bounciness),
or moving the platform through its transform. Anyone knows how can I fix this? let me know if you need any pictures or more code, thanks.

Rigidbody objects (at least dynamic) ignore parent relationships, just so you know. :wink:

Common issue. Sounds like a one-frame-off sync issue. What you want is to ensure that:

  1. platform transform updates
  2. player(s) transform updates

Not vice versa because then players would sync to the previous frame’s position of the platform. Most obvious when on an upward moving platform the player seemingly sinks into the platform floor.

Naturally. Although many of us wish our scale platforms wouldn’t do that. :grin:

Sounds like it’s trying to keep moving but something is holding it in place. Could also be a one-frame-off thing.

You’re moving a physics object, thus you should only move it within FixedUpdate. However, Input must remain in Update otherwise you’d miss some keypresses. FixedUpdate runs at 50 Hz by default, Update more often.

The player’s Rigidbody is set to Kinematic? Otherwise you shouldn’t directly manipulate velocity but rather use AddForce et al. Directly setting velocity bypasses the physics simulation.