From 6decf97524c404e37fa9d7c3596798b073114def Mon Sep 17 00:00:00 2001 From: copygirl Date: Thu, 3 Oct 2024 20:01:22 +0200 Subject: [PATCH] Change to a perspective camera again --- CameraController.cs | 14 ------ level.tscn | 19 +------- player/CameraController.cs | 47 +++++++++++++++++++ .../MovementController.cs | 2 +- character.tscn => player/character.tscn | 20 +++++++- project.godot | 1 + utility/PhysicsLayer.cs | 1 + 7 files changed, 70 insertions(+), 34 deletions(-) delete mode 100644 CameraController.cs create mode 100644 player/CameraController.cs rename MovementController.cs => player/MovementController.cs (97%) rename character.tscn => player/character.tscn (56%) diff --git a/CameraController.cs b/CameraController.cs deleted file mode 100644 index 4d79de1..0000000 --- a/CameraController.cs +++ /dev/null @@ -1,14 +0,0 @@ -public partial class CameraController : Node3D -{ - private Vector3 Offset; - public override void _Ready() - { - Offset = Position; - } - - public override void _Process(double delta) - { - var target = GetParent().GlobalPosition + Offset; - GlobalPosition = GlobalPosition.Lerp(target, 1 - Pow(0.05f, (float)delta)); - } -} diff --git a/level.tscn b/level.tscn index b03b130..a2e45be 100644 --- a/level.tscn +++ b/level.tscn @@ -1,7 +1,6 @@ -[gd_scene load_steps=9 format=3 uid="uid://cmootlmme7yid"] +[gd_scene load_steps=8 format=3 uid="uid://cmootlmme7yid"] -[ext_resource type="PackedScene" uid="uid://daihc7acaxfns" path="res://character.tscn" id="1_ymqel"] -[ext_resource type="Script" path="res://CameraController.cs" id="2_wn05g"] +[ext_resource type="PackedScene" uid="uid://daihc7acaxfns" path="res://player/character.tscn" id="1_ymqel"] [ext_resource type="Resource" uid="uid://54xdqxlq2y2g" path="res://level_terrain_data.tres" id="4_axdnd"] [ext_resource type="Material" uid="uid://doe8owgx4jeu1" path="res://terrain/terrain_material.tres" id="4_edbby"] [ext_resource type="PackedScene" uid="uid://c732i0mrp6klk" path="res://objects/tree_oak_round.tscn" id="6_xbyit"] @@ -14,26 +13,12 @@ [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] transform = Transform3D(0.573576, -0.67101, 0.469846, 0, 0.573576, 0.819152, -0.819152, -0.469846, 0.32899, 0, 8, 0) shadow_enabled = true -shadow_blur = 1.5 -directional_shadow_mode = 0 [node name="Character" parent="." instance=ExtResource("1_ymqel")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, -1, -5) collision_layer = 0 collision_mask = 255 -[node name="CameraAnchor" type="Node3D" parent="Character"] -transform = Transform3D(0.707107, 0.5, 0.5, 0, 0.707107, -0.707107, -0.707107, 0.5, 0.5, 0, 0.12, 0) -script = ExtResource("2_wn05g") - -[node name="Camera" type="Camera3D" parent="Character/CameraAnchor"] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 20, 0) -projection = 1 -current = true -size = 4.5 -near = 1.0 -far = 50.0 - [node name="Terrain" type="StaticBody3D" parent="."] collision_mask = 0 script = ExtResource("9_rniku") diff --git a/player/CameraController.cs b/player/CameraController.cs new file mode 100644 index 0000000..bd77858 --- /dev/null +++ b/player/CameraController.cs @@ -0,0 +1,47 @@ +public partial class CameraController : SpringArm3D +{ + [Export] public Vector2 MouseSensitivity { get; set; } = new(0.2f, 0.2f); // Degrees per pixel. + [Export] public float PitchMinimum { get; set; } = -90; + [Export] public float PitchMaximum { get; set; } = -25; + + // FIXME: Fix the "snappyness" when moving slowly. + // TODO: Add a "soft" minimum / maximum for pitch. + // TODO: Gradually return to maximum spring length. + // TODO: Turn player transparent as the camera moves closer. + + public static bool IsMouseCaptured + => Input.MouseMode == Input.MouseModeEnum.Captured; + + public override void _Input(InputEvent ev) + { + if (IsMouseCaptured && ev.IsActionPressed("ui_cancel")) { + // When escape is pressed, release the mouse. + Input.MouseMode = Input.MouseModeEnum.Visible; + GetViewport().SetInputAsHandled(); + } + } + + public override void _UnhandledInput(InputEvent ev) + { + switch (ev) { + case InputEventMouseButton { ButtonIndex: MouseButton.Left, Pressed: true } when !IsMouseCaptured: + // When left mouse button is pressed, capture the mouse. + Input.MouseMode = Input.MouseModeEnum.Captured; + GetViewport().SetInputAsHandled(); + break; + case InputEventMouseMotion motion when IsMouseCaptured: + ApplyRotation(-motion.Relative * MouseSensitivity); + break; + } + } + + void ApplyRotation(Vector2 delta) + { + delta *= Tau / 360; // degrees to radians + var (pitch, yaw, _) = Rotation; + yaw += delta.X; + pitch += delta.Y; + pitch = Clamp(pitch, DegToRad(PitchMinimum), DegToRad(PitchMaximum)); + Rotation = new(pitch, yaw, 0); + } +} diff --git a/MovementController.cs b/player/MovementController.cs similarity index 97% rename from MovementController.cs rename to player/MovementController.cs index 23bd8ff..7838fe4 100644 --- a/MovementController.cs +++ b/player/MovementController.cs @@ -41,7 +41,7 @@ public partial class MovementController : Node var input = Input.GetVector("move_left", "move_right", "move_forward", "move_back"); var camera = GetViewport().GetCamera3D(); - var target = input.Rotated(camera.GlobalRotation.Y - Tau / 4) * MaxSpeed; + var target = input.Rotated(-camera.GlobalRotation.Y) * MaxSpeed; var isOnFloor = Player.IsOnFloor(); var isMoving = target.Dot(horVelocity) > 0.0f; diff --git a/character.tscn b/player/character.tscn similarity index 56% rename from character.tscn rename to player/character.tscn index 724ad9e..38e7538 100644 --- a/character.tscn +++ b/player/character.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=5 format=3 uid="uid://daihc7acaxfns"] +[gd_scene load_steps=6 format=3 uid="uid://daihc7acaxfns"] -[ext_resource type="Script" path="res://MovementController.cs" id="1_akh08"] +[ext_resource type="Script" path="res://player/MovementController.cs" id="1_akh08"] +[ext_resource type="Script" path="res://player/CameraController.cs" id="2_2din1"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_urpcu"] albedo_color = Color(0.25098, 0.690196, 0.12549, 0.815686) @@ -14,6 +15,8 @@ height = 0.35 radius = 0.2 [node name="Character" type="CharacterBody3D"] +collision_layer = 4 +collision_mask = 3 floor_max_angle = 0.698132 [node name="MeshInstance3D" type="MeshInstance3D" parent="."] @@ -26,3 +29,16 @@ shape = SubResource("SphereShape3D_6qbb2") [node name="MovementController" type="Node" parent="."] script = ExtResource("1_akh08") + +[node name="CameraArm" type="SpringArm3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.766044, 0.642788, 0, -0.642788, 0.766044, 0, 0.1, 0) +collision_mask = 3 +spring_length = 2.0 +margin = 0.05 +script = ExtResource("2_2din1") + +[node name="Camera" type="Camera3D" parent="CameraArm"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2) +current = true +size = 4.5 +far = 500.0 diff --git a/project.godot b/project.godot index f7a156a..d82889e 100644 --- a/project.godot +++ b/project.godot @@ -60,6 +60,7 @@ move_jump={ 3d_physics/layer_1="Terrain" 3d_physics/layer_2="Objects" +3d_physics/layer_3="Player" [rendering] diff --git a/utility/PhysicsLayer.cs b/utility/PhysicsLayer.cs index ce1ac75..3d50842 100644 --- a/utility/PhysicsLayer.cs +++ b/utility/PhysicsLayer.cs @@ -3,4 +3,5 @@ public enum PhysicsLayer { Terrain = 0b0000_0001, Objects = 0b0000_0010, + Player = 0b0000_0100, }