Skip to main content

Takip kamerası isminden de belli olduğu gibi nesneleri takip eden bir kamera türüdür. Bu kamera genellikle sabit bir mesafeden hedefi takip eder ve hedefin dönmesiyle birlikte döner. Bu kamera türü birçok oyunda yer bulan, en çok kullanılan kameralardan biridir. Takip kamerasının konumu hedefin konumuna göre sabit olarak hesaplanırken, görünüm matrisi diğer kamera türlerine benzer şekilde bu değerler üzerinden hesaplanır.

kamera_takip_kamerasi

Takip kamerasının dönme miktarı hesaplanırken daha gerçekçi sonuçlar alabilmek için hedeften bağımsız dönmesini sağlayan esneklik (springiness) katsayısı kullanılmaktadır. Böylece kameranın yanlara esnemesi sağlanıp, katı hareketler yapması önlenir. Takip kamerası sınıfı için gerekli kod aşağıdaki gibidir.

public class ChaseCamera : Camera
{
    public Vector3 Position { get; private set; }
    public Vector3 Target { get; private set; }
    public Vector3 FollowTargetPosition { get; private set; }
    public Vector3 FollowTargetRotation { get; private set; }
    public Vector3 PositionOffset { get; set; }
    public Vector3 TargetOffset { get; set; }
    public Vector3 RelativeCameraRotation { get; set; }
    float springiness = .15f;
    public float Springiness
    {
        get { return springiness; }
        set { springiness = MathHelper.Clamp(value, 0, 1); }
    }
    public ChaseCamera(Vector3 PositionOffset, Vector3 TargetOffset, Vector3 RelativeCameraRotation, GraphicsDevice graphicsDevice)
        : base(graphicsDevice)
    {
        this.PositionOffset = PositionOffset;
        this.TargetOffset = TargetOffset;
        this.RelativeCameraRotation = RelativeCameraRotation;
    }
    public void Move(Vector3 NewFollowTargetPosition, Vector3 NewFollowTargetRotation)
    {
        this.FollowTargetPosition = NewFollowTargetPosition;
        this.FollowTargetRotation = NewFollowTargetRotation;
    }
    public void Rotate(Vector3 RotationChange)
    {
        this.RelativeCameraRotation += RotationChange;
    }
    public override void Update()
    {
        // Modelin dönme miktarlarını hesaplayarak kameranın da doğru şekilde dönmesini hesapla
        Vector3 combinedRotation = FollowTargetRotation + RelativeCameraRotation;
        // Kamera için gerekli dönme matrisini hesapla
        Matrix rotation = Matrix.CreateFromYawPitchRoll(combinedRotation.Y, combinedRotation.X, combinedRotation.Z);
        // Esneme olmadan dönme ve hedef matrislerine göre kameranın olması gereken konumunu hesapla
        Vector3 desiredPosition = FollowTargetPosition + Vector3.Transform(PositionOffset, rotation);
        // Kameranın şu anki pozisyonu ile istenen konumu arasını birleştir
        Position = Vector3.Lerp(Position, desiredPosition, Springiness);
        // Dönme matrisi ile yeni hedefi hesapla
        Target = FollowTargetPosition + Vector3.Transform(TargetOffset, rotation);
        // Kameranın üst kısmını veren vektörü hesapla
        Vector3 up = Vector3.Transform(Vector3.Up, rotation);
        // Görünüm matrisini yeniden hesapla
        View = Matrix.CreateLookAt(Position, Target, up);
    }
}