- Edited
Hey there =)
I am currently trying to have a Third Person camera, seen in the old classic 3D platformers. But I am having issues with it.
I want the player to be PARTIALLY independent of the camera. This means that when the player is looking around the world ... the Player Character will not rotate with the Cameras direction. But if the player starts to move again the world's directions will have been altered by the direction of the Camera.
Now here comes a strange bit, I've got everything for 99% working. But the last 1% has to do with a strange bug.
For some reason, if my CamerPivot's Y becomes larger than -90 or is smaller than 90 it is performing normally. But when it is smaller than -90 or bigger than 90 it inverts itself and shows this by circling.
me only moving mouse UP
Here is my C# code : You can explain it to me via GDScript as well =)
using Godot;
using System;
public class PlayerControlScript : KinematicBody
{
private Vector3 gravity = Vector3.Down * 30f;
private float speed;
[Export] public float crawlSpeed = 3f;
private bool isCrawling = false;
[Export] public float walkSpeed = 7f;
[Export] public float sprintSpeed = 21f;
[Export] public float accel = 3f;
private Vector3 velocity;
[Export] public float jumpSpeed = 14f;
private bool canJump = false;
private Spatial camPivot;
private Camera camera;
[Export] public float mouseSens = 0.3f;
[Export] public float minAngle = 50f;
[Export] public float maxAngle = 50f;
private Spatial playerMesh;
public override void _Ready()
{
camPivot = GetNode<Spatial>("../Player/CameraPivot");
camera = GetNode<Camera>("../Player/CameraPivot/Camera");
playerMesh = GetNode<Spatial>("../Player/PlayerMesh");
Input.SetMouseMode(Input.MouseMode.Captured);
speed = walkSpeed;
}
public void _GetInput()
{
bool isMoving = false;
float verticalVel = velocity.y;
velocity = new Vector3();
if (Input.IsActionPressed("Forward"))
{
velocity -= camera.GlobalTransform.basis.z * speed;
isMoving = true;
}
else if (Input.IsActionPressed("Backward"))
{
velocity += camera.GlobalTransform.basis.z * speed;
isMoving = true;
}
if (Input.IsActionPressed("Left"))
{
velocity -= camera.GlobalTransform.basis.x * speed;
isMoving = true;
}
else if (Input.IsActionPressed("Right"))
{
velocity += camera.GlobalTransform.basis.x * speed;
isMoving = true;
}
velocity.y = verticalVel;
velocity.LinearInterpolate(velocity, accel * GetPhysicsProcessDeltaTime());
if (isMoving)
{
float angle = Mathf.Atan2(-velocity.x, -velocity.z);
Vector3 playerRot = playerMesh.Rotation;
playerRot.y = angle;
playerMesh.Rotation = Vector3.Up * playerRot;
}
if (Input.IsActionPressed("Sprint"))
{
speed = sprintSpeed;
}
else if (Input.IsActionPressed("Crawl"))
{
speed = crawlSpeed;
isCrawling = true;
}
else
{
speed = walkSpeed;
isCrawling = false;
}
canJump = false;
if (Input.IsActionJustPressed("Jump") && !isCrawling)
{
canJump = true;
}
if (Input.IsActionJustPressed("ui_cancel"))
{
Input.SetMouseMode(Input.MouseMode.Visible);
}
}
public override void _UnhandledInput(InputEvent @event)
{
if (@event is InputEventMouseMotion eventMouseMotion)
{
eventMouseMotion = @event as InputEventMouseMotion;
camPivot.RotateX(Mathf.Deg2Rad(-eventMouseMotion.Relative.y * mouseSens));
camPivot.RotateY(Mathf.Deg2Rad(-eventMouseMotion.Relative.x * mouseSens));
Vector3 cameraRotation = camPivot.RotationDegrees;
cameraRotation.x = Mathf.Clamp(cameraRotation.x, -minAngle, maxAngle);
cameraRotation.z = Mathf.Clamp(cameraRotation.z, 0, 0);
camPivot.RotationDegrees = cameraRotation;
GD.Print(new Vector3(cameraRotation.x, cameraRotation.y, cameraRotation.z));
}
}
public override void _PhysicsProcess(float delta)
{
velocity.y += gravity.y * delta;
_GetInput();
velocity = MoveAndSlide(velocity, Vector3.Up);
if (canJump && IsOnFloor())
{
velocity.y = jumpSpeed;
}
}
}
I've pasted everything in since I am not sure what might be causing this issue.
Thanks for the help =)