mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2025-12-15 13:00:07 +01:00
Merge pull request #1223 from Calinou/add-3d-physics-interpolation-demo
Add 3D physics interpolation demo
This commit is contained in:
4
3d/physics_interpolation/.editorconfig
Normal file
4
3d/physics_interpolation/.editorconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
25
3d/physics_interpolation/README.md
Normal file
25
3d/physics_interpolation/README.md
Normal 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
|
||||
|
||||

|
||||
18
3d/physics_interpolation/box.tscn
Normal file
18
3d/physics_interpolation/box.tscn
Normal 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")
|
||||
27
3d/physics_interpolation/bullet.gd
Normal file
27
3d/physics_interpolation/bullet.gd
Normal 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()
|
||||
1
3d/physics_interpolation/bullet.gd.uid
Normal file
1
3d/physics_interpolation/bullet.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dohdjr8ilotkr
|
||||
86
3d/physics_interpolation/bullet.tscn
Normal file
86
3d/physics_interpolation/bullet.tscn
Normal 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"]
|
||||
41
3d/physics_interpolation/icon.png.import
Normal file
41
3d/physics_interpolation/icon.png.import
Normal 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
|
||||
1
3d/physics_interpolation/icon.svg
Normal file
1
3d/physics_interpolation/icon.svg
Normal 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 |
43
3d/physics_interpolation/icon.svg.import
Normal file
43
3d/physics_interpolation/icon.svg.import
Normal 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
|
||||
202
3d/physics_interpolation/player.gd
Normal file
202
3d/physics_interpolation/player.gd
Normal 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)
|
||||
1
3d/physics_interpolation/player.gd.uid
Normal file
1
3d/physics_interpolation/player.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cusp3a7wm67ss
|
||||
133
3d/physics_interpolation/project.godot
Normal file
133
3d/physics_interpolation/project.godot
Normal 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
|
||||
141
3d/physics_interpolation/root.tscn
Normal file
141
3d/physics_interpolation/root.tscn
Normal 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"
|
||||
0
3d/physics_interpolation/screenshots/.gdignore
Normal file
0
3d/physics_interpolation/screenshots/.gdignore
Normal file
BIN
3d/physics_interpolation/screenshots/physics_interpolation.webp
Normal file
BIN
3d/physics_interpolation/screenshots/physics_interpolation.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 164 KiB |
BIN
3d/physics_interpolation/spark_particle.png
Normal file
BIN
3d/physics_interpolation/spark_particle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 211 B |
40
3d/physics_interpolation/spark_particle.png.import
Normal file
40
3d/physics_interpolation/spark_particle.png.import
Normal 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
|
||||
21
3d/physics_interpolation/wall.tscn
Normal file
21
3d/physics_interpolation/wall.tscn
Normal 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")
|
||||
Reference in New Issue
Block a user