This commit is contained in:
Thomas Muller 2024-12-20 22:54:37 -05:00
parent 5d51e0a16e
commit 1d51e870f3
6 changed files with 407 additions and 0 deletions

View file

@ -11,5 +11,59 @@ config_version=5
[application] [application]
config/name="fml-avs" config/name="fml-avs"
run/main_scene="res://scenes/devworld.tscn"
config/features=PackedStringArray("4.3", "Forward Plus") config/features=PackedStringArray("4.3", "Forward Plus")
config/icon="res://icon.svg" config/icon="res://icon.svg"
[input]
move_forward={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
]
}
move_backward={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
]
}
move_left={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
]
}
move_right={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
]
}
jump={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
]
}
interact={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
]
}
run={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
pause={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
noclip={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":86,"key_label":0,"unicode":118,"location":0,"echo":false,"script":null)
]
}
flashlight={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null)
]
}

62
scenes/devworld.tscn Normal file
View file

@ -0,0 +1,62 @@
[gd_scene load_steps=8 format=3 uid="uid://vv1rwk4sfpch"]
[ext_resource type="PackedScene" uid="uid://clvn53i6enmno" path="res://assets/maps/devworld.blend" id="1_pj3hd"]
[ext_resource type="PackedScene" uid="uid://cy86jyiy6skvk" path="res://scenes/player.tscn" id="2_b2roh"]
[ext_resource type="PackedScene" uid="uid://nnxd1djnxech" path="res://scenes/phys_cube.tscn" id="3_8byy4"]
[ext_resource type="PackedScene" uid="uid://c8untjpyh1rjm" path="res://assets/models/general/mirror.blend" id="4_8rfge"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_2mm68"]
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
[sub_resource type="Sky" id="Sky_frs4c"]
sky_material = SubResource("ProceduralSkyMaterial_2mm68")
[sub_resource type="Environment" id="Environment_x3vhq"]
background_mode = 2
sky = SubResource("Sky_frs4c")
tonemap_mode = 2
ssr_enabled = true
ssao_enabled = true
ssil_enabled = true
sdfgi_enabled = true
sdfgi_use_occlusion = true
glow_enabled = true
[node name="Devworld" type="Node3D"]
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_x3vhq")
[node name="devworld" parent="." instance=ExtResource("1_pj3hd")]
[node name="cameratri" parent="devworld/player" index="1"]
visible = false
[node name="cameraframe" parent="devworld/player" index="2"]
visible = false
[node name="Point" parent="devworld" index="2"]
visible = false
[node name="Player" parent="." instance=ExtResource("2_b2roh")]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 5.803, 0, 7.171)
[node name="PhysCube" parent="." instance=ExtResource("3_8byy4")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.51921, 5.04702, 11.6844)
[node name="CSGBox3D" type="CSGBox3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.11, 0)
use_collision = true
size = Vector3(60, 0.2, 60)
[node name="mirror" parent="." instance=ExtResource("4_8rfge")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.21713, 1.33524, 15.4176)
[node name="OmniLight3D" type="OmniLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 6.60592, 0)
light_energy = 16.41
omni_range = 4096.0
[editable path="devworld"]
[editable path="mirror"]

17
scenes/phys_cube.tscn Normal file
View file

@ -0,0 +1,17 @@
[gd_scene load_steps=3 format=3 uid="uid://nnxd1djnxech"]
[ext_resource type="Script" path="res://scripts/physics_object.gd" id="1_lx1c5"]
[sub_resource type="BoxShape3D" id="BoxShape3D_h6ouo"]
size = Vector3(9.24554, 1, 1)
[node name="PhysCube" type="RigidBody3D"]
script = ExtResource("1_lx1c5")
[node name="CSGBox3D" type="CSGBox3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
size = Vector3(9.21936, 1, 1)
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
shape = SubResource("BoxShape3D_h6ouo")

33
scenes/player.tscn Normal file
View file

@ -0,0 +1,33 @@
[gd_scene load_steps=4 format=3 uid="uid://cy86jyiy6skvk"]
[ext_resource type="Script" path="res://scripts/player.gd" id="1_ocinr"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ljkaw"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_muavk"]
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1_ocinr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CapsuleShape3D_ljkaw")
[node name="CSGMesh3D" type="CSGMesh3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
mesh = SubResource("CapsuleMesh_muavk")
[node name="Camera3D" type="Camera3D" parent="CSGMesh3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
fov = 90.0
[node name="Ball" type="CSGSphere3D" parent="."]
radius = 0.1
[node name="Flashlight" type="SpotLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.990268, 0.139173, 0, -0.139173, 0.990268, 0, 1.5, -0.4)
light_color = Color(1, 1, 0.768627, 1)
shadow_enabled = true
distance_fade_enabled = true
spot_range = 23.178
spot_angle = 40.14

25
scripts/physics_object.gd Normal file
View file

@ -0,0 +1,25 @@
extends RigidBody3D
#
#const QUAKE = 0.0625 / 2
#const g = -800 * QUAKE
#
#@export
#var push_force = 400
#@export
#var max_velocity: float = 1000.0
#
#
##var is_held = false
##var target_velocity: Vector3 = Vector3(0, 0, 0)
##
##
##func _physics_process(delta):
##if is_held:
##linear_velocity = target_velocity * delta
##else:
##linear_velocity.y += g * delta
#
#
func can_hold(player):
return true

216
scripts/player.gd Normal file
View file

@ -0,0 +1,216 @@
extends CharacterBody3D
# Member variables
const QUAKE = 0.0625 / 2
const g = -800 * QUAKE
const MAX_SPEED = 320 * QUAKE
const MAX_AIR_SPEED = 30 * QUAKE
const FRICTION = 4# * QUAKE
const STOP_SPEED = 100 * QUAKE
const ACCEL = 15# * QUAKE
const AIR_ACCEL = 2# * QUAKE
const FORWARD_SPEED = 200 * QUAKE
const SIDE_SPEED = 350 * QUAKE
const UP_SPEED = 270 * QUAKE
const JUMP_SPEED = 270 * QUAKE
@export
var hold_force = 400
@export
var max_hold_velocity: float = 1000.0
# const DEACCEL= 8
# const MAX_SLOPE_ANGLE = 30https://www.youtube.com/watch?v=v3zT3Z5apaM
@onready
var _camera = $CSGMesh3D/Camera3D
@onready
var _ball = $Ball
@onready
var _collider = $CollisionShape3D
@onready
var _flashlight: SpotLight3D = $Flashlight
var _paused = false
var _noclip = false
var _held_object = null
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _process(_delta):
# Do this on the render tick so it doesnt jitter at higher FPS
_ball.global_position = _camera.global_position - _camera.global_transform.basis.z * 2.0
func _physics_process(delta):
# Shamelessly stolen code from quake :)
var fmove = 0.0
var smove = 0.0
var upmove = 0.0
if Input.is_action_pressed("move_forward"):
fmove += -FORWARD_SPEED
if Input.is_action_pressed("move_backward"):
fmove += FORWARD_SPEED
if Input.is_action_pressed("move_left"):
smove += -SIDE_SPEED
if Input.is_action_pressed("move_right"):
smove += SIDE_SPEED
#if Input.is_action_pressed("up"):
# upmove += UP_SPEED
if Input.is_action_pressed("run"):
fmove *= 2.0
smove *= 2.0
var wishvel = Vector3()
var cam_xform: Transform3D = _camera.get_global_transform()
var cam_basis: Basis = cam_xform.basis
wishvel = cam_basis.z * fmove + cam_basis.x * smove
if _noclip:
wishvel.y += upmove
var wishdir = wishvel.normalized()
var wishspeed = wishvel.length()
if wishspeed > MAX_SPEED:
wishvel *= MAX_SPEED / wishspeed
wishspeed = MAX_SPEED
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y += JUMP_SPEED
var vel = velocity
if _noclip:
vel = wishvel * 2
elif is_on_floor():
vel = _apply_friction(vel, delta)
vel = _apply_accel(vel, wishdir, wishspeed, delta)
else:
vel = _apply_air_accel(vel, wishvel, wishspeed, delta)
if not _noclip and not is_on_floor():
vel.y += g * delta
velocity = vel
move_and_slide()
if _held_object:
_apply_holding_force(delta)
func _apply_friction(vel: Vector3, delta: float):
var speed = sqrt(vel.x ** 2 + vel.z ** 2)
if(speed == 0.0): return vel
# TODO: edge detect friction?
var friction = FRICTION
var control = 0.0
if speed < STOP_SPEED:
control = STOP_SPEED
else:
control = speed
var newspeed = speed - delta * control * friction
if newspeed < 0.0:
newspeed = 0.0
else:
newspeed /= speed
return vel * newspeed
func _apply_accel(vel: Vector3, wishdir: Vector3, wishspeed: float, delta: float):
var currentspeed = vel.dot(wishdir)
var addspeed = wishspeed - currentspeed
if addspeed <= 0.0:
return vel
var accelspeed = ACCEL * delta * wishspeed
if accelspeed > addspeed:
accelspeed = addspeed
return vel + accelspeed * wishdir
func _apply_air_accel(vel: Vector3, wishvel: Vector3, wishspeed: float, delta: float):
var wishveloc = wishvel.normalized()
var wishspd = wishvel.length()
if wishspd > MAX_AIR_SPEED:
wishspd = MAX_AIR_SPEED
var currentspeed = vel.dot(wishveloc)
var addspeed = wishspd - currentspeed
if addspeed <= 0:
return vel
var accelspeed = AIR_ACCEL * wishspeed * delta
if accelspeed > addspeed:
accelspeed = addspeed
return vel + accelspeed * wishveloc
func _apply_holding_force(delta):
var delta_position = _ball.global_position - _held_object.global_position
var move_speed = min(delta_position.length() * hold_force, max_hold_velocity)
_held_object.linear_velocity = delta_position.normalized() * move_speed * delta
func _input(event):
if event.is_action_pressed("pause"):
_paused = not _paused
if _paused:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
if _paused: return
if event.is_action_pressed('noclip'):
_noclip = not _noclip
if _noclip:
_collider.disabled = true
else:
_collider.disabled = false
if event.is_action_pressed('flashlight'):
_flashlight.visible = not _flashlight.visible
# Camera
if event is InputEventMouseMotion:
rotation.y += -event.relative.x * 0.005
_camera.rotation.x += -event.relative.y * 0.005
_camera.rotation.x = clamp(_camera.rotation.x, deg_to_rad(-90), deg_to_rad(90))
# Rotate flashlight
_flashlight.rotation.x = _camera.rotation.x
if event.is_action_pressed("interact"):
# Handle dropping things
if _held_object:
#_held_object.drop()
_held_object = null
return
var space_state = get_world_3d().direct_space_state
# use global coordinates, not local to node
var query = PhysicsRayQueryParameters3D.create(_camera.global_position, _ball.global_position)
# Don't collide with ourselves
query.exclude = [self]
var result = space_state.intersect_ray(query)
if result.has('collider'):
print(result)
var other: Node3D = result.collider
if other.has_method('interact'):
other.interact(self)
if other.has_method('can_hold'):
print('Object')
if other.can_hold(self):
print('Can Hold')
_held_object = other
print(_held_object)