init
This commit is contained in:
+128
-64
@@ -1,97 +1,161 @@
|
||||
extends CharacterBody3D
|
||||
|
||||
const SPEED := 5.0
|
||||
const JUMP_VELOCITY := 4.5
|
||||
const MOUSE_SENSITIVITY := 0.003
|
||||
# Acceleration and deceleration are m/s².
|
||||
# max_speed is m/s.
|
||||
@export var accel := 6.7
|
||||
@export var deccel := 8.5
|
||||
@export var max_speed := 6.2
|
||||
|
||||
const ACCEL := 20.0
|
||||
const DECEL := 15.0
|
||||
@export var has_suit := true
|
||||
@export var has_hvms2 := true
|
||||
|
||||
@export var gravity := 9.8
|
||||
@export var jump_velocity := 4.5
|
||||
|
||||
# Mouse sensitivity
|
||||
@export var mouse_sensitivity := 0.003
|
||||
|
||||
# Maximum camera pitch in degrees
|
||||
@export var max_pitch := 89.0
|
||||
|
||||
var movement_vec := Vector3.ZERO
|
||||
var input_vec := Vector4.ZERO
|
||||
var jump := false
|
||||
var air_jumps := 0
|
||||
|
||||
func _ready() -> void:
|
||||
if not has_suit:
|
||||
$yaw/pitch/Camera/Hud.visible = false
|
||||
|
||||
if has_hvms2:
|
||||
max_speed = 30.0
|
||||
accel = 10
|
||||
deccel = 20
|
||||
jump_velocity = 10
|
||||
|
||||
# Capture the mouse when the game starts
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
# Mouse-look
|
||||
if event is InputEventMouseMotion:
|
||||
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||
# Horizontal rotation: rotate the player
|
||||
$yaw.rotate_y(-event.relative.x * mouse_sensitivity)
|
||||
|
||||
# Vertical rotation: rotate the camera
|
||||
$yaw/pitch.rotate_x(-event.relative.y * mouse_sensitivity)
|
||||
|
||||
# Clamp pitch so the camera cannot flip upside down
|
||||
$yaw/pitch.rotation.x = clamp(
|
||||
$yaw/pitch.rotation.x,
|
||||
deg_to_rad(-max_pitch),
|
||||
deg_to_rad(max_pitch)
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
# Mouse click captures the mouse again
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
|
||||
return
|
||||
|
||||
# Keyboard input
|
||||
if event is InputEventKey:
|
||||
if event.keycode == KEY_ESCAPE and event.pressed:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
return
|
||||
var pressed: bool = event.pressed
|
||||
|
||||
if event.keycode == KEY_SPACE and event.pressed and is_on_floor():
|
||||
velocity.y = JUMP_VELOCITY
|
||||
match event.keycode:
|
||||
KEY_W:
|
||||
input_vec.w = 1.0 if pressed else 0.0
|
||||
|
||||
if event.keycode == KEY_E and event.pressed and not event.echo:
|
||||
var node = $yaw/pitch/Facing.get_collider()
|
||||
KEY_S:
|
||||
input_vec.x = 1.0 if pressed else 0.0
|
||||
|
||||
if node and node.has_method("interact"):
|
||||
node.interact(self)
|
||||
KEY_A:
|
||||
input_vec.y = 1.0 if pressed else 0.0
|
||||
|
||||
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||
$yaw.rotate_y(-event.relative.x * MOUSE_SENSITIVITY)
|
||||
KEY_D:
|
||||
input_vec.z = 1.0 if pressed else 0.0
|
||||
|
||||
$yaw/pitch.rotate_x(-event.relative.y * MOUSE_SENSITIVITY)
|
||||
KEY_SPACE:
|
||||
if pressed and is_on_floor():
|
||||
jump=true
|
||||
|
||||
$yaw/pitch.rotation.x = clamp(
|
||||
$yaw/pitch.rotation.x,
|
||||
deg_to_rad(-89.0),
|
||||
deg_to_rad(89.0)
|
||||
)
|
||||
KEY_ESCAPE:
|
||||
if pressed:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
|
||||
KEY_SHIFT:
|
||||
if has_hvms2:
|
||||
velocity.y = max(velocity.y, -3) if pressed else velocity.y
|
||||
gravity = 3 if pressed else 9.8
|
||||
if is_on_floor():
|
||||
velocity=$yaw/pitch/Camera.basis*Vector3(0,0,50)
|
||||
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
# Gravity
|
||||
if not is_on_floor():
|
||||
velocity += get_gravity() * delta
|
||||
# W/S/A/D input
|
||||
var input_direction := Vector2(
|
||||
input_vec.z - input_vec.y,
|
||||
input_vec.w - input_vec.x
|
||||
)
|
||||
|
||||
# Read keyboard state directly
|
||||
var input_x := 0.0
|
||||
var input_z := 0.0
|
||||
|
||||
if Input.is_key_pressed(KEY_A):
|
||||
input_x -= 1.0
|
||||
|
||||
if Input.is_key_pressed(KEY_D):
|
||||
input_x += 1.0
|
||||
|
||||
if Input.is_key_pressed(KEY_W):
|
||||
input_z -= 1.0
|
||||
|
||||
if Input.is_key_pressed(KEY_S):
|
||||
input_z += 1.0
|
||||
|
||||
# Create movement vector
|
||||
var input_direction := Vector3(input_x, 0.0, input_z)
|
||||
|
||||
# Prevent diagonal movement from being faster
|
||||
if input_direction.length_squared() > 0.0:
|
||||
if input_direction.length() > 1.0:
|
||||
input_direction = input_direction.normalized()
|
||||
|
||||
# Rotate movement relative to yaw
|
||||
var direction : Vector3 = $yaw.global_transform.basis * input_direction
|
||||
direction.y = 0.0
|
||||
# Camera yaw only
|
||||
var yaw_basis: Basis = $yaw.global_transform.basis
|
||||
|
||||
if direction.length_squared() > 0.0:
|
||||
direction = direction.normalized()
|
||||
var forward := -yaw_basis.z
|
||||
var right := yaw_basis.x
|
||||
|
||||
# Target velocity
|
||||
var target := direction * SPEED
|
||||
forward.y = 0.0
|
||||
right.y = 0.0
|
||||
|
||||
var acceleration := ACCEL
|
||||
if direction.length_squared() == 0.0:
|
||||
acceleration = DECEL
|
||||
forward = forward.normalized()
|
||||
right = right.normalized()
|
||||
|
||||
# Smooth movement toward target
|
||||
velocity.x = move_toward(
|
||||
var target_direction := (
|
||||
right * input_direction.x
|
||||
+ forward * input_direction.y
|
||||
)
|
||||
|
||||
# Target horizontal velocity in m/s
|
||||
var target_velocity := target_direction * max_speed
|
||||
|
||||
# Current horizontal velocity in m/s
|
||||
var current_velocity := Vector3(
|
||||
velocity.x,
|
||||
target.x,
|
||||
0.0,
|
||||
velocity.z
|
||||
)
|
||||
|
||||
# Acceleration/deceleration in m/s²
|
||||
var acceleration := accel if target_direction != Vector3.ZERO else deccel
|
||||
|
||||
current_velocity = current_velocity.move_toward(
|
||||
target_velocity,
|
||||
acceleration * delta
|
||||
)
|
||||
|
||||
velocity.z = move_toward(
|
||||
velocity.z,
|
||||
target.z,
|
||||
acceleration * delta
|
||||
)
|
||||
velocity.x = current_velocity.x
|
||||
velocity.z = current_velocity.z
|
||||
|
||||
# Gravity
|
||||
if not is_on_floor():
|
||||
velocity.y -= gravity * delta
|
||||
else:
|
||||
if jump:
|
||||
velocity.y=jump_velocity
|
||||
jump=false
|
||||
else:
|
||||
velocity.y=0.0
|
||||
|
||||
if global_position.y<=-1000:
|
||||
get_tree().reload_current_scene()
|
||||
|
||||
move_and_slide()
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
extends Node2D
|
||||
|
||||
func _ready() -> void:
|
||||
$Container.size=get_viewport_rect().size
|
||||
|
||||
func set_tooltip(text: String) -> void:
|
||||
$Tooltip.text=text
|
||||
$Container/Tooltip.text=text
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,72 @@
|
||||
extends MeshInstance3D
|
||||
|
||||
@export var max_lights := 256
|
||||
@export var camera: Camera3D
|
||||
|
||||
var lights: Array[Light3D] = []
|
||||
|
||||
func _ready() -> void:
|
||||
find_lights(get_tree().current_scene)
|
||||
|
||||
func find_lights(node: Node) -> void:
|
||||
if node is Light3D:
|
||||
lights.append(node)
|
||||
|
||||
for child in node.get_children():
|
||||
find_lights(child)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var mat := material_override as ShaderMaterial
|
||||
if mat == null:
|
||||
return
|
||||
|
||||
if camera == null:
|
||||
camera = get_viewport().get_camera_3d()
|
||||
|
||||
if camera == null:
|
||||
return
|
||||
|
||||
mat.set_shader_parameter(
|
||||
"inv_projection",
|
||||
camera.get_camera_projection().inverse()
|
||||
)
|
||||
|
||||
mat.set_shader_parameter(
|
||||
"inv_view",
|
||||
camera.global_transform
|
||||
)
|
||||
|
||||
if mat == null:
|
||||
return
|
||||
|
||||
var positions := PackedVector3Array()
|
||||
var colors := PackedColorArray()
|
||||
var energies := PackedFloat32Array()
|
||||
var ranges := PackedFloat32Array()
|
||||
|
||||
for light in lights:
|
||||
if not is_instance_valid(light):
|
||||
continue
|
||||
|
||||
if not light.visible:
|
||||
continue
|
||||
|
||||
positions.append(light.global_position)
|
||||
colors.append(light.light_color)
|
||||
energies.append(light.light_energy)
|
||||
|
||||
if light is OmniLight3D:
|
||||
ranges.append(light.omni_range)
|
||||
elif light is SpotLight3D:
|
||||
ranges.append(light.spot_range)
|
||||
else:
|
||||
ranges.append(100.0)
|
||||
|
||||
if positions.size() >= max_lights:
|
||||
break
|
||||
|
||||
mat.set_shader_parameter("light_positions", positions)
|
||||
mat.set_shader_parameter("light_colors", colors)
|
||||
mat.set_shader_parameter("light_energies", energies)
|
||||
mat.set_shader_parameter("light_ranges", ranges)
|
||||
mat.set_shader_parameter("light_count", positions.size())
|
||||
@@ -0,0 +1 @@
|
||||
uid://blvu4cfl61262
|
||||
Reference in New Issue
Block a user