How to make a moving platform without an animation player?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By bolotie

I’ve been working on a mechanic where there is a platform that rises/falls depending on how much weight is on it. It starts with a upward velocity but, as things land on it and it accumulates weight, it starts to slow down and eventually starts going downwards. I’m currently using a KinematicBody2D for it and using MoveAndSlide. The player is using MoveAndSlideWithSnap to land on the platform and stay on; or at least that’s how I think it should be working. In practice, the platform stops moving altogether whenever the player makes contact with it. The collision is also extremely jittery frame to frame: going on and off repeatedly. I experimented with a RigidBody2D and was having the same jittery issues but it retained its upwards velocity. Is there some better way to go about this? I’ve linked a gif and my relevant code.

Gif of issue

Platform:

public override void _PhysicsProcess(float delta)
{
    _WeightLabel.Text = _Weight.ToString();

    
    MoveAndSlide(_Velocity, Vector2.Up);

    CalculateWeight();
    CalculateVelocity();
}

private void CalculateWeight() 
{

    HashSet<WeightedObject> encounteredColliders = new HashSet<WeightedObject>();
    HashSet<WeightedObject> unencounteredColliders = new HashSet<WeightedObject>();

    for (int i = 0; i < GetSlideCount(); i++) 
    {
        KinematicCollision2D collision = GetSlideCollision(i);
        Godot.Object collider = collision.Collider;

        MoveAndSlide(collision.Remainder);

        if (collider is WeightedObject) 
        {
            WeightedObject weightedCollider = (WeightedObject)collider;

            // collision has been detected for this frame
            encounteredColliders.Add(weightedCollider);

            // only add weight if the collision didn't previously exist
            if (!_Colliders.Contains(weightedCollider)) 
            {
                _Weight += (weightedCollider).Weight;
                _Colliders.Add(weightedCollider);
            }

            if (collider is Player) 
            {
                ((KinematicBody2D)collider).MoveAndSlide(collision.Remainder);
            }
        }
    }

    foreach (WeightedObject collider in _Colliders)
    {
        // if collision no longer exists subtract the weight from the platform
        if (!encounteredColliders.Contains(collider)) 
        {
            _Weight -= collider.Weight;
            unencounteredColliders.Add(collider);
        }
    }

    // remove collisions that no longer exist from colliders
    _Colliders.ExceptWith(unencounteredColliders);
}

private void CalculateVelocity() 
{
    _Velocity.y = -15f + _Weight;
}

Player:

public override void _Ready()
{
    base._Ready();

    Weight = 10;
    JumpForce = 100;
    MaxSpeed = 100;
    Gravity = 5;
    MaxFallSpeed = 200;
    Friction = 10;
    Acceleration = 10;
}