Camera

Set up the 3D camera view using RaylibRenderer.

using Xengine.Rendering;

Setting the Camera

SetCamera

void SetCamera(Vector3 position, Vector3 target, float fov)
// Basic camera setup
RaylibRenderer.Instance?.SetCamera(
    new Vector3(0, 10, -10), // Camera position
    Vector3.Zero,             // Look at point
    60f                       // Field of view
);

Camera Component

Create a reusable camera component:

public class SimpleCamera : Component
{
    public Vector3 Position = new Vector3(0, 10, -10);
    public Vector3 Target = Vector3.Zero;
    public float FOV = 60f;
    
    protected override void OnUpdate()
    {
        RaylibRenderer.Instance?.SetCamera(Position, Target, FOV);
    }
}

Follow Camera

public class FollowCamera : Component
{
    public Vector3 Offset = new Vector3(0, 8, -10);
    public float SmoothSpeed = 5f;
    
    private Vector3 _currentPos;
    
    protected override void OnStart()
    {
        _currentPos = Offset;
    }
    
    protected override void OnUpdate()
    {
        var target = Scene?.FindByName("Player");
        if (target == null) return;
        
        var targetPos = target.Transform.Position + Offset;
        _currentPos = Vector3.Lerp(_currentPos, targetPos, SmoothSpeed * Time.Delta);
        
        RaylibRenderer.Instance?.SetCamera(_currentPos, target.Transform.Position, 60f);
    }
}

Orbit Camera

public class OrbitCamera : Component
{
    public float Distance = 15f;
    public float Height = 8f;
    public float RotationSpeed = 30f;
    
    private float _angle;
    
    protected override void OnUpdate()
    {
        _angle += RotationSpeed * Time.Delta;
        
        var pos = new Vector3(
            MathF.Cos(_angle * MathHelper.Deg2Rad) * Distance,
            Height,
            MathF.Sin(_angle * MathHelper.Deg2Rad) * Distance
        );
        
        RaylibRenderer.Instance?.SetCamera(pos, Vector3.Zero, 60f);
    }
}

First Person Camera

public class FirstPersonCamera : Component
{
    public float MouseSensitivity = 0.1f;
    private float _yaw, _pitch;
    
    protected override void OnUpdate()
    {
        var delta = RaylibInput.MouseDelta;
        _yaw += delta.X * MouseSensitivity;
        _pitch -= delta.Y * MouseSensitivity;
        _pitch = MathHelper.Clamp(_pitch, -89f, 89f);
        
        var direction = new Vector3(
            MathF.Cos(_pitch * MathHelper.Deg2Rad) * MathF.Cos(_yaw * MathHelper.Deg2Rad),
            MathF.Sin(_pitch * MathHelper.Deg2Rad),
            MathF.Cos(_pitch * MathHelper.Deg2Rad) * MathF.Sin(_yaw * MathHelper.Deg2Rad)
        );
        
        var target = Transform.Position + direction;
        RaylibRenderer.Instance?.SetCamera(Transform.Position, target, 60f);
    }
}

Screen Shake

public class ShakeCamera : Component
{
    public Vector3 BasePosition = new Vector3(0, 10, -10);
    private float _shakeAmount;
    private XRandom _random = new();
    
    public void Shake(float amount) => _shakeAmount = amount;
    
    protected override void OnUpdate()
    {
        _shakeAmount = MathF.Max(0, _shakeAmount - Time.Delta * 3f);
        
        var offset = _shakeAmount > 0.01f
            ? new Vector3(_random.Float(-1, 1), _random.Float(-1, 1), 0) * _shakeAmount
            : Vector3.Zero;
        
        RaylibRenderer.Instance?.SetCamera(BasePosition + offset, Vector3.Zero, 60f);
    }
}