Scripts/Managers/CameraManager.cs
using System;
namespace Milaine.Managers;
public sealed class CameraManager : Component {
[Property, Group("References")]
public CameraComponent Camera { get; set; }
[Property, Group("Limits (grades)"), Range(0f, 30f)]
public float MaxYaw { get; set; } = 6f; // left / right
[Property, Group("Limits (grades)"), Range(0f, 30f)]
public float MaxPitch { get; set; } = 4f; // top / down
[Property, Group("Smooth"), Range(1f, 20f)]
public float SmoothSpeed { get; set; } = 6f;
[Property, Group("Safe Zone"), Range(0f, 0.9f), Title("Dead Zone (0-1)")]
public float DeadZone { get; set; } = 0.665f;
private Rotation baseRotation;
private float currentYaw;
private float currentPitch;
protected override void OnStart() {
MouseManager.ShowMouse();
if (!Camera.IsValid()) {
Camera = Components.Get<CameraComponent>() ?? Scene.Camera;
}
if (Camera.IsValid()) {
var rot = Camera.WorldRotation;
baseRotation = IsValidRotation(rot) ? rot : Rotation.Identity;
}
}
protected override void OnUpdate() {
if (!Camera.IsValid()) {
return;
}
if (Screen.Size.x <= 0 || Screen.Size.y <= 0) {
return;
}
Vector2 offset = (Mouse.Position / Screen.Size - 0.5f) * 2f;
offset = offset.Clamp(-1f, 1f);
float x = ApplyDeadZone(offset.x);
float y = ApplyDeadZone(offset.y);
float targetYaw = -x * MaxYaw;
float targetPitch = y * MaxPitch;
currentYaw = MathX.Lerp(currentYaw, targetYaw, Time.Delta * SmoothSpeed);
currentPitch = MathX.Lerp(currentPitch, targetPitch, Time.Delta * SmoothSpeed);
Camera.WorldRotation = baseRotation * Rotation.From(currentPitch, currentYaw, 0f);
}
private static bool IsValidRotation(Rotation r) {
return !float.IsNaN(r.x) && !float.IsNaN(r.y) && !float.IsNaN(r.z) && !float.IsNaN(r.w);
}
private float ApplyDeadZone(float value) {
float sign = value < 0f ? -1f : 1f;
float magnitude = MathF.Abs(value);
if (magnitude < DeadZone) {
return 0f;
}
float range = 1f - DeadZone;
if (range <= 0.0001f) {
return 0f;
}
float remapped = (magnitude - DeadZone) / range;
return sign * remapped;
}
public void SetBaseRotation() {
if (Camera.IsValid()) {
baseRotation = Camera.WorldRotation;
}
}
}