GodotShade/NoclipCamera.gd
2026-02-14 13:06:50 +01:00

133 lines
3.9 KiB
GDScript3

extends RigidBody3D
var rot_x = 0
var rot_y = 0
@export var PLAYER_SPEED = 1.0
@export var PLAYER_REACH = 1000
@export var NOCLIP = false
@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 = []
var delta_speed = 0
# 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):
delta_speed = PLAYER_SPEED * _delta * 500000
if NOCLIP:
process_noclip()
else:
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 = 5
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
constant_force.y = move_y * delta_speed
constant_force.x = (sin(rot_x) * move_z * delta_speed + cos(rot_x) * move_x * delta_speed)
constant_force.z = (-cos(rot_x) * move_z * delta_speed + sin(rot_x) * move_x * delta_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: Vector3 = raycast_result.position - (raycast_result.normal * 0.5)
hit_pos = Vector3(hit_pos.x, hit_pos.y, hit_pos.z)
ray_hit_positions.append(hit_pos)
print("ray hit at pos:", hit_pos)
signals_service.add_matter.emit(hit_pos, 0.2)
#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 * delta_speed
position.x += (sin(rot_x) * move_z * delta_speed + cos(rot_x) * move_x * delta_speed)
position.z += (-cos(rot_x) * move_z * delta_speed + sin(rot_x) * move_x * delta_speed)
move_y = 0
move_x = 0
move_z = 0