Initial project
This commit is contained in:
168
Engine/Controller/PlayerCamera.cs
Normal file
168
Engine/Controller/PlayerCamera.cs
Normal file
@@ -0,0 +1,168 @@
|
||||
using Godot;
|
||||
|
||||
public partial class PlayerCamera : Camera3D
|
||||
{
|
||||
[ExportCategory("Camera Movement")]
|
||||
[Export] public float CameraPanSpeed { get; set; } = 20f;
|
||||
[Export] public float CameraZoomSpeed { get; set; } = 20f;
|
||||
[Export] public float CameraZoomMin { get; set; } = 10f;
|
||||
[Export] public float CameraZoomMax { get; set; } = 50f;
|
||||
|
||||
[ExportCategory("Edge Scrolling")]
|
||||
[Export] public float EdgeScrollMargin { get; set; } = 20f;
|
||||
[Export] public float EdgeScrollSpeed { get; set; } = 15f;
|
||||
|
||||
[ExportCategory("Rotation")]
|
||||
[Export] public float YawSensitivity { get; set; } = 0.5f;
|
||||
[Export] public float PitchSensitivity { get; set; } = 0.18f;
|
||||
[Export] public float StepDegreeMax { get; set; } = 3f;
|
||||
[Export] public float PitchDegreeMin { get; set; } = 10f;
|
||||
[Export] public float PitchDegreeMax { get; set; } = 80f;
|
||||
[Export] public bool CaptureMiddleButton { get; set; } = false;
|
||||
|
||||
Vector3 origin = Vector3.Zero;
|
||||
float orbitDistance = 25f;
|
||||
float currentHeight = 20f;
|
||||
float orbitRadius = 20f;
|
||||
bool isMiddleMouseRotating = false;
|
||||
float yaw = 0f;
|
||||
float pitch = 0f;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
var pitchMin = Mathf.DegToRad(PitchDegreeMin);
|
||||
var pitchMax = Mathf.DegToRad(PitchDegreeMax);
|
||||
|
||||
pitch = Mathf.Clamp(pitch, pitchMin, pitchMax);
|
||||
|
||||
UpdateCameraPosition();
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
var movement = Vector3.Zero;
|
||||
|
||||
// Keyboard Input
|
||||
if (Input.IsActionPressed("camera_pan_right"))
|
||||
{
|
||||
movement.X += 1f;
|
||||
}
|
||||
if (Input.IsActionPressed("camera_pan_left"))
|
||||
{
|
||||
movement.X -= 1f;
|
||||
}
|
||||
if (Input.IsActionPressed("camera_pan_up"))
|
||||
{
|
||||
movement.Z += 1f;
|
||||
}
|
||||
if (Input.IsActionPressed("camera_pan_down"))
|
||||
{
|
||||
movement.Z -= 1f;
|
||||
}
|
||||
|
||||
// Edge Scrolling
|
||||
var mousePosition = GetViewport().GetMousePosition();
|
||||
var viewportSize = GetViewport().GetVisibleRect().Size;
|
||||
|
||||
if (mousePosition.X < EdgeScrollMargin)
|
||||
{
|
||||
movement.X -= 1f;
|
||||
}
|
||||
if (mousePosition.X > viewportSize.X - EdgeScrollMargin)
|
||||
{
|
||||
movement.X += 1f;
|
||||
}
|
||||
if (mousePosition.Y < EdgeScrollMargin)
|
||||
{
|
||||
movement.Z -= 1f;
|
||||
}
|
||||
if (mousePosition.Y > viewportSize.Y - EdgeScrollMargin)
|
||||
{
|
||||
movement.Z += 1f;
|
||||
}
|
||||
|
||||
// Rotating
|
||||
if (movement.Length() > 0f)
|
||||
{
|
||||
movement = movement.Normalized().Rotated(Vector3.Up, yaw);
|
||||
origin += movement * CameraPanSpeed * (float)delta;
|
||||
|
||||
UpdateCameraPosition();
|
||||
}
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (@event is InputEventMouseButton mouseButtonEvent)
|
||||
{
|
||||
if (mouseButtonEvent.Pressed)
|
||||
{
|
||||
var delta = (float)GetProcessDeltaTime();
|
||||
|
||||
if (mouseButtonEvent.ButtonIndex is MouseButton.WheelUp)
|
||||
{
|
||||
orbitDistance = Mathf.Max(CameraZoomMin, orbitDistance - CameraZoomSpeed * delta);
|
||||
}
|
||||
else if (mouseButtonEvent.ButtonIndex is MouseButton.WheelDown)
|
||||
{
|
||||
orbitDistance = Mathf.Min(CameraZoomMax, orbitDistance + CameraZoomSpeed * delta);
|
||||
}
|
||||
|
||||
UpdateCameraPosition();
|
||||
}
|
||||
|
||||
if (mouseButtonEvent.ButtonIndex is MouseButton.Middle)
|
||||
{
|
||||
isMiddleMouseRotating = mouseButtonEvent.Pressed;
|
||||
|
||||
if (CaptureMiddleButton)
|
||||
{
|
||||
Input.MouseMode = mouseButtonEvent.Pressed
|
||||
? Input.MouseModeEnum.Captured
|
||||
: Input.MouseModeEnum.Visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (@event is InputEventMouseMotion mouseMotionEvent && isMiddleMouseRotating)
|
||||
{
|
||||
var viewportSize = GetViewport().GetVisibleRect().Size;
|
||||
var viewMin = (float)Mathf.Min(viewportSize.X, viewportSize.Y);
|
||||
var delta = (float)GetProcessDeltaTime() * 60f;
|
||||
|
||||
// px => normalized fraction of screen -> radians, scaled by dt
|
||||
var dx = (mouseMotionEvent.Relative.X / viewMin) * YawSensitivity * Mathf.Tau * delta;
|
||||
var dy = (mouseMotionEvent.Relative.Y / viewMin) * PitchSensitivity * Mathf.Tau * delta;
|
||||
|
||||
// Safety cap per event
|
||||
var maxStep = Mathf.DegToRad(StepDegreeMax);
|
||||
|
||||
dx = Mathf.Clamp(dx, -maxStep, maxStep);
|
||||
dy = Mathf.Clamp(dy, -maxStep, maxStep);
|
||||
|
||||
yaw -= dx;
|
||||
pitch += dy;
|
||||
|
||||
var pitchMin = Mathf.DegToRad(PitchDegreeMin);
|
||||
var pitchMax = Mathf.DegToRad(PitchDegreeMax);
|
||||
|
||||
pitch = Mathf.Clamp(pitch, pitchMax, pitchMax);
|
||||
|
||||
UpdateCameraPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCameraPosition()
|
||||
{
|
||||
var direction = new Vector3(
|
||||
x: Mathf.Sin(yaw) * Mathf.Cos(pitch),
|
||||
y: Mathf.Sin(pitch),
|
||||
z: Mathf.Cos(yaw) * Mathf.Cos(pitch)
|
||||
).Normalized();
|
||||
|
||||
Position = origin + direction * orbitDistance;
|
||||
LookAt(origin, Vector3.Up);
|
||||
|
||||
currentHeight = orbitDistance * Mathf.Sin(pitch);
|
||||
orbitRadius = orbitDistance * Mathf.Cos(pitch);
|
||||
}
|
||||
}
|
||||
1
Engine/Controller/PlayerCamera.cs.uid
Normal file
1
Engine/Controller/PlayerCamera.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://7pn3nacee2ay
|
||||
6
Engine/Controller/PlayerCamera.tscn
Normal file
6
Engine/Controller/PlayerCamera.tscn
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://badifqjgdh2os"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://7pn3nacee2ay" path="res://Engine/Controller/PlayerCamera.cs" id="1_ckl5i"]
|
||||
|
||||
[node name="PlayerCamera" type="Camera3D"]
|
||||
script = ExtResource("1_ckl5i")
|
||||
Reference in New Issue
Block a user