Framework/TableCamera.cs

A Component that drives the local camera to sit behind the local player's seat or show an overview when not seated. It queries a TableAnchor and CardGame from the scene, computes a target camera transform (including optional game-specific camera height), and smoothly interpolates the component's world position and rotation each update.

using System;
using System.Linq;

namespace CardGames;

/// <summary>
/// Drives the camera so it sits behind the LOCAL player's seat (or an overview when not seated),
/// looking across the table. Smoothly follows when seats change. Purely local - view only.
/// </summary>
public sealed class TableCamera : Component
{
	[Property] public float Smoothing { get; set; } = 8f;

	private TableAnchor Anchor => _anchor ??= Scene.Get<TableAnchor>();
	private TableAnchor _anchor;

	private CardGame Game => Scene.Get<CardGame>();

	protected override void OnUpdate()
	{
		if ( Anchor is null ) return;

		// A game can ask to zoom out further (Solitaire's board is bigger than a Blackjack table).
		float height = Game?.CameraHeight is > 0f and var h ? h : Anchor.CameraHeight;
		var target = Anchor.Camera( height );
		float t = 1f - MathF.Exp( -Smoothing * Time.Delta );
		WorldPosition = Vector3.Lerp( WorldPosition, target.Position, t );
		WorldRotation = Rotation.Slerp( WorldRotation, target.Rotation, t );
	}
}