Merge pull request #690 from godotengine/master

Merge the `master` branch into the `4.0-dev` branch
This commit is contained in:
Aaron Franke
2022-03-26 15:19:30 -05:00
committed by GitHub
119 changed files with 6000 additions and 246 deletions

View File

@@ -1,8 +1,7 @@
<!--
Only submit a pull request if all of the following conditions are met:
* It must work with the latest stable Godot version. Do not submit a
pull request if it only works with alpha/beta builds.
* It must work with the latest Godot version of the branch you're submitting to.
* It must follow all of the Godot style guides, including the GDScript
style guide and the C# style guide.

View File

@@ -2,15 +2,16 @@
</ul>
<h2>Unavailable demos</h2>
<ul>
<li><code>2d/hdr/</code>: Not supported on HTML5 yet.
<li><code>3d/voxel/</code>: Not supported on HTML5 yet.
<li><code>audio/device_changer/</code>: Not supported on HTML5 due to browser limitations.
<li><code>loading/background_load/</code>: Not supported on HTML5 yet.
<li><code>loading/multiple_threads_loading/</code>: Not supported on HTML5 yet.
<li><code>loading/threads/</code>: Not supported on HTML5 yet.
<li><code>misc/matrix_transform/</code>: Results are only visible in the editor.
<li><code>mobile/android_iap/</code>: Only relevant on native Android.
<li><code>mobile/sensors/</code>: Not supported on HTML5 yet.
<li><code>2d/hdr/</code>: Not supported on HTML5 yet.</li>
<li><code>3d/global_illumination/</code>: Not supported on HTML5 yet (freezes the browser).</li>
<li><code>3d/voxel/</code>: Not supported on HTML5 yet.</li>
<li><code>audio/device_changer/</code>: Not supported on HTML5 due to browser limitations.</li>
<li><code>loading/background_load/</code>: Not supported on HTML5 yet.</li>
<li><code>loading/multiple_threads_loading/</code>: Not supported on HTML5 yet.</li>
<li><code>loading/threads/</code>: Not supported on HTML5 yet.</li>
<li><code>misc/matrix_transform/</code>: Results are only visible in the editor.</li>
<li><code>mobile/android_iap/</code>: Only relevant on native Android.</li>
<li><code>mobile/sensors/</code>: Not supported on HTML5 yet.</li>
<li><code>mono/*/</code>: Not available yet (requires Mono-enabled HTML5 build).</li>
<li><code>networking/*/</code>: Doesn't make sense to be hosted on a static host, as the server must be hosted on the same origin due to the browser's same-origin policy.</li>
<li><code>plugins/*/</code>: Only effective within the editor.</li>

View File

@@ -15,7 +15,7 @@ jobs:
image: barichello/godot-ci:3.3.3
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup
run: |
@@ -31,6 +31,7 @@ jobs:
# Remember to update `.github/dist/footer.html` when updating the list of excluded demos.
rm -rf \
2d/hdr/ \
3d/global_illumination/ \
3d/voxel/ \
audio/device_changer/ \
loading/background_load/ \

View File

@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install dependencies
run: |

1
.gitignore vendored
View File

@@ -18,4 +18,5 @@ mono_crash.*.json
# System/tool-specific ignores
.directory
.DS_Store
*~

View File

@@ -5,4 +5,4 @@ These demos are all 2D, but otherwise do not have a common theme.
Languages: Most have GDScript, some have
[GDSL](https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/shading_language.html)
Renderers: 6 of them are GLES 3, but most are GLES 2
Renderers: 4 of them are GLES 3, but most are GLES 2

View File

@@ -12,7 +12,7 @@ size = 64
font_data = ExtResource( 2 )
[sub_resource type="InputEventAction" id=3]
action = "ui_select"
action = "start_game"
[sub_resource type="ShortCut" id=4]
shortcut = SubResource( 3 )
@@ -50,6 +50,9 @@ margin_bottom = -100.0
custom_fonts/font = SubResource( 2 )
shortcut = SubResource( 4 )
text = "Start"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MessageTimer" type="Timer" parent="."]
one_shot = true

View File

@@ -26,14 +26,13 @@ func new_game():
func _on_MobTimer_timeout():
# Create a new instance of the Mob scene.
var mob = mob_scene.instance()
# Choose a random location on Path2D.
var mob_spawn_location = get_node("MobPath/MobSpawnLocation")
mob_spawn_location.offset = randi()
# Create a Mob instance and add it to the scene.
var mob = mob_scene.instance()
add_child(mob)
# Set the mob's direction perpendicular to the path direction.
var direction = mob_spawn_location.rotation + PI / 2
@@ -48,6 +47,8 @@ func _on_MobTimer_timeout():
var velocity = Vector2(rand_range(150.0, 250.0), 0.0)
mob.linear_velocity = velocity.rotated(direction)
# Spawn the mob by adding it to the Main scene.
add_child(mob)
func _on_ScoreTimer_timeout():
score += 1

View File

@@ -20,6 +20,9 @@ mob_scene = ExtResource( 2 )
anchor_right = 1.0
anchor_bottom = 1.0
color = Color( 0.219608, 0.372549, 0.380392, 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Player" parent="." instance=ExtResource( 3 )]

View File

@@ -4,7 +4,7 @@ This is a simple game where your character must move
and avoid the enemies for as long as possible.
This is a finished version of the game featured in the
["Your first game"](https://docs.godotengine.org/en/latest/getting_started/step_by_step/your_first_game.html)
["Your first 2D game"](https://docs.godotengine.org/en/latest/getting_started/first_2d_game/index.html)
tutorial in the documentation. For more details,
consider following the tutorial in the documentation.

View File

@@ -14,7 +14,7 @@ config/name="Dodge the Creeps"
config/description="This is a simple game where your character must move
and avoid the enemies for as long as possible.
This is a finished version of the game featured in the 'Your first game'
This is a finished version of the game featured in the 'Your first 2D game'
tutorial in the documentation. For more details, consider
following the tutorial in the documentation."
run/main_scene="res://Main.tscn"
@@ -61,3 +61,8 @@ move_down={
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
]
}
start_game={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777221,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}

View File

@@ -9,7 +9,7 @@ manual modification of the RigidBody velocity.
Language: GDScript
Renderer: GLES 3 (particles are not available in GLES 2)
Renderer: GLES 2
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/119

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=12 format=2]
[gd_scene load_steps=10 format=2]
[ext_resource path="res://coin/coin.gd" type="Script" id=1]
[ext_resource path="res://coin/coin.png" type="Texture" id=2]
@@ -97,21 +97,6 @@ blend_mode = 1
[sub_resource type="Curve" id=5]
[sub_resource type="CurveTexture" id=6]
curve = SubResource( 5 )
[sub_resource type="ParticlesMaterial" id=7]
emission_shape = 1
emission_sphere_radius = 20.0
flag_disable_z = true
gravity = Vector3( 0, 0, 0 )
initial_velocity = 1.0
angular_velocity = 0.0191222
orbit_velocity = 0.0
orbit_velocity_random = 0.0
scale = 0.3
scale_curve = SubResource( 6 )
[node name="Coin" type="Area2D"]
script = ExtResource( 1 )
@@ -130,14 +115,20 @@ shape = SubResource( 3 )
[node name="Sound" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource( 3 )
[node name="Particles" type="Particles2D" parent="."]
[node name="Particles" type="CPUParticles2D" parent="."]
modulate = Color( 0.596863, 0.638745, 1, 1 )
material = SubResource( 4 )
emitting = false
one_shot = true
explosiveness = 0.7
process_material = SubResource( 7 )
texture = ExtResource( 4 )
emission_shape = 1
emission_sphere_radius = 20.0
gravity = Vector2( 0, 0 )
initial_velocity = 1.0
angular_velocity = 0.0191222
scale_amount = 0.3
scale_amount_curve = SubResource( 5 )
[node name="Enabler" type="VisibilityEnabler2D" parent="."]
rect = Rect2( -5, -5, 10, 10 )

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=14 format=2]
[gd_scene load_steps=12 format=2]
[ext_resource path="res://enemy/enemy.gd" type="Script" id=1]
[ext_resource path="res://enemy/enemy.png" type="Texture" id=2]
@@ -106,23 +106,6 @@ radius = 7.0
offsets = PoolRealArray( 0.5, 1 )
colors = PoolColorArray( 1, 1, 1, 0.501961, 0, 0, 0, 0 )
[sub_resource type="GradientTexture" id=7]
gradient = SubResource( 6 )
[sub_resource type="ParticlesMaterial" id=8]
emission_shape = 1
emission_sphere_radius = 8.0
flag_disable_z = true
spread = 180.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 120.0
initial_velocity_random = 0.5
orbit_velocity = 0.0
orbit_velocity_random = 0.0
angle_random = 1.0
scale_random = 1.0
color_ramp = SubResource( 7 )
[node name="Enemy" type="RigidBody2D"]
mode = 2
physics_material_override = SubResource( 1 )
@@ -166,7 +149,7 @@ position = Vector2( 11, -4.672 )
enabled = true
cast_to = Vector2( 0, 22.5 )
[node name="Explosion" type="Particles2D" parent="."]
[node name="Explosion" type="CPUParticles2D" parent="."]
modulate = Color( 1, 1, 1, 0.685843 )
emitting = false
amount = 32
@@ -174,8 +157,16 @@ lifetime = 0.5
one_shot = true
speed_scale = 1.2
explosiveness = 0.76
process_material = SubResource( 8 )
texture = ExtResource( 3 )
emission_shape = 1
emission_sphere_radius = 8.0
spread = 180.0
gravity = Vector2( 0, 0 )
initial_velocity = 120.0
initial_velocity_random = 0.5
angle_random = 1.0
scale_amount_random = 1.0
color_ramp = SubResource( 6 )
[node name="SoundHit" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource( 4 )

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=7 format=2]
[gd_scene load_steps=6 format=2]
[ext_resource path="res://player/bullet.gd" type="Script" id=1]
[ext_resource path="res://player/bullet.png" type="Texture" id=2]
@@ -6,20 +6,10 @@
[sub_resource type="CanvasItemMaterial" id=1]
blend_mode = 1
[sub_resource type="ParticlesMaterial" id=2]
flag_disable_z = true
spread = 0.0
gravity = Vector3( 0, 0, 0 )
initial_velocity = 1.0
angular_velocity = 38.0
orbit_velocity = 0.0
orbit_velocity_random = 0.0
scale = 0.8
[sub_resource type="CircleShape2D" id=3]
[sub_resource type="CircleShape2D" id=2]
radius = 4.5
[sub_resource type="Animation" id=4]
[sub_resource type="Animation" id=3]
length = 1.5
tracks/0/type = "method"
tracks/0/path = NodePath(".")
@@ -64,24 +54,29 @@ tracks/2/keys = {
continuous_cd = 2
script = ExtResource( 1 )
[node name="Particles2D" type="Particles2D" parent="."]
[node name="Particles2D" type="CPUParticles2D" parent="."]
material = SubResource( 1 )
emitting = false
lifetime = 0.3
speed_scale = 3.0
local_coords = false
process_material = SubResource( 2 )
texture = ExtResource( 2 )
spread = 0.0
gravity = Vector2( 0, 0 )
initial_velocity = 1.0
angular_velocity = 38.0
scale_amount = 0.8
[node name="Sprite" type="Sprite" parent="."]
texture = ExtResource( 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 3 )
shape = SubResource( 2 )
[node name="Timer" type="Timer" parent="."]
one_shot = true
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
anims/shutdown = SubResource( 4 )
anims/shutdown = SubResource( 3 )
[connection signal="timeout" from="Timer" to="." method="disable"]

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=25 format=2]
[gd_scene load_steps=23 format=2]
[ext_resource path="res://player/player.gd" type="Script" id=1]
[ext_resource path="res://player/robot_demo.png" type="Texture" id=2]
@@ -16,22 +16,7 @@ friction = 0.0
[sub_resource type="Gradient" id=2]
colors = PoolColorArray( 0.708353, 0.72498, 1, 1, 1, 1, 1, 0 )
[sub_resource type="GradientTexture" id=3]
gradient = SubResource( 2 )
[sub_resource type="ParticlesMaterial" id=4]
flag_disable_z = true
spread = 65.84
gravity = Vector3( 0, -15, 0 )
initial_velocity = 10.14
angular_velocity = 200.0
angular_velocity_random = 1.0
orbit_velocity = 0.0
orbit_velocity_random = 0.0
linear_accel = 100.0
color_ramp = SubResource( 3 )
[sub_resource type="Animation" id=5]
[sub_resource type="Animation" id=3]
length = 0.01
loop = true
step = 0.25
@@ -48,7 +33,7 @@ tracks/0/keys = {
"values": [ 22 ]
}
[sub_resource type="Animation" id=6]
[sub_resource type="Animation" id=4]
length = 0.01
loop = true
step = 0.25
@@ -65,7 +50,7 @@ tracks/0/keys = {
"values": [ 21 ]
}
[sub_resource type="Animation" id=7]
[sub_resource type="Animation" id=5]
length = 0.5
loop = true
step = 0.25
@@ -82,7 +67,7 @@ tracks/0/keys = {
"values": [ 26 ]
}
[sub_resource type="Animation" id=8]
[sub_resource type="Animation" id=6]
length = 7.0
loop = true
step = 0.25
@@ -99,7 +84,7 @@ tracks/0/keys = {
"values": [ 16, 17, 18, 16, 19, 20, 19, 16 ]
}
[sub_resource type="Animation" id=9]
[sub_resource type="Animation" id=7]
length = 0.5
loop = true
step = 0.25
@@ -116,7 +101,7 @@ tracks/0/keys = {
"values": [ 25 ]
}
[sub_resource type="Animation" id=10]
[sub_resource type="Animation" id=8]
length = 0.5
loop = true
step = 0.25
@@ -133,7 +118,7 @@ tracks/0/keys = {
"values": [ 23, 24, 23 ]
}
[sub_resource type="Animation" id=11]
[sub_resource type="Animation" id=9]
length = 0.5
loop = true
step = 0.25
@@ -150,7 +135,7 @@ tracks/0/keys = {
"values": [ 26 ]
}
[sub_resource type="Animation" id=12]
[sub_resource type="Animation" id=10]
length = 1.25
loop = true
step = 0.25
@@ -167,7 +152,7 @@ tracks/0/keys = {
"values": [ 0, 1, 2, 3, 4, 0 ]
}
[sub_resource type="Animation" id=13]
[sub_resource type="Animation" id=11]
length = 1.25
loop = true
step = 0.25
@@ -184,7 +169,7 @@ tracks/0/keys = {
"values": [ 5, 6, 7, 8, 9, 5 ]
}
[sub_resource type="Animation" id=14]
[sub_resource type="Animation" id=12]
length = 1.25
loop = true
step = 0.25
@@ -201,7 +186,7 @@ tracks/0/keys = {
"values": [ 10, 11, 12, 13, 14, 5 ]
}
[sub_resource type="RayShape2D" id=15]
[sub_resource type="RayShape2D" id=13]
custom_solver_bias = 0.5
length = 18.0
@@ -218,7 +203,7 @@ texture = ExtResource( 2 )
hframes = 16
vframes = 2
[node name="Smoke" type="Particles2D" parent="Sprite"]
[node name="Smoke" type="CPUParticles2D" parent="Sprite"]
self_modulate = Color( 1, 1, 1, 0.26702 )
position = Vector2( 10, 1.5 )
rotation = -1.45648
@@ -227,20 +212,26 @@ lifetime = 0.3
one_shot = true
explosiveness = 1.0
local_coords = false
process_material = SubResource( 4 )
texture = ExtResource( 3 )
spread = 65.84
gravity = Vector2( 0, -15 )
initial_velocity = 10.14
angular_velocity = 200.0
angular_velocity_random = 1.0
linear_accel = 100.0
color_ramp = SubResource( 2 )
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
anims/crouch = SubResource( 5 )
anims/falling = SubResource( 6 )
anims/falling_weapon = SubResource( 7 )
anims/idle = SubResource( 8 )
anims/idle_weapon = SubResource( 9 )
anims/jumping = SubResource( 10 )
anims/jumping_weapon = SubResource( 11 )
anims/run = SubResource( 12 )
anims/run_weapon = SubResource( 13 )
anims/standing_weapon_ready = SubResource( 14 )
anims/crouch = SubResource( 3 )
anims/falling = SubResource( 4 )
anims/falling_weapon = SubResource( 5 )
anims/idle = SubResource( 6 )
anims/idle_weapon = SubResource( 7 )
anims/jumping = SubResource( 8 )
anims/jumping_weapon = SubResource( 9 )
anims/run = SubResource( 10 )
anims/run_weapon = SubResource( 11 )
anims/standing_weapon_ready = SubResource( 12 )
[node name="Camera" type="Camera2D" parent="."]
current = true
@@ -253,7 +244,7 @@ position = Vector2( 15, 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2( 0.15, -6 )
shape = SubResource( 15 )
shape = SubResource( 13 )
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
polygon = PoolVector2Array( -0.138, 8.25, -10, -12, 11, -12 )

View File

@@ -66,7 +66,7 @@ window/size/width=800
window/size/height=480
window/dpi/allow_hidpi=true
window/stretch/mode="2d"
window/stretch/aspect="keep"
window/stretch/aspect="keep_height"
[gdnative]
@@ -154,6 +154,7 @@ mipmap_policy=1
[rendering]
quality/driver/driver_name="GLES2"
quality/intended_usage/framebuffer_allocation=0
quality/intended_usage/framebuffer_allocation.mobile=1
2d/snapping/use_gpu_pixel_snap=true

View File

@@ -17,7 +17,7 @@ they contain a lot of comments that explain how each class works.
Language: GDScript
Renderer: GLES 3 (particles are not available in GLES 2)
Renderer: GLES 2
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/120

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -28,6 +28,7 @@ process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false

View File

@@ -240,6 +240,7 @@ mipmap_policy=1
[rendering]
quality/driver/driver_name="GLES2"
quality/intended_usage/framebuffer_allocation=0
quality/intended_usage/framebuffer_allocation.mobile=1
2d/snapping/use_gpu_pixel_snap=true

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=15 format=2]
[gd_scene load_steps=13 format=2]
[ext_resource path="res://assets/art/player/bullet/bullet.png" type="Texture" id=1]
[ext_resource path="res://assets/audio/sfx/explode.wav" type="AudioStream" id=2]
@@ -179,26 +179,6 @@ blend_mode = 1
offsets = PoolRealArray( 0.5, 1 )
colors = PoolColorArray( 1, 1, 1, 1, 0, 0, 0, 1 )
[sub_resource type="GradientTexture" id=8]
gradient = SubResource( 7 )
width = 256
[sub_resource type="ParticlesMaterial" id=9]
emission_shape = 1
emission_sphere_radius = 8.0
flag_disable_z = true
spread = 180.0
gravity = Vector3( 0, 250, 0 )
initial_velocity = 120.0
initial_velocity_random = 0.5
orbit_velocity = 0.0
orbit_velocity_random = 0.0
angle_random = 1.0
scale_random = 1.0
color_ramp = SubResource( 8 )
hue_variation = 0.05
hue_variation_random = 0.46
[node name="Enemy" type="KinematicBody2D"]
collision_layer = 2
collision_mask = 24
@@ -239,7 +219,7 @@ anims/walk = SubResource( 4 )
rotation = -1.5708
shape = SubResource( 5 )
[node name="Explosion" type="Particles2D" parent="."]
[node name="Explosion" type="CPUParticles2D" parent="."]
self_modulate = Color( 1, 1, 1, 0.12 )
material = SubResource( 6 )
emitting = false
@@ -249,8 +229,18 @@ one_shot = true
speed_scale = 1.2
explosiveness = 0.76
draw_order = 215832976
process_material = SubResource( 9 )
texture = ExtResource( 1 )
emission_shape = 1
emission_sphere_radius = 8.0
spread = 180.0
gravity = Vector2( 0, 250 )
initial_velocity = 120.0
initial_velocity_random = 0.5
angle_random = 1.0
scale_amount_random = 1.0
color_ramp = SubResource( 7 )
hue_variation = 0.05
hue_variation_random = 0.46
[node name="Hit" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource( 3 )

View File

@@ -22,4 +22,5 @@ func shoot(direction = 1):
bullet.set_as_toplevel(true)
add_child(bullet)
sound_shoot.play()
timer.start()
return true

View File

@@ -22,10 +22,14 @@ func _ready():
var camera: Camera2D = $Camera
if action_suffix == "_p1":
camera.custom_viewport = $"../.."
yield(get_tree(), "idle_frame")
camera.make_current()
elif action_suffix == "_p2":
var viewport: Viewport = $"../../../../ViewportContainer2/Viewport"
var viewport: Viewport = $"../../../../ViewportContainer2/Viewport2"
viewport.world_2d = ($"../.." as Viewport).world_2d
camera.custom_viewport = viewport
yield(get_tree(), "idle_frame")
camera.make_current()
# Physics process is a built-in loop in Godot.

View File

@@ -40,7 +40,7 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="Viewport" type="Viewport" parent="Black/SplitContainer/ViewportContainer1"]
[node name="Viewport1" type="Viewport" parent="Black/SplitContainer/ViewportContainer1"]
size = Vector2( 394, 480 )
size_override_stretch = true
handle_input_locally = false
@@ -48,13 +48,13 @@ usage = 0
render_target_update_mode = 3
audio_listener_enable_2d = true
[node name="Level" parent="Black/SplitContainer/ViewportContainer1/Viewport" instance=ExtResource( 3 )]
[node name="Level" parent="Black/SplitContainer/ViewportContainer1/Viewport1" instance=ExtResource( 3 )]
[node name="Player1" parent="Black/SplitContainer/ViewportContainer1/Viewport/Level" instance=ExtResource( 4 )]
[node name="Player1" parent="Black/SplitContainer/ViewportContainer1/Viewport1/Level" instance=ExtResource( 4 )]
position = Vector2( 90, 546 )
action_suffix = "_p1"
[node name="Player2" parent="Black/SplitContainer/ViewportContainer1/Viewport/Level" instance=ExtResource( 4 )]
[node name="Player2" parent="Black/SplitContainer/ViewportContainer1/Viewport1/Level" instance=ExtResource( 4 )]
position = Vector2( 120, 546 )
action_suffix = "_p2"
@@ -69,7 +69,7 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="Viewport" type="Viewport" parent="Black/SplitContainer/ViewportContainer2"]
[node name="Viewport2" type="Viewport" parent="Black/SplitContainer/ViewportContainer2"]
size = Vector2( 394, 480 )
size_override_stretch = true
handle_input_locally = false
@@ -77,4 +77,4 @@ usage = 0
render_target_update_mode = 3
audio_listener_enable_2d = true
[node name="ParallaxBackground" parent="Black/SplitContainer/ViewportContainer2/Viewport" instance=ExtResource( 5 )]
[node name="ParallaxBackground" parent="Black/SplitContainer/ViewportContainer2/Viewport2" instance=ExtResource( 5 )]

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=9 format=2]
[gd_scene load_steps=8 format=2]
[ext_resource path="res://assets/art/player/bullet/bullet.png" type="Texture" id=1]
[ext_resource path="res://src/Objects/Bullet.gd" type="Script" id=2]
@@ -8,21 +8,12 @@
[sub_resource type="CanvasItemMaterial" id=2]
blend_mode = 1
[sub_resource type="ParticlesMaterial" id=3]
flag_disable_z = true
spread = 0.0
gravity = Vector3( 0, 0, 0 )
orbit_velocity = 0.0
orbit_velocity_random = 0.0
scale = 0.8
color = Color( 1, 1, 1, 0.705882 )
[sub_resource type="CanvasItemMaterial" id=3]
[sub_resource type="CanvasItemMaterial" id=4]
[sub_resource type="CircleShape2D" id=5]
[sub_resource type="CircleShape2D" id=4]
radius = 4.5
[sub_resource type="Animation" id=6]
[sub_resource type="Animation" id=5]
resource_name = "destroy"
length = 0.3
tracks/0/type = "method"
@@ -73,27 +64,31 @@ contacts_reported = 1
contact_monitor = true
script = ExtResource( 2 )
[node name="Particles2D" type="Particles2D" parent="."]
[node name="Particles2D" type="CPUParticles2D" parent="."]
material = SubResource( 2 )
emitting = false
lifetime = 0.3
speed_scale = 3.0
local_coords = false
process_material = SubResource( 3 )
texture = ExtResource( 1 )
spread = 0.0
gravity = Vector2( 0, 0 )
scale_amount = 0.8
color = Color( 1, 1, 1, 0.705882 )
[node name="Sprite" type="Sprite" parent="."]
material = SubResource( 4 )
material = SubResource( 3 )
texture = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 5 )
shape = SubResource( 4 )
[node name="Timer" type="Timer" parent="."]
one_shot = true
autostart = true
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
anims/destroy = SubResource( 6 )
anims/destroy = SubResource( 5 )
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
[connection signal="timeout" from="Timer" to="." method="destroy"]

View File

@@ -12,7 +12,7 @@ func _ready():
anim_sprite.play()
# Check if the game is in splitscreen mode by checking the scene root name.
if get_tree().get_root().get_child(0).name == "Splitscreen":
var _level_node = get_node(@"../../../../Black/SplitContainer/ViewportContainer1/Viewport/Level")
var _level_node = get_node(@"../../../../Black/SplitContainer/ViewportContainer1/Viewport1/Level")
_level_node.get_node("Player1").connect("collect_coin", self, "_collect_coin")
_level_node.get_node("Player2").connect("collect_coin", self, "_collect_coin")
else:

View File

@@ -0,0 +1,51 @@
# Global Illumination
This demo showcases Godot's global illumination systems:
[GIProbe](https://docs.godotengine.org/en/stable/tutorials/3d/gi_probes.html),
[BakedLightmap](https://docs.godotengine.org/en/stable/tutorials/3d/baked_lightmaps.html)
(indirect only and fully baked) and
[ReflectionProbe](https://docs.godotengine.org/en/stable/tutorials/3d/reflection_probes.html).
Use the mouse to look around, <kbd>W</kbd>/<kbd>A</kbd>/<kbd>S</kbd>/<kbd>D</kbd>
or arrow keys to move.
Language: GDScript
Renderer: GLES 3[^1]
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/1290
## How does it work?
A glTF scene (which acts as the level mesh) is imported with its **Light Baking**
option set to **Gen Lightmaps**.
This is required for BakedLightmap to work (but is not required for GIProbe
or BakedLightmap).
The level mesh is duplicated several times to allow displaying it with various bake settings:
- No baking (uses GIProbe or environment lighting).
- Baked indirect lighting. Slower, but allows for real-time shadows to display
on baked surfaces.
- Baked direct *and* indirect lighting. Faster, but does not allow for real-time
shadows to display on baked surfaces.
A sphere and box are parented to the camera to showcase dynamic object lighting.
A ReflectionProbe is parented to the sphere to showcase real-time reflections.
When the ReflectionProbe is hidden, it is disabled. In this case,
GIProbe or environment lighting will be used to provide fallback reflections.
## Screenshots
![Screenshot](screenshots/global_illumination.png)
## Licenses
`zdm2.glb` is derived from the [Cube 2: Sauerbraten](http://sauerbraten.org/)
map "zdm2" and is
[licensed under CC BY 4.0 Unported](https://github.com/Calinou/game-maps-obj/blob/master/sauerbraten/zdm2.txt).
The OBJ file which it was converted from is available in the [game-maps-obj](https://github.com/Calinou/game-maps-obj) repository.
[^1]: This demo can be made to work with GLES2, but GIProbe will not work.
Additionally, lightmaps have to be rebaked with the **Atlas > Generate** property
disabled in BakedLightmap.

View File

@@ -0,0 +1,43 @@
extends Camera
const MOUSE_SENSITIVITY = 0.002
const MOVE_SPEED = 1.5
var rot = Vector3()
var velocity = Vector3()
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
# Mouse look (only if the mouse is captured).
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
# Horizontal mouse look.
rot.y -= event.relative.x * MOUSE_SENSITIVITY
# Vertical mouse look.
rot.x = clamp(rot.x - event.relative.y * MOUSE_SENSITIVITY, -1.57, 1.57)
transform.basis = Basis(rot)
if event.is_action_pressed("toggle_mouse_capture"):
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _process(delta):
var motion = Vector3(
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
0,
Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
)
# Normalize motion to prevent diagonal movement from being
# `sqrt(2)` times faster than straight movement.
motion = motion.normalized()
velocity += MOVE_SPEED * delta * transform.basis.xform(motion)
velocity *= 0.85
translation += velocity

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,13 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
sky_energy = 0.2
ground_energy = 0.0
[resource]
background_mode = 2
background_sky = SubResource( 1 )
fog_sun_amount = 1.0
fog_depth_begin = 0.0
tonemap_mode = 2
tonemap_white = 6.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@@ -0,0 +1,73 @@
; 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=4
[application]
config/name="Global Illumination"
run/main_scene="res://test.tscn"
config/icon="res://icon.png"
[display]
window/dpi/allow_hidpi=true
window/stretch/mode="2d"
window/stretch/aspect="expand"
[input]
cycle_gi_mode={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
toggle_reflection_probe={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
move_forward={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":87,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777232,"unicode":0,"echo":false,"script":null)
]
}
move_back={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":83,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777234,"unicode":0,"echo":false,"script":null)
]
}
move_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":65,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777231,"unicode":0,"echo":false,"script":null)
]
}
move_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":68,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777233,"unicode":0,"echo":false,"script":null)
]
}
toggle_mouse_capture={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777253,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":16777217,"unicode":0,"echo":false,"script":null)
]
}
[physics]
common/enable_pause_aware_picking=true
[rendering]
quality/shadows/filter_mode=2
environment/default_environment="res://default_env.tres"

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

View File

@@ -0,0 +1,25 @@
[remap]
importer="texture_array"
type="TextureArray"
path="res://.import/test.exr-c2074adc031b4eb62ef608033f6d937a.texarr"
metadata={
"vram_texture": false
}
[deps]
source_file="res://test.exr"
dest_files=[ "res://.import/test.exr-c2074adc031b4eb62ef608033f6d937a.texarr" ]
[params]
compress/mode=0
compress/no_bptc_if_rgb=false
flags/repeat=false
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=false
slices/horizontal=1
slices/vertical=1

View File

@@ -0,0 +1,114 @@
extends Spatial
enum GIMode {
NONE,
BAKED_LIGHTMAP_ALL,
BAKED_LIGHTMAP_INDIRECT,
GI_PROBE,
MAX, # Maximum value of the enum, used internally.
}
# Keep this in sync with the GIMode enum (except for MAX).
const GI_MODE_TEXTS = [
"Environment Lighting (Fastest)",
"Baked Lightmap All (Fast)",
"Baked Lightmap Indirect (Average)",
"GIProbe (Slow)",
]
var gi_mode = GIMode.NONE
var use_reflection_probe = false
onready var gi_mode_label = $GIMode
onready var reflection_probe_mode_label = $ReflectionProbeMode
onready var reflection_probe = $Camera/ReflectiveSphere/ReflectionProbe
func _ready():
set_gi_mode(GIMode.NONE)
set_use_reflection_probe(false)
func _input(event):
if event.is_action_pressed("cycle_gi_mode"):
set_gi_mode(wrapi(gi_mode + 1, 0, GIMode.MAX))
if event.is_action_pressed("toggle_reflection_probe"):
set_use_reflection_probe(not use_reflection_probe)
func set_gi_mode(p_gi_mode):
gi_mode = p_gi_mode
gi_mode_label.text = "Current GI mode: %s " % GI_MODE_TEXTS[gi_mode]
match p_gi_mode:
GIMode.NONE:
$ZdmBakeIndirect.visible = false
$ZdmBakeAll.visible = false
$ZdmNoBake.visible = true
$BakedLightmapIndirect.visible = false
$BakedLightmapAll.visible = false
$GIProbe.visible = false
# There is no difference between Indirect and Disabled when no GI is used.
# Pick the default value (which is Indirect).
$Sun.light_bake_mode = Light.BAKE_INDIRECT
$GrateOmniLight.light_bake_mode = Light.BAKE_INDIRECT
$GarageOmniLight.light_bake_mode = Light.BAKE_INDIRECT
$CornerSpotLight.light_bake_mode = Light.BAKE_INDIRECT
GIMode.BAKED_LIGHTMAP_ALL:
$ZdmBakeIndirect.visible = false
$ZdmBakeAll.visible = true
$ZdmNoBake.visible = false
$BakedLightmapIndirect.visible = false
$BakedLightmapAll.visible = true
$GIProbe.visible = false
# Make lights not affect baked surfaces by setting their bake mode to All.
$Sun.light_bake_mode = Light.BAKE_ALL
$GrateOmniLight.light_bake_mode = Light.BAKE_ALL
$GarageOmniLight.light_bake_mode = Light.BAKE_ALL
$CornerSpotLight.light_bake_mode = Light.BAKE_ALL
GIMode.BAKED_LIGHTMAP_INDIRECT:
$ZdmBakeIndirect.visible = true
$ZdmBakeAll.visible = false
$ZdmNoBake.visible = false
$BakedLightmapIndirect.visible = true
$BakedLightmapAll.visible = false
$GIProbe.visible = false
$Sun.light_bake_mode = Light.BAKE_INDIRECT
$GrateOmniLight.light_bake_mode = Light.BAKE_INDIRECT
$GarageOmniLight.light_bake_mode = Light.BAKE_INDIRECT
$CornerSpotLight.light_bake_mode = Light.BAKE_INDIRECT
GIMode.GI_PROBE:
$ZdmBakeIndirect.visible = false
$ZdmBakeAll.visible = false
$ZdmNoBake.visible = true
$BakedLightmapIndirect.visible = false
$BakedLightmapAll.visible = false
$GIProbe.visible = true
# Bake mode must be Indirect, not Disabled. Otherwise, GI will
# not be visible for those lights.
# Moving/blinking lights should generally have their bake mode set to Disabled
# to avoid visible GI pop-ins. This is because GIProbe
# can take a while to update.
$Sun.light_bake_mode = Light.BAKE_INDIRECT
$GrateOmniLight.light_bake_mode = Light.BAKE_INDIRECT
$GarageOmniLight.light_bake_mode = Light.BAKE_INDIRECT
$CornerSpotLight.light_bake_mode = Light.BAKE_INDIRECT
func set_use_reflection_probe(p_visible):
use_reflection_probe = p_visible
if p_visible:
reflection_probe_mode_label.text = "Current reflection probe mode: Enabled - Using reflection probe (Average)"
else:
reflection_probe_mode_label.text = "Current reflection probe mode: Disabled - Using environment or GIProbe reflections (Fast)"
reflection_probe.visible = p_visible

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -0,0 +1,25 @@
[remap]
importer="texture_array"
type="TextureArray"
path="res://.import/test_all.exr-20e3b4b8c4ad01c2073fdca1a38f60ed.texarr"
metadata={
"vram_texture": false
}
[deps]
source_file="res://test_all.exr"
dest_files=[ "res://.import/test_all.exr-20e3b4b8c4ad01c2073fdca1a38f60ed.texarr" ]
[params]
compress/mode=0
compress/no_bptc_if_rgb=false
flags/repeat=false
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=false
slices/horizontal=1
slices/vertical=1

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -15,6 +15,7 @@ texture_size = 0
[resource]
background_mode = 2
background_sky = SubResource( 1 )
ambient_light_energy = 5.0
tonemap_mode = 2
tonemap_white = 6.0
ssao_blur = 1

View File

@@ -1,9 +1,8 @@
[gd_scene load_steps=10 format=2]
[gd_scene load_steps=9 format=2]
[ext_resource path="res://cubelib.tres" type="MeshLibrary" id=1]
[ext_resource path="res://player/cubio.tscn" type="PackedScene" id=2]
[ext_resource path="res://models/cube.mesh" type="ArrayMesh" id=3]
[ext_resource path="res://gi_probe_data.res" type="GIProbeData" id=4]
[ext_resource path="res://models/mushroom.glb" type="PackedScene" id=5]
[sub_resource type="BoxShape" id=1]
@@ -60,12 +59,6 @@ __meta__ = {
"_editor_floor_": Vector3( 0, 12, 0 )
}
[node name="GIProbe" type="GIProbe" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 4 )
extents = Vector3( 8, 8, 10 )
propagation = 1.0
data = ExtResource( 4 )
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( -0.173649, 0.806707, -0.564863, 0, 0.573576, 0.819152, 0.984808, 0.142244, -0.0996007, 0, 0, 0 )
light_energy = 1.3

View File

@@ -0,0 +1,25 @@
# RigidBody Character 3D
RigidBody character demo for 3D using a capsule for the character.
Cubes as RigidBodies spawn in the map from above to show interaction
with the player (jump on them, gently push them), which would be
impossible with a KinematicBody.
Language: GDScript
Renderer: GLES 3
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/1291
## How does it work?
This demo uses a [`RigidBody`](https://docs.godotengine.org/en/stable/classes/class_rigidbody.html)
for the player, and [`StaticBody`](https://docs.godotengine.org/en/latest/classes/class_staticbody.html)
for the level. Each has colliders, the player moves itself via
`apply_central_impulse()` in `_physics_process()`, and collides with the level.
## Screenshots
![Screenshot](screenshots/ingame.png)
![Screenshot](screenshots/editor.png)

View File

@@ -0,0 +1,25 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://models/white_wood.png" type="Texture" id=1]
[sub_resource type="BoxShape" id=1]
extents = Vector3( 0.5, 0.5, 0.5 )
[sub_resource type="SpatialMaterial" id=3]
resource_name = "Material"
albedo_color = Color( 0.917647, 0.384314, 0.0823529, 1 )
albedo_texture = ExtResource( 1 )
roughness = 0.75
[sub_resource type="CubeMesh" id=2]
material = SubResource( 3 )
size = Vector3( 1, 1, 1 )
[node name="cube_rigidbody" type="RigidBody"]
[node name="CollisionShape" type="CollisionShape" parent="."]
shape = SubResource( 1 )
[node name="MeshInstance" type="MeshInstance" parent="."]
mesh = SubResource( 2 )
material/0 = null

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,25 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
radiance_size = 1
sky_top_color = Color( 0.219882, 0.193725, 0.366471, 1 )
sky_horizon_color = Color( 0.342622, 0.0655002, 0.558935, 1 )
sky_curve = 0.0490365
ground_bottom_color = Color( 0.0342205, 0.0333383, 0.0322154, 1 )
ground_horizon_color = Color( 0.148289, 0.138067, 0.125119, 1 )
ground_curve = 0.25
sun_latitude = 55.0
sun_longitude = -80.0
texture_size = 0
[resource]
background_mode = 2
background_sky = SubResource( 1 )
tonemap_mode = 2
tonemap_white = 6.0
ssao_blur = 1
glow_levels/7 = true
glow_strength = 0.79
glow_bloom = 1.0
glow_blend_mode = 0
glow_bicubic_upscale = true

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@@ -0,0 +1,9 @@
extends Spatial
# Random spawn of Rigidbody cubes.
func _on_SpawnTimer_timeout():
var new_rb = preload("res://cube_rigidbody.tscn").instance()
new_rb.translation.y = 15
new_rb.translation.x = rand_range(-5, 5)
new_rb.translation.z = rand_range(-5, 5)
add_child(new_rb)

View File

@@ -0,0 +1,128 @@
[gd_scene load_steps=11 format=2]
[ext_resource path="res://cubelib.tres" type="MeshLibrary" id=1]
[ext_resource path="res://player/cubio.tscn" type="PackedScene" id=2]
[ext_resource path="res://models/cube.mesh" type="ArrayMesh" id=3]
[ext_resource path="res://models/mushroom.glb" type="PackedScene" id=5]
[ext_resource path="res://level.gd" type="Script" id=6]
[ext_resource path="res://cube_rigidbody.tscn" type="PackedScene" id=7]
[sub_resource type="BoxShape" id=1]
margin = 0.001
extents = Vector3( 0.5, 0.5, 0.5 )
[sub_resource type="Animation" id=2]
length = 10.0
loop = true
tracks/0/type = "value"
tracks/0/path = NodePath(".:translation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 1, 4, 6, 9, 10 ),
"transitions": PoolRealArray( 1, -2, 1, -2, 1, 1 ),
"update": 0,
"values": [ Vector3( 0.5, 4.5, -2.5 ), Vector3( 0.5, 4.5, -2.5 ), Vector3( 0.5, 8.5, -2.5 ), Vector3( 0.5, 8.5, -2.5 ), Vector3( 0.5, 4.5, -2.5 ), Vector3( 0.5, 4.5, -2.5 ) ]
}
[sub_resource type="Animation" id=3]
length = 10.0
loop = true
tracks/0/type = "value"
tracks/0/path = NodePath(".:translation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 2, 4.5, 6, 9 ),
"transitions": PoolRealArray( 1, -2, 1, -2, 1 ),
"update": 0,
"values": [ Vector3( -3.5, 8.5, 4.5 ), Vector3( -3.5, 8.5, 4.5 ), Vector3( 3.5, 8.5, 4.5 ), Vector3( 3.5, 8.5, 4.5 ), Vector3( -3.5, 8.5, 4.5 ) ]
}
[sub_resource type="BoxShape" id=4]
[node name="World" type="Spatial"]
script = ExtResource( 6 )
__meta__ = {
"__editor_plugin_screen__": "3D"
}
[node name="GridMap" type="GridMap" parent="."]
mesh_library = ExtResource( 1 )
cell_size = Vector3( 1, 1, 1 )
data = {
"cells": PoolIntArray( 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0, 65530, 0, 0, 65531, 0, 0, 65532, 0, 0, 65533, 0, 0, 65534, 0, 0, 65535, 0, 0, 196603, 0, 0, 196604, 0, 0, 524292, 0, 0, 589820, 0, 0, 786432, 0, 0, 851967, 0, 0, 0, 1, 0, 1, 1, 0, 2, 1, 0, 3, 1, 0, 4, 1, 0, 65530, 1, 0, 65531, 1, 0, 65532, 1, 0, 65533, 1, 0, 65534, 1, 0, 65535, 1, 0, 131075, 1, 0, 196603, 1, 0, 196604, 1, 0, 524292, 1, 0, 589820, 1, 0, 786432, 1, 0, 851967, 1, 0, 0, 2, 0, 1, 2, 0, 2, 2, 0, 3, 2, 0, 4, 2, 0, 65530, 2, 0, 65531, 2, 0, 65532, 2, 0, 65533, 2, 0, 65534, 2, 0, 65535, 2, 0, 131075, 2, 0, 196603, 2, 0, 196604, 2, 0, 524292, 2, 0, 589820, 2, 0, 786432, 2, 0, 786433, 2, 0, 851966, 2, 0, 851967, 2, 0, 0, 3, 0, 1, 3, 0, 2, 3, 0, 3, 3, 0, 4, 3, 0, 65530, 3, 0, 65531, 3, 0, 65532, 3, 0, 65533, 3, 0, 65534, 3, 0, 65535, 3, 0, 196603, 3, 0, 524291, 3, 0, 524292, 3, 0, 589820, 3, 0, 786432, 3, 0, 786433, 3, 0, 851966, 3, 0, 851967, 3, 0, 0, 4, 0, 1, 4, 0, 2, 4, 0, 3, 4, 0, 4, 4, 0, 65530, 4, 0, 65531, 4, 0, 65532, 4, 0, 65533, 4, 0, 65534, 4, 0, 65535, 4, 0, 196603, 4, 0, 0, 5, 0, 1, 5, 0, 2, 5, 0, 3, 5, 0, 4, 5, 0, 65530, 5, 0, 65531, 5, 0, 65532, 5, 0, 65533, 5, 0, 65534, 5, 0, 65535, 5, 0, 131075, 5, 0, 0, 6, 0, 1, 6, 0, 2, 6, 0, 3, 6, 0, 4, 6, 0, 65530, 6, 0, 65531, 6, 0, 65532, 6, 0, 65533, 6, 0, 65534, 6, 0, 65535, 6, 0, 131075, 6, 0, 196603, 6, 0, 0, 7, 0, 1, 7, 0, 2, 7, 0, 3, 7, 0, 4, 7, 0, 65530, 7, 0, 65531, 7, 0, 65532, 7, 0, 65533, 7, 0, 65534, 7, 0, 65535, 7, 0, 131075, 7, 0, 196603, 7, 0, 0, 8, 0, 1, 8, 0, 2, 8, 0, 3, 8, 0, 4, 8, 0, 65530, 8, 0, 65531, 8, 0, 65532, 8, 0, 65533, 8, 0, 65534, 8, 0, 65535, 8, 0, 131075, 8, 0, 196603, 8, 0, 196604, 8, 0, 0, 9, 0, 1, 9, 0, 2, 9, 0, 3, 9, 0, 4, 9, 0, 65530, 9, 0, 65531, 9, 0, 65532, 9, 0, 65533, 9, 0, 65534, 9, 0, 65535, 9, 0, 131073, 9, 0, 131074, 9, 0, 131075, 9, 0, 196603, 9, 0, 196604, 9, 0, 196605, 9, 0, 196608, 9, 0, 262142, 9, 0, 0, 10, 0, 1, 10, 0, 2, 10, 0, 3, 10, 0, 4, 10, 0, 65530, 10, 0, 65531, 10, 0, 65532, 10, 0, 65533, 10, 0, 65534, 10, 0, 65535, 10, 0, 0, 11, 0, 1, 11, 0, 2, 11, 0, 3, 11, 0, 4, 11, 0, 65530, 11, 0, 65531, 11, 0, 65532, 11, 0, 65533, 11, 0, 65534, 11, 0, 65535, 11, 0, 0, 65532, 0, 1, 65532, 0, 2, 65532, 0, 3, 65532, 0, 4, 65532, 0, 65530, 65532, 0, 65531, 65532, 0, 65532, 65532, 0, 65533, 65532, 0, 65534, 65532, 0, 65535, 65532, 0, 0, 65533, 0, 1, 65533, 0, 2, 65533, 0, 3, 65533, 0, 4, 65533, 0, 65530, 65533, 0, 65531, 65533, 0, 65532, 65533, 0, 65533, 65533, 0, 65534, 65533, 0, 65535, 65533, 0, 262145, 65533, 0, 262146, 65533, 0, 262147, 65533, 0, 589822, 65533, 0, 589823, 65533, 0, 655363, 65533, 0, 655364, 65533, 0, 720897, 65533, 0, 720898, 65533, 0, 786432, 65533, 0, 851967, 65533, 0, 0, 65534, 0, 1, 65534, 0, 2, 65534, 0, 3, 65534, 0, 4, 65534, 0, 65530, 65534, 0, 65531, 65534, 0, 65532, 65534, 0, 65533, 65534, 0, 65534, 65534, 0, 65535, 65534, 0, 65536, 65534, 0, 131071, 65534, 0, 196603, 65534, 0, 196604, 65534, 0, 196605, 65534, 0, 196606, 65534, 0, 196607, 65534, 0, 589822, 65534, 0, 589828, 65534, 0, 786432, 65534, 0, 851967, 65534, 0, 0, 65535, 0, 1, 65535, 0, 2, 65535, 0, 3, 65535, 0, 4, 65535, 0, 65530, 65535, 0, 65531, 65535, 0, 65532, 65535, 0, 65533, 65535, 0, 65534, 65535, 0, 65535, 65535, 0, 196603, 65535, 0, 196604, 65535, 0, 196611, 65535, 0, 589820, 65535, 0, 589821, 65535, 0, 589822, 65535, 0, 589828, 65535, 0, 786432, 65535, 0, 851967, 65535, 0 )
}
__meta__ = {
"_editor_clip_": 0,
"_editor_floor_": Vector3( 0, 12, 0 )
}
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( -0.173649, 0.806707, -0.564863, 0, 0.573576, 0.819152, 0.984808, 0.142244, -0.0996007, 0, 0, 0 )
light_energy = 1.3
shadow_enabled = true
shadow_bias = -0.02
shadow_reverse_cull_face = true
directional_shadow_mode = 0
directional_shadow_normal_bias = 0.0
directional_shadow_bias_split_scale = 0.0
directional_shadow_max_distance = 20.0
[node name="Cubio" parent="." instance=ExtResource( 2 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -1.5, 2, 4 )
[node name="Elevator1" type="KinematicBody" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 4.5, -2.5 )
input_capture_on_drag = true
[node name="Mesh" type="MeshInstance" parent="Elevator1"]
mesh = ExtResource( 3 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="Elevator1"]
shape = SubResource( 1 )
[node name="AnimationPlayer" type="AnimationPlayer" parent="Elevator1"]
autoplay = "updown1"
playback_process_mode = 0
anims/updown1 = SubResource( 2 )
[node name="Elevator2" type="KinematicBody" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -3.5, 8.5, 4.5 )
[node name="Mesh" type="MeshInstance" parent="Elevator2"]
mesh = ExtResource( 3 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="Elevator2"]
shape = SubResource( 1 )
[node name="AnimationPlayer" type="AnimationPlayer" parent="Elevator2"]
autoplay = "side"
playback_process_mode = 0
anims/side = SubResource( 3 )
anims/updown1 = SubResource( 2 )
[node name="Princess" type="Area" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 13.25, 3 )
[node name="Mushroom" parent="Princess" instance=ExtResource( 5 )]
[node name="CollisionShape" type="CollisionShape" parent="Princess"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0 )
shape = SubResource( 4 )
[node name="SpawnTimer" type="Timer" parent="."]
wait_time = 2.0
autostart = true
[node name="cube_rigidbody" parent="." instance=ExtResource( 7 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.416964, 3.3565, 2.6332 )
[connection signal="body_entered" from="Princess" to="Cubio" method="_on_tcube_body_entered"]
[connection signal="timeout" from="SpawnTimer" to="." method="_on_SpawnTimer_timeout"]

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,9 @@
[gd_resource type="SpatialMaterial" load_steps=2 format=2]
[ext_resource path="res://models/white_wood.png" type="Texture" id=1]
[resource]
resource_name = "Material"
albedo_color = Color( 0.5, 0.25, 1, 1 )
albedo_texture = ExtResource( 1 )
roughness = 0.75

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
[gd_resource type="SpatialMaterial" load_steps=2 format=2]
[ext_resource path="res://models/white_wood.png" type="Texture" id=1]
[resource]
resource_name = "Material"
albedo_texture = ExtResource( 1 )
roughness = 0.75

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

View File

@@ -0,0 +1,38 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/white_wood.png-821b7bf9b3881778c9bff1c965d8a87c.s3tc.stex"
path.etc2="res://.import/white_wood.png-821b7bf9b3881778c9bff1c965d8a87c.etc2.stex"
path.etc="res://.import/white_wood.png-821b7bf9b3881778c9bff1c965d8a87c.etc.stex"
metadata={
"imported_formats": [ "s3tc", "etc2", "etc" ],
"vram_texture": true
}
[deps]
source_file="res://models/white_wood.png"
dest_files=[ "res://.import/white_wood.png-821b7bf9b3881778c9bff1c965d8a87c.s3tc.stex", "res://.import/white_wood.png-821b7bf9b3881778c9bff1c965d8a87c.etc2.stex", "res://.import/white_wood.png-821b7bf9b3881778c9bff1c965d8a87c.etc.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=true
flags/srgb=1
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

View File

@@ -0,0 +1,39 @@
extends RigidBody
onready var raycast = $RayCast
onready var camera = $Target/Camera
onready var start_position = translation
func _physics_process(_delta):
if Input.is_action_just_pressed("exit"):
get_tree().quit()
if Input.is_action_just_pressed("reset_position"):
translation = start_position
return
var dir = Vector3()
dir.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
dir.z = Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
# Get the camera's transform basis, but remove the X rotation such
# that the Y axis is up and Z is horizontal.
var cam_basis = camera.global_transform.basis
var basis = cam_basis.rotated(cam_basis.x, -cam_basis.get_euler().x)
dir = basis.xform(dir)
apply_central_impulse(dir.normalized() / 10)
# Jumping code.
if on_ground() and Input.is_action_pressed("jump"):
apply_central_impulse(Vector3.UP)
# Test if there is a body below the player.
func on_ground():
if raycast.is_colliding():
return true
func _on_tcube_body_entered(body):
if body == self:
get_node("WinText").show()

View File

@@ -0,0 +1,64 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://player/cubio.gd" type="Script" id=1]
[ext_resource path="res://player/follow_camera.gd" type="Script" id=3]
[ext_resource path="res://models/white_cube_material.tres" type="Material" id=4]
[sub_resource type="CapsuleMesh" id=6]
radius = 0.5
mid_height = 0.7
[sub_resource type="CapsuleShape" id=5]
radius = 0.5
height = 0.7
[node name="RigidBody" type="RigidBody"]
can_sleep = false
axis_lock_angular_x = true
axis_lock_angular_y = true
axis_lock_angular_z = true
linear_damp = 0.5
script = ExtResource( 1 )
[node name="CubeMesh" type="MeshInstance" parent="."]
_import_path = NodePath("cube-col")
transform = Transform( 0.9, 0, 0, 0, -3.93403e-08, -0.9, 0, 0.9, -3.93403e-08, 0, 0, 0 )
mesh = SubResource( 6 )
skeleton = NodePath("")
material/0 = ExtResource( 4 )
[node name="CollisionShape" type="CollisionShape" parent="."]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 )
shape = SubResource( 5 )
[node name="Target" type="Spatial" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8, 0 )
[node name="Camera" type="Camera" parent="Target"]
transform = Transform( 0.34202, -0.321394, 0.883022, 0, 0.939693, 0.34202, -0.939693, -0.116978, 0.321394, 2, 0.5, 0.913381 )
fov = 74.0
near = 0.1
far = 50.0
script = ExtResource( 3 )
[node name="WinText" type="CenterContainer" parent="."]
visible = false
anchor_right = 1.0
margin_bottom = 100.0
[node name="Holder" type="Control" parent="WinText"]
margin_left = 512.0
margin_top = 50.0
margin_right = 512.0
margin_bottom = 50.0
[node name="TextLabel" type="Label" parent="WinText/Holder"]
margin_left = -354.0
margin_bottom = 14.0
rect_scale = Vector2( 2, 2 )
text = "Thank You, Cubio! But the Princess is in Another Demo!"
align = 1
valign = 1
[node name="RayCast" type="RayCast" parent="."]
enabled = true

View File

@@ -0,0 +1,41 @@
extends Camera
var collision_exception = []
export var min_distance = 0.5
export var max_distance = 3.0
export var angle_v_adjust = 0.0
var max_height = 2.0
var min_height = 0
onready var target_node: Spatial = get_parent()
func _ready():
collision_exception.append(target_node.get_parent().get_rid())
# Detaches the camera transform from the parent spatial node
set_as_toplevel(true)
func _physics_process(_delta):
var target_pos: Vector3 = target_node.global_transform.origin
var camera_pos: Vector3 = global_transform.origin
var delta_pos: Vector3 = camera_pos - target_pos
# Regular delta follow
# Check ranges
if delta_pos.length() < min_distance:
delta_pos = delta_pos.normalized() * min_distance
elif delta_pos.length() > max_distance:
delta_pos = delta_pos.normalized() * max_distance
# Check upper and lower height
delta_pos.y = clamp(delta_pos.y, min_height, max_height)
camera_pos = target_pos + delta_pos
look_at_from_position(camera_pos, target_pos, Vector3.UP)
# Turn a little up or down
var t = transform
t.basis = Basis(t.basis[0], deg2rad(angle_v_adjust)) * t.basis
transform = t

View File

@@ -0,0 +1,93 @@
; 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=4
[application]
config/name="RigidBody Character 3D"
config/description="Rigidbody character demo for 3D using a capsule for the character.
"
run/main_scene="res://level.tscn"
config/icon="res://icon.png"
[gdnative]
singletons=[ ]
[input]
jump={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
move_back={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"physical_scancode":0,"unicode":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":1,"axis_value":1.0,"script":null)
]
}
move_forward={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"physical_scancode":0,"unicode":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)
]
}
move_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"physical_scancode":0,"unicode":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)
]
}
move_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"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)
]
}
reset_position={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
]
}
exit={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"physical_scancode":0,"unicode":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)
]
}
[physics]
common/physics_fps=120
[rasterizer]
shadow_filter=3
[rendering]
quality/driver/fallback_to_gles2=true
vram_compression/import_etc=true
quality/shadows/filter_mode=2
quality/filters/anisotropic_filter_level=16
quality/filters/msaa=2
environment/default_environment="res://default_env.tres"
quality/filters/msaa.mobile=0
quality/filters/anisotropic_filter_level.mobile=4

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 KiB

View File

@@ -1,5 +1,5 @@
Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. \
Copyright (c) 2014-2021 Godot Engine contributors.
Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. \
Copyright (c) 2014-2022 Godot Engine contributors.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -6,9 +6,11 @@ be used with [Godot Engine](https://godotengine.org), the open source
## Godot versions
- The [`master`](https://github.com/godotengine/godot-demo-projects) branch is compatible with the latest stable Godot version (currently 3.4.x).
- The [`master`](https://github.com/godotengine/godot-demo-projects) branch is compatible with the latest Godot version (currently 4.0 alpha).
- If you are using an older version of Godot, use the appropriate branch for your Godot version:
- [`3.4`](https://github.com/godotengine/godot-demo-projects/tree/3.4)
branch for Godot 3.4.x.
- [`3.3`](https://github.com/godotengine/godot-demo-projects/tree/3.3)
branch for Godot 3.3.x.
- [`3.2`](https://github.com/godotengine/godot-demo-projects/tree/3.2)

View File

@@ -0,0 +1,21 @@
# MIDI Piano
This demo shows how to use
[InputEventMIDI](https://docs.godotengine.org/en/latest/classes/class_inputeventmidi.html)
by creating a piano that can be controlled by a MIDI device.
This is known to work with a Yamaha MX88.
The piano can also be controlled by clicking on the keys, or by
manually calling the activate and deactivate methods on each key.
Note that MIDI output is not yet supported in Godot, only input works.
Language: GDScript
Renderer: GLES 2
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/1292
## Screenshots
![Screenshot](screenshots/piano-pressed.png)

BIN
audio/midi_piano/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 807 B

View File

@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

97
audio/midi_piano/piano.gd Normal file
View File

@@ -0,0 +1,97 @@
extends Control
# A standard piano with 88 keys has keys from 21 to 108.
# To get a different set of keys, modify these numbers.
# A maximally extended 108-key piano goes from 12 to 119.
# A 76-key piano goes from 23 to 98, 61-key from 36 to 96,
# 49-key from 36 to 84, 37-key from 41 to 77, and 25-key
# from 48 to 72. Middle C is pitch number 60, A440 is 69.
const START_KEY = 21
const END_KEY = 108
const WhiteKeyScene = preload("res://piano_keys/white_piano_key.tscn")
const BlackKeyScene = preload("res://piano_keys/black_piano_key.tscn")
var piano_key_dict := Dictionary()
onready var white_keys = $WhiteKeys
onready var black_keys = $BlackKeys
func _ready():
# Sanity checks.
if _is_note_index_sharp(_pitch_index_to_note_index(START_KEY)):
printerr("The start key can't be a sharp note (limitation of this piano-generating algorithm). Try 21.")
return
for i in range(START_KEY, END_KEY + 1):
piano_key_dict[i] = _create_piano_key(i)
if white_keys.get_child_count() != black_keys.get_child_count():
_add_placeholder_key(black_keys)
OS.open_midi_inputs()
print(OS.get_connected_midi_inputs())
func _input(input_event):
if not (input_event is InputEventMIDI):
return
var midi_event: InputEventMIDI = input_event
if midi_event.pitch < START_KEY or midi_event.pitch > END_KEY:
# The given pitch isn't on the on-screen keyboard, so return.
return
_print_midi_info(midi_event)
var key: PianoKey = piano_key_dict[midi_event.pitch]
if midi_event.message == MIDI_MESSAGE_NOTE_ON:
key.activate()
else:
key.deactivate()
func _add_placeholder_key(container):
var placeholder = Control.new()
placeholder.size_flags_horizontal = SIZE_EXPAND_FILL
placeholder.mouse_filter = Control.MOUSE_FILTER_IGNORE
placeholder.name = "Placeholder"
container.add_child(placeholder)
func _create_piano_key(pitch_index):
var note_index = _pitch_index_to_note_index(pitch_index)
var piano_key: PianoKey
if _is_note_index_sharp(note_index):
piano_key = BlackKeyScene.instance()
black_keys.add_child(piano_key)
else:
piano_key = WhiteKeyScene.instance()
white_keys.add_child(piano_key)
if _is_note_index_lacking_sharp(note_index):
_add_placeholder_key(black_keys)
piano_key.setup(pitch_index)
return piano_key
func _is_note_index_lacking_sharp(note_index: int):
# B and E, because no B# or E#
return note_index in [2, 7]
func _is_note_index_sharp(note_index: int):
# A#, C#, D#, F#, and G#
return note_index in [1, 4, 6, 9, 11]
func _pitch_index_to_note_index(pitch: int):
pitch += 3
return pitch % 12
func _print_midi_info(midi_event: InputEventMIDI):
print(midi_event)
print("Channel: " + str(midi_event.channel))
print("Message: " + str(midi_event.message))
print("Pitch: " + str(midi_event.pitch))
print("Velocity: " + str(midi_event.velocity))
print("Instrument: " + str(midi_event.instrument))
print("Pressure: " + str(midi_event.pressure))
print("Controller number: " + str(midi_event.controller_number))
print("Controller value: " + str(midi_event.controller_value))

Some files were not shown because too many files have changed in this diff Show More