VisualPinball.Engine icon indicating copy to clipboard operation
VisualPinball.Engine copied to clipboard

Bumpers cannot be controlled by game logic engine

Open arthurkehrwald opened this issue 1 year ago • 0 comments

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.

arthurkehrwald avatar Sep 26 '24 17:09 arthurkehrwald