GodotShade/NoclipCamera.gd
2025-11-26 19:07:10 +01:00

129 lines
3.8 KiB
GDScript3

extends RigidBody3D
var rot_x = 0
var rot_y = 0
@onready var world = $"../World/"
@export var PLAYER_SPEED = 1
@export var PLAYER_REACH = 1000
@export_range(0.00001, 0.01) var LOOK_SENSITIVITY = 0.002
var move_x = 0
var move_y = 0
var move_z = 0
var camera: Camera3D
var ray_hit_positions = []
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
# Called when the node enters the scene tree for the first time.
func _ready():
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
camera = find_child("PlayerCamera")
pass # Replace with function body.
func _input(event):
if Input.is_action_just_pressed("LeftClick"):
raycast_from_center()
if Input.is_action_just_pressed("RightClick"):
pass
if event is InputEventKey and event.is_action_released("ShowCursor"):
if Input.mouse_mode == Input.MOUSE_MODE_VISIBLE:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
else:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
if event is InputEventMouseMotion and (Input.mouse_mode == Input.MOUSE_MODE_CAPTURED or event.button_mask & 1):
# modify accumulated mouse rotation
rot_x += event.relative.x * LOOK_SENSITIVITY
rot_y += event.relative.y * LOOK_SENSITIVITY
camera.transform.basis = Basis() # reset rotation
rot_x = fmod(rot_x, (PI * 2))
rot_y = fmod(rot_y, (PI * 2))
camera.rotate_object_local(Vector3(0, -1, 0), rot_x) # first rotate in Y
camera.rotate_object_local(Vector3(-1, 0, 0), rot_y) # then rotate in X
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
process_noclip()
#process_physics_movements()
#for hit_pos in ray_hit_positions:
#DebugDraw3D.draw_sphere(hit_pos)
func process_physics_movements():
if Input.is_action_pressed("MoveCamUp"):
move_y = 1
if Input.is_action_pressed("MoveCamDown"):
pass
if Input.is_action_pressed("MoveCamLeft"):
move_x = -1
if Input.is_action_pressed("MoveCamRight"):
move_x = 1
if Input.is_action_pressed("MoveCamForward"):
move_z = 1
if Input.is_action_pressed("MoveCamBack"):
move_z = -1
constant_force.y = move_y * PLAYER_SPEED
constant_force.x = (sin(rot_x) * move_z * PLAYER_SPEED + cos(rot_x) * move_x * PLAYER_SPEED)
constant_force.z = (-cos(rot_x) * move_z * PLAYER_SPEED + sin(rot_x) * move_x * PLAYER_SPEED)
if constant_force.x != 0 || constant_force.y != 0 || constant_force.z != 0:
physics_material_override.friction = 0
else:
physics_material_override.friction = 1
move_y = 0
move_x = 0
move_z = 0
func raycast_from_center():
var center = get_viewport().size / 2
var ray_length = PLAYER_REACH
var ray_origin = camera.project_ray_origin(center)
var ray_direction = ray_origin + camera.project_ray_normal(center) * ray_length
var space = get_world_3d().direct_space_state
var ray_query = PhysicsRayQueryParameters3D.new()
ray_query.from = ray_origin
ray_query.to = ray_direction
ray_query.exclude = [self]
var raycast_result = space.intersect_ray(ray_query)
if len(raycast_result) > 0:
var hit_pos = raycast_result.position - (raycast_result.normal * 0.5)
hit_pos = Vector3i(round(hit_pos.x), round(hit_pos.y), round(hit_pos.z))
ray_hit_positions.append(hit_pos)
world.SetBlockAtPosition(hit_pos, Block.BlockType.Air)
func process_noclip():
if Input.is_action_pressed("MoveCamUp"):
move_y = 1
if Input.is_action_pressed("MoveCamDown"):
move_y = -1
if Input.is_action_pressed("MoveCamLeft"):
move_x = -1
if Input.is_action_pressed("MoveCamRight"):
move_x = 1
if Input.is_action_pressed("MoveCamForward"):
move_z = 1
if Input.is_action_pressed("MoveCamBack"):
move_z = -1
position.y += move_y * PLAYER_SPEED
position.x += (sin(rot_x) * move_z * PLAYER_SPEED + cos(rot_x) * move_x * PLAYER_SPEED)
position.z += (-cos(rot_x) * move_z * PLAYER_SPEED + sin(rot_x) * move_x * PLAYER_SPEED)
move_y = 0
move_x = 0
move_z = 0