Merge pull request #1223 from Calinou/add-3d-physics-interpolation-demo

Add 3D physics interpolation demo
This commit is contained in:
Aaron Franke
2025-09-30 09:37:52 -07:00
committed by GitHub
18 changed files with 784 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

View File

@@ -0,0 +1,25 @@
# Physics Interpolation
This demo showcases [physics interpolation](https://docs.godotengine.org/en/stable/tutorials/physics/interpolation/index.html)
in 3D with varying camera modes (first person, third person, fixed perspective).
This is also known as *fixed timestep interpolation*.
Physics interpolation makes motion appear smooth regardless of the rendered
framerate and physics ticks per second configured in the Project Settings.
There are some caveats related to its usage though, such as increased latency
and potential issues with teleporting objects. It's recommended to go
through the
[documentation](https://docs.godotengine.org/en/stable/tutorials/physics/interpolation/physics_interpolation_introduction.html)
when enabling physics interpolation in a project.
Physics interpolation is enabled by default in this project. Press <kbd>T</kbd>
to toggle it while the demo is running. This allows you to see the impact on
smoothness of physics interpolation.
Language: GDScript
Renderer: Compatibility
## Screenshots
![Screenshot](screenshots/physics_interpolation.webp)

View File

@@ -0,0 +1,18 @@
[gd_scene load_steps=4 format=3 uid="uid://cvgxw8nq67xxm"]
[sub_resource type="BoxShape3D" id="BoxShape3D_pq8q7"]
[sub_resource type="BoxMesh" id="BoxMesh_pyidc"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_oq5cr"]
albedo_color = Color(0.5544661, 0.39379695, 0.15444939, 1)
[node name="Box" type="RigidBody3D"]
mass = 10.0
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("BoxShape3D_pq8q7")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
mesh = SubResource("BoxMesh_pyidc")
surface_material_override/0 = SubResource("StandardMaterial3D_oq5cr")

View File

@@ -0,0 +1,27 @@
extends RigidBody3D
@export var scale_curve: Curve
var _enabled: bool = false
func _ready() -> void:
$CollisionShape3D.disabled = true
func _physics_process(_delta: float) -> void:
# Start with physics collision disabled until the first tick.
# This prevents bullets from colliding with the player when first shot, while still
# allowing them to be moved by the player when they're laying on the ground.
if !_enabled:
$CollisionShape3D.disabled = false
_enabled = true
# Apply the appearance scaling according to the scale curve.
var time_left_ratio: float = 1.0 - $Timer.time_left / $Timer.wait_time
var scale_sampled := scale_curve.sample_baked(time_left_ratio)
$Scaler.scale = Vector3.ONE * scale_sampled
func _on_timer_timeout() -> void:
queue_free()

View File

@@ -0,0 +1 @@
uid://dohdjr8ilotkr

View File

@@ -0,0 +1,86 @@
[gd_scene load_steps=15 format=3 uid="uid://2r5wc1n0ybju"]
[ext_resource type="Script" uid="uid://dohdjr8ilotkr" path="res://bullet.gd" id="1_v7oki"]
[ext_resource type="Texture2D" uid="uid://b70s43gn8c3kx" path="res://spark_particle.png" id="2_v8qja"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_v8qja"]
bounce = 0.61
[sub_resource type="Curve" id="Curve_t4vbm"]
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.02, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 3
[sub_resource type="SphereShape3D" id="SphereShape3D_rtl8c"]
radius = 0.2
[sub_resource type="Gradient" id="Gradient_v8qja"]
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_t4vbm"]
gradient = SubResource("Gradient_v8qja")
[sub_resource type="Curve" id="Curve_v8qja"]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="CurveTexture" id="CurveTexture_t4vbm"]
curve = SubResource("Curve_v8qja")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_v7oki"]
direction = Vector3(0, 1, 0)
initial_velocity_max = 1.0
gravity = Vector3(0, 1, 0)
scale_min = 0.2
scale_curve = SubResource("CurveTexture_t4vbm")
color_ramp = SubResource("GradientTexture1D_t4vbm")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_t4vbm"]
transparency = 1
blend_mode = 1
shading_mode = 0
vertex_color_use_as_albedo = true
albedo_color = Color(2.33575, 3.29442, 3.29442, 1)
albedo_texture = ExtResource("2_v8qja")
texture_filter = 5
[sub_resource type="QuadMesh" id="QuadMesh_rtl8c"]
material = SubResource("StandardMaterial3D_t4vbm")
size = Vector2(0.2, 0.2)
[sub_resource type="SphereMesh" id="SphereMesh_v7oki"]
radial_segments = 24
rings = 12
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_v7oki"]
albedo_color = Color(0.431649, 0.57319, 0.501392, 1)
metallic = 1.0
[node name="Bullet" type="RigidBody3D"]
collision_layer = 2
physics_material_override = SubResource("PhysicsMaterial_v8qja")
script = ExtResource("1_v7oki")
scale_curve = SubResource("Curve_t4vbm")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("SphereShape3D_rtl8c")
[node name="GPUParticles3D" type="GPUParticles3D" parent="."]
amount = 64
transform_align = 1
process_material = SubResource("ParticleProcessMaterial_v7oki")
draw_pass_1 = SubResource("QuadMesh_rtl8c")
[node name="Scaler" type="Node3D" parent="."]
transform = Transform3D(0.001, 0, 0, 0, 0.001, 0, 0, 0, 0.001, 0, 0, 0)
[node name="MeshInstance3D" type="MeshInstance3D" parent="Scaler"]
transform = Transform3D(0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.4, 0, 0, 0)
mesh = SubResource("SphereMesh_v7oki")
skeleton = NodePath("../..")
surface_material_override/0 = SubResource("StandardMaterial3D_v7oki")
[node name="Timer" type="Timer" parent="."]
wait_time = 5.0
autostart = true
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]

View File

@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c5avn6uhdr88"
path.s3tc="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://icon.png"
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><g fill="none" stroke="#5fff95" stroke-linecap="round" style="stroke:gray;stroke-opacity:1" transform="matrix(8 0 0 8 -4 36)"><path stroke-width="2" d="M2 6c5 0 3-4 6-4s1 4 6 4" style="stroke:gray;stroke-opacity:1"/><circle cx="14" cy="2" r="1.5" style="stroke:gray;stroke-opacity:1"/></g></svg>

After

Width:  |  Height:  |  Size: 361 B

View File

@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cb05v27t8vx5t"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@@ -0,0 +1,202 @@
extends CharacterBody3D
const MOUSE_SENSITIVITY = 2.5
const CAMERA_SMOOTH_SPEED = 10.0
const MOVE_SPEED = 3.0
const FRICTION = 10.0
const JUMP_VELOCITY = 8.0
const BULLET_SPEED = 9.0
const Bullet = preload("res://bullet.tscn")
# Define our FPS and TPS player views using Euler angles.
var _yaw: float = 0.0
var _pitch: float = 0.0
# XZ direction the player is looking at.
var _dir := Vector3(sin(_yaw), 0, cos(_yaw))
# TPS camera.
var _tps_camera_proximity: float = 3.0
var _tps_camera_look_from := Vector3()
enum CameraType {
CAM_FIXED, ## Fixed camera perspective.
CAM_FPS, ## First-person perspective.
CAM_TPS, ## Third-person perspective.
}
# Current camera type.
# (Note that we toggle this in `_ready()`, so it actually starts with FPS camera.)
var _cam_type := CameraType.CAM_FIXED
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
func _ready() -> void:
# Capture the mouse (stops the mouse cursor from showing and ensures it stays within the window).
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
# We define the TPS camera in global space by setting it
# as `top_level` so it ignores the parent transform.
$Rig/Camera_TPS.top_level = true
# Perform the logic to create FPS view to start with.
cycle_camera_type()
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
_yaw -= event.screen_relative.x * MOUSE_SENSITIVITY * 0.001
_pitch += event.screen_relative.y * MOUSE_SENSITIVITY * 0.002
_pitch = clamp(_pitch, -PI, PI)
$Rig.rotation = Vector3(0, _yaw, 0)
func _update_camera(delta: float) -> void:
# Keep the player direction up-to-date based on the yaw.
_dir.x = sin(_yaw)
_dir.z = cos(_yaw)
# Rotate the head (and FPS camera and firing origin) with the
# pitch from the mouse.
$Rig/Head.rotation = Vector3(_pitch * -0.5, 0, 0)
match _cam_type:
CameraType.CAM_TPS:
# We will focus the TPS camera on the head of the player.
var target: Vector3 = $Rig/Head.get_global_transform_interpolated().origin
# Calculate a position to look at the player from.
var pos := target
# The camera should be behind the player, so offset the camera relative to direction.
pos.x += _dir.x * _tps_camera_proximity
pos.z += _dir.z * _tps_camera_proximity
# Move the TPS camera up and down depending on the pitch.
# There's no special formula here, just something that looks okay.
pos.y += 2.0 + _pitch * _tps_camera_proximity * 0.2
# Offset from the old `_tps_camera_look_from` to the new position
# we want the TPS camera to move to.
var offset: Vector3 = pos - _tps_camera_look_from
var l: float = offset.length()
# We cap how far we allow the TPS camera to move on each update,
# so we get a smooth movement rather than snapping.
var tps_cam_speed: float = CAMERA_SMOOTH_SPEED * delta
# If we are trying to move further than the maximum allowed,
# we resize the offset to `tps_cam_speed`.
if l > tps_cam_speed:
offset *= tps_cam_speed / l
# Move the TPS camera.
_tps_camera_look_from += offset
# `look_at_from_position()` does all the magic for us.
$Rig/Camera_TPS.look_at_from_position(_tps_camera_look_from, target, Vector3(0, 1, 0))
# For a real TPS camera, some other things to try:
# - Ray cast from the player towards the camera to prevent it looking through walls.
# The SpringArm3D node can be useful here.
# - Try smoothing the camera by yaw/pitch from the player rather than offset.
func cycle_camera_type() -> void:
match _cam_type:
CameraType.CAM_FIXED:
_cam_type = CameraType.CAM_FPS
$Rig/Head/Camera_FPS.make_current()
CameraType.CAM_FPS:
_cam_type = CameraType.CAM_TPS
$Rig/Camera_TPS.make_current()
CameraType.CAM_TPS:
_cam_type = CameraType.CAM_FIXED
get_node("../Camera_Fixed").make_current()
# Hide body in FPS view (but keep shadow casting to improve spatial awareness).
if _cam_type == CameraType.CAM_FPS:
$Rig/Mesh_Body.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_SHADOWS_ONLY
else:
$Rig/Mesh_Body.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_ON
func _process(delta: float) -> void:
if Input.is_action_just_pressed(&"cycle_camera_type"):
cycle_camera_type()
if Input.is_action_just_pressed(&"toggle_physics_interpolation"):
get_tree().physics_interpolation = not get_tree().physics_interpolation
if Input.is_action_just_pressed(&"fire"):
var bullet: RigidBody3D = Bullet.instantiate()
# Figure out where we want the bullet to spawn.
# We use a dummy Node offset from the head, but you may want to use e.g.
# a BoneAttachment3D, or dummy node on a weapon.
var transform_3d: Transform3D = $Rig/Head/Fire_Origin.get_global_transform_interpolated()
bullet.position = transform_3d.origin
# We can calculate the direction the bullet should travel from the basis (rotation)
# of the dummy Node.
var bul_dir: Vector3 = transform_3d.basis[2].normalized()
# Give our physics bullet some starting velocity.
bullet.linear_velocity = bul_dir * -BULLET_SPEED
get_parent().add_child(bullet)
# A moving start for a bullet using physics interpolation can be done
# by resetting, *then* offsetting the position in the direction of travel.
# This means that on the first tick the bullet will be moving rather than
# standing still, as standing still on the first tick can look unnatural.
bullet.reset_physics_interpolation()
bullet.position -= bul_dir * (1.0 - Engine.get_physics_interpolation_fraction())
# If we pressed reset, or went too far from the origin, move back to the origin.
if Input.is_action_just_pressed(&"reset_position") or position.length() > 10.0:
position = Vector3(0, 1, 0)
velocity = Vector3()
reset_physics_interpolation()
_yaw = 0.0
_pitch = 0.0
$Rig.rotation = Vector3(0, _yaw, 0)
if Input.is_action_just_pressed(&"jump") and is_on_floor():
velocity.y += JUMP_VELOCITY
# We update our camera every frame.
# Our camera is not physics interpolated, as we want fast response from the mouse.
# However in the case of first-person and third-person views, the position is indirectly
# inherited from physics-interpolated player, so we get nice smooth motion while still
# having quick mouse response.
_update_camera(delta)
# When physics interpolation is active on the node,
# you should move it on the physics tick (physics_process)
# rather than on the frame (process).
func _physics_process(delta: float) -> void:
var move := Vector3()
# Calculate movement relative to the player's coordinate system.
var input: Vector2 = Input.get_vector(&"move_left", &"move_right", &"move_forward", &"move_backward") * MOVE_SPEED
move.x = input.x
move.z = input.y
# Apply gravity.
move.y -= gravity * delta
# Apply mouse rotation to the move, so that it is now in global space.
move = move.rotated(Vector3(0, 1, 0), _yaw)
# Apply the global space move to the physics.
velocity += move
move_and_slide()
# Apply friction to horizontal motion in a tick rate-independent manner.
var friction_delta := exp(-FRICTION * delta)
velocity = Vector3(velocity.x * friction_delta, velocity.y, velocity.z * friction_delta)

View File

@@ -0,0 +1 @@
uid://cusp3a7wm67ss

View File

@@ -0,0 +1,133 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Physics Interpolation"
config/description="This demo showcases physics interpolation in 3D with varying camera modes
(first person, third person, fixed perspective). This is also known as fixed timestep interpolation."
run/main_scene="uid://bj5w87j8wwnsl"
config/features=PackedStringArray("4.5", "GL Compatibility")
config/icon="res://icon.svg"
[debug]
gdscript/warnings/untyped_declaration=1
[display]
window/stretch/mode="canvas_items"
window/stretch/aspect="expand"
[input]
ui_accept={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194309,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194310,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
ui_left={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
, 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)
]
}
ui_right={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
, 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)
]
}
ui_up={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
, null, 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)
]
}
ui_down={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
, 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)
]
}
jump={
"deadzone": 0.2,
"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)
, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
fire={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(56, 19),"global_position":Vector2(65, 67),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
move_forward={
"deadzone": 0.2,
"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":122,"location":0,"echo":false,"script":null)
, 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":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
move_backward={
"deadzone": 0.2,
"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)
, 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":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
move_left={
"deadzone": 0.2,
"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":113,"location":0,"echo":false,"script":null)
, 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":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
move_right={
"deadzone": 0.2,
"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)
, 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":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
reset_position={
"deadzone": 0.2,
"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":82,"physical_keycode":0,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null)
]
}
cycle_camera_type={
"deadzone": 0.2,
"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":4194306,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
toggle_physics_interpolation={
"deadzone": 0.2,
"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":84,"physical_keycode":0,"key_label":0,"unicode":116,"location":0,"echo":false,"script":null)
]
}
[physics]
common/physics_ticks_per_second=20
3d/physics_engine="Jolt Physics"
3d/default_gravity=20.0
common/physics_interpolation=true
[rendering]
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=4
textures/default_filters/anisotropic_filtering_level=4
anti_aliasing/quality/msaa_3d=2

View File

@@ -0,0 +1,141 @@
[gd_scene load_steps=15 format=3 uid="uid://bj5w87j8wwnsl"]
[ext_resource type="Script" uid="uid://cusp3a7wm67ss" path="res://player.gd" id="1_pq8q7"]
[ext_resource type="PackedScene" uid="uid://cvgxw8nq67xxm" path="res://box.tscn" id="2_pyidc"]
[ext_resource type="PackedScene" uid="uid://dtuq8cdwg46ti" path="res://wall.tscn" id="3_vvh5c"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_vvh5c"]
[sub_resource type="Sky" id="Sky_28aoi"]
sky_material = SubResource("ProceduralSkyMaterial_vvh5c")
[sub_resource type="Environment" id="Environment_vvh5c"]
background_mode = 2
sky = SubResource("Sky_28aoi")
ambient_light_source = 2
ambient_light_color = Color(1, 1, 1, 1)
ambient_light_energy = 0.3
tonemap_mode = 4
glow_enabled = true
glow_hdr_threshold = 0.7
[sub_resource type="CylinderShape3D" id="CylinderShape3D_vvh5c"]
[sub_resource type="CylinderMesh" id="CylinderMesh_vvh5c"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_pq8q7"]
albedo_color = Color(1, 0, 0, 1)
[sub_resource type="PrismMesh" id="PrismMesh_pq8q7"]
size = Vector3(1, 1, 0.01)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_pyidc"]
transparency = 1
no_depth_test = true
albedo_color = Color(1, 1, 0, 0.501961)
[sub_resource type="BoxMesh" id="BoxMesh_vho56"]
size = Vector3(10, 0.2, 10)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vvh5c"]
albedo_color = Color(0.178458, 0.199519, 0.338574, 1)
[sub_resource type="BoxShape3D" id="BoxShape3D_vvh5c"]
size = Vector3(10, 1, 10)
[node name="Root" type="Node3D"]
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_vvh5c")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.258819, 0.616341, -0.743732, 0, 0.769968, 0.638083, 0.965926, -0.165148, 0.199282, 0, 6.24965, 0)
shadow_enabled = true
shadow_normal_bias = 2.7
directional_shadow_mode = 0
directional_shadow_fade_start = 1.0
directional_shadow_max_distance = 15.0
[node name="Player" type="CharacterBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.24778, 0)
script = ExtResource("1_pq8q7")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Player"]
shape = SubResource("CylinderShape3D_vvh5c")
[node name="Rig" type="Node3D" parent="Player"]
physics_interpolation_mode = 2
[node name="Mesh_Body" type="MeshInstance3D" parent="Player/Rig"]
mesh = SubResource("CylinderMesh_vvh5c")
skeleton = NodePath("../..")
surface_material_override/0 = SubResource("StandardMaterial3D_pq8q7")
[node name="Camera_TPS" type="Camera3D" parent="Player/Rig"]
transform = Transform3D(1, 0, 0, 0, 0.819152, 0.573576, 0, -0.573576, 0.819152, 0, 1.72429, 2.14884)
[node name="Head" type="Node3D" parent="Player/Rig"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.12412, 0)
[node name="Camera_FPS" type="Camera3D" parent="Player/Rig/Head"]
current = true
[node name="Mesh_Head" type="MeshInstance3D" parent="Player/Rig/Head"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, -0.5)
mesh = SubResource("PrismMesh_pq8q7")
skeleton = NodePath("../..")
surface_material_override/0 = SubResource("StandardMaterial3D_pyidc")
[node name="Fire_Origin" type="Node3D" parent="Player/Rig/Head"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.60726)
[node name="Camera_Fixed" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.788161, 0.615469, 0, -0.615469, 0.788161, 0, 4.94837, 5.75259)
[node name="Background" type="Node3D" parent="."]
[node name="Floor" type="MeshInstance3D" parent="Background"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.1, 0)
mesh = SubResource("BoxMesh_vho56")
skeleton = NodePath("../..")
surface_material_override/0 = SubResource("StandardMaterial3D_vvh5c")
[node name="StaticBody3D" type="StaticBody3D" parent="Background/Floor"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="Background/Floor/StaticBody3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.4, 0)
shape = SubResource("BoxShape3D_vvh5c")
[node name="Box" parent="Background" instance=ExtResource("2_pyidc")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.596531, 2.19581)
can_sleep = false
[node name="Wall" parent="Background" instance=ExtResource("3_vvh5c")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 5)
[node name="Wall2" parent="Background" instance=ExtResource("3_vvh5c")]
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, -5)
[node name="Wall3" parent="Background" instance=ExtResource("3_vvh5c")]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 5, 0, 0)
[node name="Wall4" parent="Background" instance=ExtResource("3_vvh5c")]
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -5, 0, 0)
[node name="Label" type="Label" parent="."]
self_modulate = Color(1, 1, 1, 0.627451)
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 24.0
offset_top = -151.0
offset_right = 181.0
offset_bottom = -24.0
grow_vertical = 0
theme_override_constants/outline_size = 5
text = "WASD - Move
Space - Jump
Left Mouse - Fire
Tab - Toggle Camera
R - Reset Player
T - Toggle Physics Interpolation"

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

View File

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b70s43gn8c3kx"
path="res://.godot/imported/spark_particle.png-c360d6960fdef6ea0e055d81cca0d9a7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://spark_particle.png"
dest_files=["res://.godot/imported/spark_particle.png-c360d6960fdef6ea0e055d81cca0d9a7.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@@ -0,0 +1,21 @@
[gd_scene load_steps=4 format=3 uid="uid://dtuq8cdwg46ti"]
[sub_resource type="BoxShape3D" id="BoxShape3D_pq8q7"]
size = Vector3(10.2, 1, 0.2)
[sub_resource type="BoxMesh" id="BoxMesh_pyidc"]
size = Vector3(10.2, 1, 0.2)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_oh6kn"]
albedo_color = Color(0.3204, 0.72, 0.072, 1)
[node name="Wall" type="StaticBody3D"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
shape = SubResource("BoxShape3D_pq8q7")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
mesh = SubResource("BoxMesh_pyidc")
surface_material_override/0 = SubResource("StandardMaterial3D_oh6kn")