VisualPinball.Engine
VisualPinball.Engine copied to clipboard
Bumpers cannot be controlled by game logic engine
Problem description
The impact of the bumper on the ball is implemented in the BumperCollider class:
internal static class BumperCollider
{
public static void Collide(ref BallState ball, ref NativeQueue<EventData>.ParallelWriter events,
ref CollisionEventData collEvent, ref BumperRingAnimationState ringState, ref BumperSkirtAnimationState skirtState,
in ColliderHeader collHeader, in BumperStaticState state, ref Random random)
{
var dot = math.dot(collEvent.HitNormal, ball.Velocity); // needs to be computed before Collide3DWall()!
var material = collHeader.Material;
BallCollider.Collide3DWall(ref ball, in material, in collEvent, in collEvent.HitNormal, ref random); // reflect ball from wall
if (state.HitEvent && dot <= -state.Threshold) { // if velocity greater than threshold level
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
ball.Velocity += collEvent.HitNormal * state.Force; // add a chunk of velocity to drive ball away
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ringState.IsHit = true;
skirtState.HitEvent = true;
skirtState.BallPosition = ball.Position;
events.Enqueue(new EventData(EventId.HitEventsHit, collHeader.ItemId, ball.Id, true));
}
}
}
The OnCoil function of BumperApi that is called when the game logic engine activates the bumper coil only controls the animation:
void IApiCoil.OnCoil(bool enabled)
{
if (!enabled) {
return;
}
ref var bumperState = ref PhysicsEngine.BumperState(ItemId);
bumperState.RingAnimation.IsHit = true;
}
This is not what a table author would expect given how a real bumper works. Activating the coil is what pushes the ball away, not the impact with the bumper. It also makes it impossible to control the bumper via the game logic engine.