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;
}