Delay in add platform velocity to player velocity causes it to slowly slide off

This moving platform script is for moving a platform with a player on it in mind. So that the player moves with platform and can freely move on it without trouble. That works because in the player script the velocity of the platform gets added to the velocity of the player. The platform is based on velocity movement because i had to get the velocity of the platform to make it work with the player.
Here below is a video of what is happening:

The problem
The problem is that everytime the platform switches direction the velocity of the platform changes in the opposite direction and the player should adjust with that in sync. But it does not. Rather, it goes a little to the right or left because the velocity change has a delay ( I assume that that is the problem, but could be something else) . I’ve tried multiple things, asigning the transform of the player to the transform of the collision while changing direction, does not work. Also making the player a child of the platform while changing direction, does not work. (I could have implemented them wrong but im not sure). I’ve added dampening to the movement of the platform but that does not work either, only minimizes it. That’s why I ask for help for how to fix this. Here’s a video below to show it.
PlayerPlatform

Movingplatform

 using System.Collections;
using System.Collections.Generic;
using TarodevController;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class WaypointFollower : MonoBehaviour
{


    public Transform posA, posB;
    public float speed;
    Vector3 targetPos;
    private Vector3 velocity;
    public float smoothTime;
    PlayerController PlayerController;
    Rigidbody2D rb;
    Vector3 moveDirection;
    Rigidbody2D playerRb;
    //bool PlayerOnPlatform;
    //Transform PlayerCollision;
    //Transform Player;
   //GameObject PLAYER;
    //bool direction;
    private void Awake()
    {
        PlayerController = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerController>();
        rb = GetComponent<Rigidbody2D>();
        playerRb = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>();
        //Player = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
    }

    private void Start()
    {
        targetPos = posB.position;
        DirectionCalculate();

    }

    

    private void Update()
    {
        if (Vector2.Distance(transform.position, posA.position) < 0.1f)
        {
            targetPos = posB.position;
           
            DirectionCalculate();
       
        }
        if (Vector2.Distance(transform.position, posB.position) < 0.1f )
        {
            targetPos = posA.position;
            
            DirectionCalculate();
            
        }
        
        

    }
    private void FixedUpdate()
    {
        Vector3 targetVelocity = moveDirection * speed;
        rb.velocity = Vector3.SmoothDamp(rb.velocity, targetVelocity, ref velocity, smoothTime);

    }

    void DirectionCalculate()
    {
        moveDirection = (targetPos - transform.position).normalized;

    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            PlayerController.isOnPlatform = true;
            //PlayerOnPlatform = true;
            PlayerController.platformRb = rb;
            playerRb.gravityScale = 0;
            //PLAYER = collision.gameObject;
        }
    }

    private void OnTriggerStay2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            //PlayerCollision = collision.transform;
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            //PlayerOnPlatform = false;
            PlayerController.isOnPlatform = false;
            playerRb.gravityScale = 0;
        }
    }
}

PLAYERCONTROLLER

using System;
using System.Runtime.InteropServices;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using static UnityEngine.Networking.UnityWebRequest;

namespace TarodevController
{
  
    [RequireComponent(typeof(Rigidbody2D), typeof(Collider2D))]
    public class PlayerController : MonoBehaviour, IPlayerController
    {
        [SerializeField] private ScriptableStats _stats;
        private Rigidbody2D _rb;
        private CapsuleCollider2D _col;
        private FrameInput _frameInput;
        private Vector2 _frameVelocity;
        private bool _cachedQueryStartInColliders;

        private bool _ceilingHit;
        private bool _isSliding;
        private bool _CannotFlip;
        public bool isOnPlatform;
        public Rigidbody2D platformRb;


        private bool _canSlide;
        private SpriteRenderer flip;
        
        private float _slideVelocity;


        #region Interface

        public Vector2 FrameInput => _frameInput.Move;
        public event Action<bool, float> GroundedChanged;
        public event Action Jumped;
        public event Action <bool> Slided;
        public event Action<bool> Crouched;

        #endregion

        private float _time;

        private void Awake()
        {
            _CrouchSpeed = _stats.MaxSpeed;
            _rb = GetComponent<Rigidbody2D>();
            _col = GetComponent<CapsuleCollider2D>();

            _cachedQueryStartInColliders = Physics2D.queriesStartInColliders;
            _canSlide = true;
            _isSliding = false;
            flip = gameObject.GetComponent<SpriteRenderer>();



        }
     

        private void Update()
        {
            _time += Time.deltaTime;
            GatherInput();
            
        }

        private void GatherInput()
        {
            _frameInput = new FrameInput
            {
                JumpDown = Input.GetButtonDown("Jump") || Input.GetKeyDown(KeyCode.C),
                JumpHeld = Input.GetButton("Jump") || Input.GetKey(KeyCode.C),
                Move = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"))
            };

            if (_stats.SnapInput)
            {
                _frameInput.Move.x = Mathf.Abs(_frameInput.Move.x) < _stats.HorizontalDeadZoneThreshold ? 0 : Mathf.Sign(_frameInput.Move.x);
                _frameInput.Move.y = Mathf.Abs(_frameInput.Move.y) < _stats.VerticalDeadZoneThreshold ? 0 : Mathf.Sign(_frameInput.Move.y);
            }

            if (_frameInput.JumpDown)
            {
                _jumpToConsume = true;
                _timeJumpWasPressed = _time;
            }
        }

        private void FixedUpdate()
        {
            CheckCollisions();
            HandleJump();
            HandleDirection();
            HandleCrouch();
            HandleSlide();
            ApplyMovement();    
            HandleGravity();
            HandleFlip();
            
            
        }


    private void HandleFlip() 
        {
            if (_frameVelocity.x < 0)
            {
                
            flip.flipX = true;
           
            }
            
            else if (_frameVelocity.x > 0)
            {
                
            flip.flipX = false;
           
            }
        }

private void HandleCrouch()
{
    if (_isSliding)
    {
        // If sliding, do nothing
        return;
    }

    if ((_grounded && ceilingHitCheck()) || (_frameInput.Move.y < 0 && _grounded))
    {
                Crouched?.Invoke(true);
                _CrouchSpeed = _stats.MaxSpeed / 2;
                GetComponent<CapsuleCollider2D>().size = new Vector2(0.47f, 0.95f);
                GetComponent<CapsuleCollider2D>().offset = new Vector2(-0.09f, -0.52f);

            }
    else if (!_ceilingHit) // Add this condition to check if not currently hitting the ceiling
    {
                
                _CrouchSpeed = _stats.MaxSpeed;
                GetComponent<CapsuleCollider2D>().offset = new Vector2(-0.09f, -0.05f);
                GetComponent<CapsuleCollider2D>().size = new Vector2(0.47f, 1.9f);
                Crouched?.Invoke(false);
            }
}


private void HandleSlide()
{
    // Check if the player is grounded, moving horizontally past a certain speed, holding down 's', and allowed to slide
    if (_grounded && Input.GetAxisRaw("Vertical") < 0 && Mathf.Abs(_frameVelocity.x) >= _stats.StartSlideSpeed && _canSlide)
    {

        GetComponent<CapsuleCollider2D>().size = new Vector2(0.47f, 0.95f);
        GetComponent<CapsuleCollider2D>().offset = new Vector2(-0.09f, -0.52f);
        // Set sliding to true
        _isSliding = true;

        // Set canSlide to false
        _canSlide = false;

        // Preserve the current horizontal velocity (this will be your initial slide velocity)
        _slideVelocity = _frameVelocity.x;

        _CrouchSpeed = _stats.MaxSpeed / 2;

        Slided?.Invoke(true);
        }

    // Check if the slide button is released or the player stops holding down 's'
    if (Input.GetAxisRaw("Vertical") >= 0 && _canSlide == false)
    {
        // Set sliding to false
        _isSliding = false;

        // Set canSlide to true
        _canSlide = true;
                Slided?.Invoke(false);

            }

    if (_isSliding && _canSlide == false)
    {
        
        // Gradually decrease the slide velocity using a slide deceleration factor
        _slideVelocity = Mathf.MoveTowards(_slideVelocity, 0, _stats.SlideDeceleration * Time.fixedDeltaTime);

        // Assign the slide velocity to the frame velocity's x component
        _frameVelocity.x = _slideVelocity;

        // If the slide velocity reaches zero, stop sliding
        
        
        if ((Math.Abs(_slideVelocity) <= _CrouchSpeed) && (_stats.MinSlideSpeedIsCrouch) && _canSlide == false)
        {
            _isSliding = false;
              Slided?.Invoke(false);
                }

        else if ((Math.Abs(_slideVelocity) <= _stats.MinSlideSpeed) && (!_stats.MinSlideSpeedIsCrouch) && _canSlide == false)
        {
            _isSliding = false;
            Slided?.Invoke(false);
                }
    }
}
        


        bool ceilingHitCheck()
        {
            RaycastHit2D[] results = new RaycastHit2D[10];
            int numHits = Physics2D.CapsuleCastNonAlloc(_col.bounds.center, _col.size, _col.direction, 0, Vector2.up, results, _stats.CeilingDistance, ~_stats.PlayerLayer);

            bool hit = false;
            foreach (var result in results)
            {
                if (result.collider != null && !result.collider.isTrigger)
                {
                    hit = true;
                    break;
                }
            }

            return hit;
        }

        #region Collisions
        
        private float _frameLeftGrounded = float.MinValue;
        private bool _grounded;
        
        

        private void CheckCollisions()
        {

            
            Physics2D.queriesStartInColliders = false;

            // Ground and Ceiling
            bool groundHit = Physics2D.CapsuleCast(_col.bounds.center, _col.size, _col.direction, 0, Vector2.down, _stats.GrounderDistance, ~_stats.PlayerLayer);
            bool ceilingHit = ceilingHitCheck();
            Debug.Log($"Ground Hit: {groundHit}, Ceiling Hit: {ceilingHit}");
            // Hit a Ceiling
            if (ceilingHit)
            { 
                _frameVelocity.y = Mathf.Min(0, _frameVelocity.y);
            
            } 
            // Landed on the Ground
            if (!_grounded && groundHit)
            {
                _grounded = true;
                _coyoteUsable = true;
                _bufferedJumpUsable = true;
                _endedJumpEarly = false;
                GroundedChanged?.Invoke(true, Mathf.Abs(_frameVelocity.y));
            }
            // Left the Ground
            else if (_grounded && !groundHit)
            {
                _grounded = false;
                _frameLeftGrounded = _time;
                GroundedChanged?.Invoke(false, 0);
            }

            Physics2D.queriesStartInColliders = _cachedQueryStartInColliders;
        }

        #endregion


        #region Jumping

        private bool _jumpToConsume;
        private bool _bufferedJumpUsable;
        private bool _endedJumpEarly;
        private bool _coyoteUsable;
        private float _timeJumpWasPressed;

        private float _CrouchSpeed;

        private bool HasBufferedJump => _bufferedJumpUsable && _time < _timeJumpWasPressed + _stats.JumpBuffer;
        private bool CanUseCoyote => _coyoteUsable && !_grounded && _time < _frameLeftGrounded + _stats.CoyoteTime;

        private void HandleJump()
        {
            if (!_endedJumpEarly && !_grounded && !_frameInput.JumpHeld && _rb.velocity.y > 0) _endedJumpEarly = true;

            if (!_jumpToConsume && !HasBufferedJump) return;

            if (_grounded || CanUseCoyote) ExecuteJump();

            _jumpToConsume = false;
        }

        private void ExecuteJump()
        {
            _endedJumpEarly = false;
            _timeJumpWasPressed = 0;
            _bufferedJumpUsable = false;
            _coyoteUsable = false;
            _frameVelocity.y = _stats.JumpPower;
            Jumped?.Invoke();
        }

        #endregion

        #region Horizontal

        private void HandleDirection()
{
    if (!_isSliding)
    {
        if (_frameInput.Move.x == 0)
        {
            var deceleration = _grounded ? _stats.GroundDeceleration : _stats.AirDeceleration;
            _frameVelocity.x = Mathf.MoveTowards(_frameVelocity.x, 0, deceleration * Time.fixedDeltaTime);
        }
        else
        {
            _frameVelocity.x = Mathf.MoveTowards(_frameVelocity.x, _frameInput.Move.x * _CrouchSpeed, _stats.Acceleration * Time.fixedDeltaTime);
        }
    }
    else if (_isSliding && _slideVelocity == 0 && Input.GetAxisRaw("Vertical") < 0)
    {
        // If the slide has ended and the player is still holding down 's', transition to crouching
        
        HandleCrouch();
    }
}




        #endregion

        #region Gravity

        private void HandleGravity()
        {
            if (_grounded && _frameVelocity.y <= 0f)
            {
                _frameVelocity.y = _stats.GroundingForce;
            }
            else
            {
                var inAirGravity = _stats.FallAcceleration;
                if (_endedJumpEarly && _frameVelocity.y > 0) inAirGravity *= _stats.JumpEndEarlyGravityModifier;
                _frameVelocity.y = Mathf.MoveTowards(_frameVelocity.y, -_stats.MaxFallSpeed, inAirGravity * Time.fixedDeltaTime);
            }
        }

        #endregion





        private void ApplyMovement()
        {
           
            if (isOnPlatform)
            {
                _rb.velocity = new Vector2(Mathf.Clamp((_frameVelocity.x + (platformRb.velocity.x + (platformRb.velocity.x * 0.02f ))), -_stats.MaxSpeed, _stats.MaxSpeed), _frameVelocity.y);
                
            }
            else
            {
                _rb.velocity = new Vector2(_frameVelocity.x, _frameVelocity.y);
            }
        }
#if UNITY_EDITOR
        private void OnValidate()
        {
            if (_stats == null) Debug.LogWarning("Please assign a ScriptableStats asset to the Player Controller's Stats slot", this);
        }
#endif
    }   
  
    public struct FrameInput
    {
        public bool JumpDown;
        public bool JumpHeld;
        public Vector2 Move;
    }

    public interface IPlayerController
    {
        public event Action<bool, float> GroundedChanged;

        public event Action Jumped;

        public event Action<bool> Crouched;

        public event Action<bool> Slided;
        public Vector2 FrameInput { get; }
    }
}

Hello @TRIS_TANK, it seem to me like the issue is with the method you are moving the object with. For example: You are moving it with velocity, so when the platform changes direction, the player still has a little velocity in the other direction.
To fix this there are a few things you could try.

Firstly you could try adding a bit more force to the player when the platform changes direction, to overcome the velocity of the player in the other direction.

Another option is to comment out all the code you use to move the player with the platform, and instead make it to where when the player lands on the platform it is parented to the platform, and when it not touching the platform, that it is no longer parented to the platform.
In theory both should work. Let me know how it goes.
Also, one last thing, try not to delete any of your current code until we find a working solution. Just in case.

Hi @Waterstudios11 and thanks for your reply.
The first solution you gave could probably be implemented, but it seems more like a temporary solution, because when the platform goes faster the added force should also be larger. It does not seem like this would be the permanent solution to this problem.

And for the second thing. Adding the player as a child to the platform so that it moves with it, works. But, the reason that I changed it to velocity based in the first place, is because the player movement stutters when using parenting. It does not work properly and thats why i tried to only use parenting when the platform gets close to the place it will change direction so you can move 90% properly of the time. But this seems not to be working for some reason and the player is not affected by parenting while running the game.

I would love to come to any other solutions with you, but these seem not it. Let me know what you think.