Add player movement
This commit is contained in:
parent
269b962fef
commit
3f97e18615
27 changed files with 631 additions and 1 deletions
200
scripts/Player.cs
Normal file
200
scripts/Player.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue