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