Add player movement

This commit is contained in:
Aslan 2026-01-24 12:34:02 -05:00
parent 269b962fef
commit 3f97e18615
27 changed files with 631 additions and 1 deletions

3
scripts/Constants.cs Normal file
View file

@ -0,0 +1,3 @@
public static partial class Constants
{
}

1
scripts/Constants.cs.uid Normal file
View file

@ -0,0 +1 @@
uid://dxtvl7k4e3nn4

View file

@ -0,0 +1,9 @@
using Godot;
public partial class GameMenuController : Control
{
public void OnMainMenu()
{
GetTree().ChangeSceneToFile("res://scenes/main_menu.tscn");
}
}

View file

@ -0,0 +1 @@
uid://betypbypf6bf2

View file

@ -0,0 +1,41 @@
using Godot;
public partial class GeneralControlManager : Node
{
[Export] Control GameMenu;
public override void _Ready()
{
Input.MouseMode = Input.MouseModeEnum.Captured;
}
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("ui_cancel"))
{
if (GameMenu.Visible)
{
HideMenu();
}
else
{
ShowMenu();
}
return;
}
}
public void ShowMenu()
{
GameMenu.Show();
Input.MouseMode = Input.MouseModeEnum.Visible;
}
public void HideMenu()
{
GameMenu.Hide();
Input.MouseMode = Input.MouseModeEnum.Captured;
}
}

View file

@ -0,0 +1 @@
uid://n557xfrv0i6x

View file

@ -0,0 +1,22 @@
using Godot;
public partial class GravityReceiver : Node3D
{
public bool InGravityZone = false;
public float GravityStrength = 0f;
public Vector3 GravityDirection = Vector3.Down;
public void EnterGravityZone(float gravityStrength, Vector3 gravityDirection)
{
InGravityZone = true;
GravityStrength = gravityStrength;
GravityDirection = gravityDirection;
}
public void ExitGravityZone()
{
InGravityZone = false;
GravityStrength = 0f;
GravityDirection = Vector3.Down;
}
}

View file

@ -0,0 +1 @@
uid://bwpdtkgmwjs7g

16
scripts/GravityZone.cs Normal file
View file

@ -0,0 +1,16 @@
using Godot;
public partial class GravityZone : Area3D
{
public void OnBodyEntered(Node3D body)
{
GravityReceiver receiver = body.GetNodeOrNull<GravityReceiver>("GravityReceiver");
receiver?.EnterGravityZone(Gravity, GlobalTransform.Basis.Y);
}
public void OnBodyExited(Node3D body)
{
GravityReceiver receiver = body.GetNodeOrNull<GravityReceiver>("GravityReceiver");
receiver?.ExitGravityZone();
}
}

View file

@ -0,0 +1 @@
uid://cy8nuarxbnd

3
scripts/Helpers.cs Normal file
View file

@ -0,0 +1,3 @@
public static partial class Helpers
{
}

1
scripts/Helpers.cs.uid Normal file
View file

@ -0,0 +1 @@
uid://de2nkadeybqn0

View file

@ -0,0 +1,14 @@
using Godot;
public partial class MainMenuController : Node
{
public void OnStartGame()
{
GetTree().ChangeSceneToFile("res://scenes/game.tscn");
}
public void OnExitGame()
{
GetTree().Quit();
}
}

View file

@ -0,0 +1 @@
uid://b7inoxterktk3

200
scripts/Player.cs Normal file
View file

@ -0,0 +1,200 @@
using Godot;
public partial class Player : CharacterBody3D
{
[Export] Control GameMenu;
[Export] public float Speed = 5f;
[Export] public float JumpForce = 5f;
[Export] public float MouseSensitivity = 0.2f;
private Vector3 gravityVelocity = Vector3.Zero;
private Vector3 movementVelocity = Vector3.Zero;
private float cameraPitch = 0f;
private Camera3D camera;
private GravityReceiver gravityReceiver;
public override void _Ready()
{
camera = GetNode<Camera3D>("Camera");
gravityReceiver = GetNode<GravityReceiver>("GravityReceiver");
}
public override void _PhysicsProcess(double delta)
{
Vector3 newGravityVelocity = gravityVelocity;
Vector3 newMovementVelocity = movementVelocity;
if (IsInGravity())
{
ProcessGravity(delta, ref newGravityVelocity);
if (!GameMenu.Visible)
{
ProcessControlsGravity(ref newGravityVelocity, ref newMovementVelocity);
}
}
else
{
newGravityVelocity = Vector3.Zero;
ProcessCamera(delta);
if (!GameMenu.Visible)
{
ProcessControls(ref newMovementVelocity);
}
}
gravityVelocity = newGravityVelocity;
movementVelocity = newMovementVelocity;
Velocity = newGravityVelocity + newMovementVelocity;
MoveAndSlide();
}
public override void _Input(InputEvent @event)
{
if (GameMenu.Visible)
{
return;
}
if (@event is InputEventMouseMotion motion)
{
float yawDelta = -motion.Relative.X * MouseSensitivity;
float yawDeltaRad = Mathf.DegToRad(yawDelta);
float pitchDelta = -motion.Relative.Y * MouseSensitivity;
float pitchDeltaRad = Mathf.DegToRad(pitchDelta);
RotateObjectLocal(Vector3.Up, yawDeltaRad);
if (IsInGravity())
{
cameraPitch = Mathf.Clamp(cameraPitch + pitchDelta, -90f, 90f);
}
else
{
RotateObjectLocal(Vector3.Right, pitchDeltaRad);
}
camera.RotationDegrees = new Vector3(cameraPitch, 0, 0);
}
}
public bool IsInGravity()
{
return gravityReceiver.InGravityZone && gravityReceiver.GravityStrength > 0f;
}
public bool IsOnGravityFloor()
{
for (int i = 0; i < GetSlideCollisionCount(); i++)
{
KinematicCollision3D collision = GetSlideCollision(i);
Vector3 collisionNormal = collision.GetNormal();
float alignment = collisionNormal.Dot(gravityReceiver.GravityDirection);
if (alignment > 0.7f)
{
return true;
}
}
return false;
}
private void ProcessGravity(double delta, ref Vector3 newGravityVelocity)
{
if (!IsOnGravityFloor())
{
newGravityVelocity -= gravityReceiver.GravityDirection * gravityReceiver.GravityStrength * (float)delta;
}
else
{
newGravityVelocity = -gravityReceiver.GravityDirection;
}
Vector3 currentUp = GlobalTransform.Basis.Y;
Vector3 targetUp = gravityReceiver.GravityDirection;
Vector3 axis = currentUp.Cross(targetUp);
if (axis.Length() < 0.00001f)
{
return;
}
float angle = currentUp.AngleTo(targetUp);
Rotate(axis.Normalized(), angle * (float)delta * 10f);
}
private void ProcessCamera(double delta)
{
if (cameraPitch > 0.01f)
{
cameraPitch -= 90f * (float)delta;
}
else if (cameraPitch < -0.001f)
{
cameraPitch += 90f * (float)delta;
}
if (Mathf.Abs(cameraPitch) < 1f)
{
cameraPitch = 0f;
}
camera.RotationDegrees = new Vector3(cameraPitch, 0, 0);
}
private void ProcessControlsGravity(ref Vector3 newGravityVelocity, ref Vector3 newMovementVelocity)
{
float inputX = Input.GetAxis("move_left", "move_right");
float inputZ = Input.GetAxis("move_forward", "move_back");
Vector3 direction = Transform.Basis.X * inputX + Transform.Basis.Z * inputZ;
if (direction != Vector3.Zero)
{
newMovementVelocity.X = direction.X * Speed;
newMovementVelocity.Y = direction.Y * Speed;
newMovementVelocity.Z = direction.Z * Speed;
}
else
{
newMovementVelocity.X = 0f;
newMovementVelocity.Y = 0f;
newMovementVelocity.Z = 0f;
}
if (Input.IsActionJustPressed("jump") && IsOnGravityFloor())
{
newGravityVelocity = gravityReceiver.GravityDirection * JumpForce;
}
}
private void ProcessControls(ref Vector3 newMovementVelocity)
{
float inputX = Input.GetAxis("move_left", "move_right");
float inputY = -Input.GetAxis("move_up", "move_down");
float inputZ = Input.GetAxis("move_forward", "move_back");
Vector3 direction = Transform.Basis.X * inputX + Transform.Basis.Y * inputY + Transform.Basis.Z * inputZ;
if (direction != Vector3.Zero)
{
newMovementVelocity.X = direction.X * Speed;
newMovementVelocity.Y = direction.Y * Speed;
newMovementVelocity.Z = direction.Z * Speed;
}
else
{
newMovementVelocity.X = 0f;
newMovementVelocity.Y = 0f;
newMovementVelocity.Z = 0f;
}
float inputRotateZ = Input.GetAxis("rotate_left", "rotate_right");
float rotateAmountZ = Mathf.DegToRad(inputRotateZ);
RotateObjectLocal(Vector3.Forward, rotateAmountZ);
}
}

1
scripts/Player.cs.uid Normal file
View file

@ -0,0 +1 @@
uid://cue3c56axvyja