diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4709183 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Godot 4+ specific ignores +.godot/ diff --git a/Ball/Meshes/ball_bouncing.glb b/Ball/Meshes/ball_bouncing.glb new file mode 100644 index 0000000..60a6680 Binary files /dev/null and b/Ball/Meshes/ball_bouncing.glb differ diff --git a/Ball/Meshes/ball_bouncing.glb.import b/Ball/Meshes/ball_bouncing.glb.import new file mode 100644 index 0000000..b11282d --- /dev/null +++ b/Ball/Meshes/ball_bouncing.glb.import @@ -0,0 +1,39 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://lge7m41oi6pn" +path="res://.godot/imported/ball_bouncing.glb-1ac9f8098d8ec4d887838d50493ecd3b.scn" + +[deps] + +source_file="res://Ball/Meshes/ball_bouncing.glb" +dest_files=["res://.godot/imported/ball_bouncing.glb-1ac9f8098d8ec4d887838d50493ecd3b.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=false +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={ +"materials": { +"Projectile": { +"use_external/enabled": true, +"use_external/path": "res://Ball/Meshes/ball_material.tres" +} +} +} +gltf/embedded_image_handling=1 diff --git a/Ball/Meshes/ball_flying.glb b/Ball/Meshes/ball_flying.glb new file mode 100644 index 0000000..f0d6155 Binary files /dev/null and b/Ball/Meshes/ball_flying.glb differ diff --git a/Ball/Meshes/ball_flying.glb.import b/Ball/Meshes/ball_flying.glb.import new file mode 100644 index 0000000..889951c --- /dev/null +++ b/Ball/Meshes/ball_flying.glb.import @@ -0,0 +1,39 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://b1embyb2knvho" +path="res://.godot/imported/ball_flying.glb-2e72ac9d7b4b8b2e6357f34d6db76d73.scn" + +[deps] + +source_file="res://Ball/Meshes/ball_flying.glb" +dest_files=["res://.godot/imported/ball_flying.glb-2e72ac9d7b4b8b2e6357f34d6db76d73.scn"] + +[params] + +nodes/root_type="Node3D" +nodes/root_name="Scene Root" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +skins/use_named_skins=true +animation/import=false +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +import_script/path="" +_subresources={ +"materials": { +"Projectile": { +"use_external/enabled": true, +"use_external/path": "res://Ball/Meshes/ball_material.tres" +} +} +} +gltf/embedded_image_handling=1 diff --git a/Ball/Meshes/ball_material.tres b/Ball/Meshes/ball_material.tres new file mode 100644 index 0000000..176674e --- /dev/null +++ b/Ball/Meshes/ball_material.tres @@ -0,0 +1,11 @@ +[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://ccktnp41cys0r"] + +[ext_resource type="Shader" path="res://Ball/Meshes/ball_shader.gdshader" id="1_kfvtm"] +[ext_resource type="Texture2D" uid="uid://7xvwnxdwlypg" path="res://Misc/matcap_wobbly.png" id="2_o5lk5"] + +[resource] +render_priority = 0 +shader = ExtResource("1_kfvtm") +shader_parameter/intensity = 1.0 +shader_parameter/color = Color(0.333333, 0.545098, 0.976471, 0.862745) +shader_parameter/matcap = ExtResource("2_o5lk5") diff --git a/Ball/Meshes/ball_shader.gdshader b/Ball/Meshes/ball_shader.gdshader new file mode 100644 index 0000000..fa6b558 --- /dev/null +++ b/Ball/Meshes/ball_shader.gdshader @@ -0,0 +1,18 @@ +/* + MatCap Shader by Firerabbit + + MIT License +*/ + +shader_type spatial; + +uniform sampler2D matcap : source_color, hint_default_black; +uniform float intensity : hint_range(0.0,1.0) = 1.0; +uniform vec4 color : source_color = vec4(1.0); + +void fragment() { + vec2 matcap_uv = (NORMAL.xy * vec2(0.5, -0.5) + vec2(0.5, 0.5)); + ALBEDO = color.rgb; + ALBEDO *= mix(vec3(1.0), texture(matcap, matcap_uv).rgb, intensity); + ALPHA = color.a; +} \ No newline at end of file diff --git a/Ball/Meshes/ball_visual_shader.tres b/Ball/Meshes/ball_visual_shader.tres new file mode 100644 index 0000000..8b469b4 --- /dev/null +++ b/Ball/Meshes/ball_visual_shader.tres @@ -0,0 +1,63 @@ +[gd_resource type="VisualShader" load_steps=9 format=3 uid="uid://ny01m62ohegv"] + +[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_sbl4o"] +operator = 8 + +[sub_resource type="VisualShaderNodeVectorCompose" id="VisualShaderNodeVectorCompose_7ys52"] +default_input_values = [0, 0.0, 1, 0.0, 2, 1.0] + +[sub_resource type="VisualShaderNodeVectorDecompose" id="VisualShaderNodeVectorDecompose_o0c6e"] +default_input_values = [0, Vector2(0, 0)] +op_type = 0 + +[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_5rytf"] +input_name = "screen_uv" + +[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_nwrdd"] +default_input_values = [0, Vector2(0, 0), 1, Vector2(0.5, 0.5)] +op_type = 0 +operator = 1 + +[sub_resource type="VisualShaderNodeVectorFunc" id="VisualShaderNodeVectorFunc_711ug"] + +[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_fou4c"] +input_name = "normal" + +[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_2wva2"] +operator = 2 + +[resource] +code = "shader_type spatial; +render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_lambert, specular_schlick_ggx; + + + + +void fragment() { +// Input:7 + vec3 n_out7p0 = NORMAL; + + +// Output:0 + ALBEDO = n_out7p0; + + +} +" +nodes/fragment/3/node = SubResource("VisualShaderNodeInput_5rytf") +nodes/fragment/3/position = Vector2(-1780, 340) +nodes/fragment/5/node = SubResource("VisualShaderNodeVectorOp_nwrdd") +nodes/fragment/5/position = Vector2(-1480, 400) +nodes/fragment/6/node = SubResource("VisualShaderNodeVectorFunc_711ug") +nodes/fragment/6/position = Vector2(-920, 400) +nodes/fragment/7/node = SubResource("VisualShaderNodeInput_fou4c") +nodes/fragment/7/position = Vector2(-880, 200) +nodes/fragment/9/node = SubResource("VisualShaderNodeVectorOp_2wva2") +nodes/fragment/9/position = Vector2(-400, 200) +nodes/fragment/10/node = SubResource("VisualShaderNodeVectorOp_sbl4o") +nodes/fragment/10/position = Vector2(-200, 260) +nodes/fragment/11/node = SubResource("VisualShaderNodeVectorCompose_7ys52") +nodes/fragment/11/position = Vector2(-1120, 400) +nodes/fragment/12/node = SubResource("VisualShaderNodeVectorDecompose_o0c6e") +nodes/fragment/12/position = Vector2(-1320, 400) +nodes/fragment/connections = PackedInt32Array(3, 0, 5, 0, 7, 0, 9, 0, 9, 0, 10, 0, 6, 0, 10, 1, 5, 0, 11, 0, 5, 0, 12, 0, 12, 1, 11, 1, 11, 0, 6, 0, 3, 0, 9, 1, 7, 0, 0, 0) diff --git a/Ball/bal42CA.tmp b/Ball/bal42CA.tmp new file mode 100644 index 0000000..5062c96 --- /dev/null +++ b/Ball/bal42CA.tmp @@ -0,0 +1,35 @@ +[gd_scene load_steps=5 format=3 uid="uid://rdlvlyf0l1l"] + +[ext_resource type="Script" path="res://Ball/ball.gd" id="1_oenn5"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_b4pqe"] +size = Vector3(0.5, 0.5, 0.5) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tdblm"] +albedo_color = Color(0.117647, 0.427451, 0.611765, 1) +roughness = 0.42 + +[sub_resource type="SphereMesh" id="SphereMesh_mq1q1"] +radius = 0.3 +height = 0.6 + +[node name="Ball" type="RigidBody3D"] +collision_layer = 4 +custom_integrator = true +max_contacts_reported = 1 +contact_monitor = true +can_sleep = false +lock_rotation = true +linear_damp_mode = 1 +angular_damp_mode = 1 +script = ExtResource("1_oenn5") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("BoxShape3D_b4pqe") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +material_override = SubResource("StandardMaterial3D_tdblm") +mesh = SubResource("SphereMesh_mq1q1") + +[node name="TimerCollision" type="Timer" parent="."] +one_shot = true diff --git a/Ball/bal6D7B.tmp b/Ball/bal6D7B.tmp new file mode 100644 index 0000000..cb6271f --- /dev/null +++ b/Ball/bal6D7B.tmp @@ -0,0 +1,36 @@ +[gd_scene load_steps=6 format=3 uid="uid://rdlvlyf0l1l"] + +[ext_resource type="Script" path="res://Ball/ball.gd" id="1_oenn5"] +[ext_resource type="PackedScene" uid="uid://lge7m41oi6pn" path="res://Ball/Meshes/ball_bouncing.glb" id="2_ccq7m"] +[ext_resource type="PackedScene" uid="uid://b1embyb2knvho" path="res://Ball/Meshes/ball_flying.glb" id="4_fh5j8"] +[ext_resource type="Script" path="res://Ball/ball_meshes.gd" id="4_llldm"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_ogc07"] +radius = 0.3 + +[node name="Ball" type="RigidBody3D"] +collision_layer = 4 +custom_integrator = true +max_contacts_reported = 1 +contact_monitor = true +can_sleep = false +lock_rotation = true +linear_damp_mode = 1 +angular_damp_mode = 1 +script = ExtResource("1_oenn5") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("SphereShape3D_ogc07") + +[node name="TimerCollision" type="Timer" parent="."] +one_shot = true + +[node name="Meshes" type="Node3D" parent="."] +script = ExtResource("4_llldm") + +[node name="BallBouncingMesh" parent="Meshes" instance=ExtResource("2_ccq7m")] +visible = false + +[node name="BallFlyingMesh" parent="Meshes" instance=ExtResource("4_fh5j8")] + +[node name="RotationNode" type="Node3D" parent="Meshes"] diff --git a/Ball/balA3FF.tmp b/Ball/balA3FF.tmp new file mode 100644 index 0000000..b7febdb --- /dev/null +++ b/Ball/balA3FF.tmp @@ -0,0 +1,40 @@ +[gd_scene load_steps=7 format=3 uid="uid://rdlvlyf0l1l"] + +[ext_resource type="Script" path="res://Ball/ball.gd" id="1_oenn5"] +[ext_resource type="Shader" uid="uid://ny01m62ohegv" path="res://Ball/Meshes/ball_visual_shader.tres" id="2_wbu40"] +[ext_resource type="PackedScene" uid="uid://dn8tw0i6t3701" path="res://Ball/ball_mesh_bouncing.tscn" id="3_3pvgr"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_ogc07"] +radius = 0.3 + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_qwhgq"] +render_priority = 0 +shader = ExtResource("2_wbu40") + +[sub_resource type="SphereMesh" id="SphereMesh_mq1q1"] +radius = 0.3 +height = 0.6 + +[node name="Ball" type="RigidBody3D"] +collision_layer = 4 +custom_integrator = true +max_contacts_reported = 1 +contact_monitor = true +can_sleep = false +lock_rotation = true +linear_damp_mode = 1 +angular_damp_mode = 1 +script = ExtResource("1_oenn5") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("SphereShape3D_ogc07") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +visible = false +material_override = SubResource("ShaderMaterial_qwhgq") +mesh = SubResource("SphereMesh_mq1q1") + +[node name="TimerCollision" type="Timer" parent="."] +one_shot = true + +[node name="BallBouncingMesh" parent="." instance=ExtResource("3_3pvgr")] diff --git a/Ball/ball.gd b/Ball/ball.gd new file mode 100644 index 0000000..85968f0 --- /dev/null +++ b/Ball/ball.gd @@ -0,0 +1,62 @@ +extends RigidBody3D + + +signal ball_collision_started +signal ball_collision_ended + +var captured_velocity : Vector3 +var bounced_velocity : Vector3 +var just_collided = false + +var total_bounce_duration = 0.5 +var gravity = Vector3(0, -10, 0) + + +func _physics_process(delta): + # Capture the linear velocity unless the ball have stopped on collision + if not just_collided: + captured_velocity = linear_velocity + + _get_collision(delta) + + +var collision_normal : Vector3 +var collision_angle_factor : float +func _get_collision(delta): + var collision : KinematicCollision3D + # test_only is true so this function doesn't move the ball on top of the main movement + collision = move_and_collide(linear_velocity * delta, true) + + # A collision happens + if collision: + # Get collision data stuff + collision_normal = collision.get_normal() + bounced_velocity = captured_velocity.bounce(collision_normal) + # Get the dot product between the surface normal and the ball direction on hit + collision_angle_factor = collision_normal.dot(captured_velocity.normalized() * -1) + + # Set the duration of the timer based on the collision angle + $TimerCollision.wait_time = total_bounce_duration * collision_angle_factor + $TimerCollision.start() + + # Send the signal after getting the data to avoid having zeroed values + just_collided = true + emit_signal("ball_collision_started") + + # Completely stop the ball in place + linear_velocity = Vector3.ZERO + freeze = true + + # Move the ball again after the timer runs out + # The if check prevents the timeout function from trying to connect every frame + if not $TimerCollision.timeout.is_connected(_after_collision): + $TimerCollision.timeout.connect(_after_collision) + + +func _after_collision(): + just_collided = false + emit_signal("ball_collision_ended") + + # Unfreezes the ball and apply the bounced captured velocity to it + freeze = false + linear_velocity = bounced_velocity diff --git a/Ball/ball.tscn b/Ball/ball.tscn new file mode 100644 index 0000000..5c71a40 --- /dev/null +++ b/Ball/ball.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=6 format=3 uid="uid://rdlvlyf0l1l"] + +[ext_resource type="Script" path="res://Ball/ball.gd" id="1_oenn5"] +[ext_resource type="PackedScene" uid="uid://lge7m41oi6pn" path="res://Ball/Meshes/ball_bouncing.glb" id="2_ccq7m"] +[ext_resource type="PackedScene" uid="uid://b1embyb2knvho" path="res://Ball/Meshes/ball_flying.glb" id="4_fh5j8"] +[ext_resource type="Script" path="res://Ball/ball_meshes.gd" id="4_llldm"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_ogc07"] +radius = 0.3 + +[node name="Ball" type="RigidBody3D"] +collision_layer = 4 +max_contacts_reported = 1 +contact_monitor = true +can_sleep = false +lock_rotation = true +linear_damp_mode = 1 +angular_damp_mode = 1 +script = ExtResource("1_oenn5") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("SphereShape3D_ogc07") + +[node name="TimerCollision" type="Timer" parent="."] +one_shot = true + +[node name="Meshes" type="Node3D" parent="."] +script = ExtResource("4_llldm") + +[node name="RotationNode" type="Node3D" parent="Meshes"] + +[node name="BallBouncingMesh" parent="Meshes" instance=ExtResource("2_ccq7m")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.3) +visible = false + +[node name="BallFlyingMesh" parent="Meshes" instance=ExtResource("4_fh5j8")] diff --git a/Ball/ball_mesh_bouncing.tscn b/Ball/ball_mesh_bouncing.tscn new file mode 100644 index 0000000..1ec041b --- /dev/null +++ b/Ball/ball_mesh_bouncing.tscn @@ -0,0 +1,5 @@ +[gd_scene load_steps=2 format=3 uid="uid://8svturwvd3cx"] + +[ext_resource type="PackedScene" uid="uid://lge7m41oi6pn" path="res://Ball/Meshes/ball_bouncing.glb" id="1_gs32o"] + +[node name="BallBouncingMesh" instance=ExtResource("1_gs32o")] diff --git a/Ball/ball_meshes.gd b/Ball/ball_meshes.gd new file mode 100644 index 0000000..3805acb --- /dev/null +++ b/Ball/ball_meshes.gd @@ -0,0 +1,77 @@ +extends Node3D + + +@onready var skeleton_flying = $BallFlyingMesh.get_node("SKL_projectile_flying/Skeleton3D") +@onready var skeleton_bouncing = $BallBouncingMesh.get_node("SKL_projectile_bouncing/Skeleton3D") +@onready var ball = owner +@onready var timer = ball.get_node("TimerCollision") + +var is_bouncing = false +var max_squish_xy = 0.5 # Starts at 0 +var max_squish_z = 0.8 # From 0 to 1 + +# Apply a small offset to the up vector in the look_at function to fix it +# not working when the target is perfectly aligned with the up vector +const LOOK_AT_OFFSET_FIX = Vector3(0.01, 1, 0.01) + + +func _ready(): + ball.ball_collision_started.connect(_on_collision) + ball.ball_collision_ended.connect(_after_collision) + + +func _process(delta): + _align_mesh_to_direction() + _squish_animation() + + +func _align_mesh_to_direction(): + # Align the RotationNode to the movement direction + $RotationNode.look_at(ball.captured_velocity + ball.global_position, LOOK_AT_OFFSET_FIX) + + # Convert the rotation euler into a quaternion + var euler_rotation = $RotationNode.rotation + var quaternion_rotation : Quaternion + quaternion_rotation = quaternion_rotation.from_euler(euler_rotation) + + # Rotate the bone + skeleton_flying.set_bone_pose_rotation(1, quaternion_rotation) + + +func _on_collision(): + $BallFlyingMesh.visible = false + $BallBouncingMesh.visible = true + is_bouncing = true + + # Align the Meshes node to the surface normal so the bouncing mesh is properly aligned + look_at(ball.collision_normal + ball.global_position, LOOK_AT_OFFSET_FIX) + + +func _after_collision(): + $BallFlyingMesh.visible = true + $BallBouncingMesh.visible = false + is_bouncing = false + + # Reset the Meshes node rotation + rotation = Vector3.ZERO + + +func _squish_animation(): + if is_bouncing: + # Remap the time_left value of the timer + var time_left_remap = remap(timer.time_left, timer.wait_time, 0, 0, 2) + var time_left_pingpong = pingpong(time_left_remap, 1) + + # Multiply the scaling by the collision angle factor to reduce + # the squishing effect at shallow angles + var scale_xy_factor = 1.0 + (ball.collision_angle_factor * max_squish_xy) + var scale_xy = 1.0 * remap(time_left_pingpong, 0, 1, 1, scale_xy_factor) + var scale_z_factor = 1.0 - (ball.collision_angle_factor * max_squish_z) + var scale_z = 1.0 * remap(time_left_pingpong, 0, 1, 1, scale_z_factor) + + # Compose the vector for the bone scaling + var scale_squish_vector = Vector3(scale_xy, scale_xy, scale_z) + + # Scale the bone + skeleton_bouncing.set_bone_pose_scale(1, scale_squish_vector) + diff --git a/Misc/64x64_orange_grey.png b/Misc/64x64_orange_grey.png new file mode 100644 index 0000000..56cfefa Binary files /dev/null and b/Misc/64x64_orange_grey.png differ diff --git a/Misc/64x64_orange_grey.png.import b/Misc/64x64_orange_grey.png.import new file mode 100644 index 0000000..74ed10a --- /dev/null +++ b/Misc/64x64_orange_grey.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://onahsd5he406" +path.bptc="res://.godot/imported/64x64_orange_grey.png-203365b2fcad03a2e512ed8cebf3390d.bptc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Misc/64x64_orange_grey.png" +dest_files=["res://.godot/imported/64x64_orange_grey.png-203365b2fcad03a2e512ed8cebf3390d.bptc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=true +compress/lossy_quality=0.7 +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/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 diff --git a/Misc/debug_cone.gd b/Misc/debug_cone.gd new file mode 100644 index 0000000..d823ce9 --- /dev/null +++ b/Misc/debug_cone.gd @@ -0,0 +1,11 @@ +extends Node3D + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + look_at(owner.get_node("Player").position) diff --git a/Misc/matcap_wobbly.png b/Misc/matcap_wobbly.png new file mode 100644 index 0000000..56e299c Binary files /dev/null and b/Misc/matcap_wobbly.png differ diff --git a/Misc/matcap_wobbly.png.import b/Misc/matcap_wobbly.png.import new file mode 100644 index 0000000..f75f4fa --- /dev/null +++ b/Misc/matcap_wobbly.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://7xvwnxdwlypg" +path.s3tc="res://.godot/imported/matcap_wobbly.png-13d838ce64cae2354ad30b75a27707f8.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Misc/matcap_wobbly.png" +dest_files=["res://.godot/imported/matcap_wobbly.png-13d838ce64cae2354ad30b75a27707f8.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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 diff --git a/Player/player.gd b/Player/player.gd new file mode 100644 index 0000000..0616990 --- /dev/null +++ b/Player/player.gd @@ -0,0 +1,56 @@ +extends CharacterBody3D + + +const SPEED = 5.0 +const JUMP_VELOCITY = 4.5 + +# Get the gravity from the project settings to be synced with RigidBody nodes. +var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") + + +func _ready(): + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + + +func _physics_process(delta): + # Add the gravity. + if not is_on_floor(): + velocity.y -= gravity * delta + + # Handle Jump. + if Input.is_action_just_pressed("jump") and is_on_floor(): + velocity.y = JUMP_VELOCITY + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + var input_dir = Input.get_vector("move_left", "move_right", "move_up", "move_down") + var direction = ( + transform.basis * + $Camera/CameraBasis.transform.basis * + Vector3(input_dir.x, 0, input_dir.y) + ).normalized() + if direction: + velocity.x = direction.x * SPEED + velocity.z = direction.z * SPEED + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + velocity.z = move_toward(velocity.z, 0, SPEED) + + # Shooting the ball + if Input.is_action_just_pressed("shoot"): + $Camera/Shooter.shoot($Camera/Shooter.global_position, camera_direction, 10) + + _get_camera_direction() + move_and_slide() + + +func _input(event): + if event is InputEventMouseMotion: + $Camera.rotation.y -= event.relative.x * (1.0 / 1000) + $Camera.rotation.x -= event.relative.y * (1.0 / 1000) + $Camera.rotation.x = clamp($Camera.rotation.x, deg_to_rad(-90), deg_to_rad(90)) + + +var camera_direction : Vector3 +func _get_camera_direction(): + camera_direction = $Camera.global_position.direction_to($Camera/CameraDirection.global_position) diff --git a/Player/player.tscn b/Player/player.tscn new file mode 100644 index 0000000..125f987 --- /dev/null +++ b/Player/player.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=6 format=3 uid="uid://ggl4tqcb5dbc"] + +[ext_resource type="Script" path="res://Player/player.gd" id="1_f70jf"] +[ext_resource type="Script" path="res://Player/player_camera_basis.gd" id="2_o7m3c"] +[ext_resource type="Script" path="res://Player/shooter.gd" id="3_eijnn"] +[ext_resource type="PackedScene" uid="uid://rdlvlyf0l1l" path="res://Ball/ball.tscn" id="4_5tvf6"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_v066f"] +radius = 0.35 +height = 1.6 + +[node name="Player" type="CharacterBody3D"] +collision_layer = 2 +script = ExtResource("1_f70jf") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8, 0) +shape = SubResource("CapsuleShape3D_v066f") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.24985, 0) + +[node name="CameraBasis" type="Node3D" parent="Camera"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.24985, 0) +top_level = true +script = ExtResource("2_o7m3c") + +[node name="CameraDirection" type="Node3D" parent="Camera"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1) + +[node name="Shooter" type="Node3D" parent="Camera"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.5) +script = ExtResource("3_eijnn") +ball_scene = ExtResource("4_5tvf6") diff --git a/Player/player_camera_basis.gd b/Player/player_camera_basis.gd new file mode 100644 index 0000000..b0a81a1 --- /dev/null +++ b/Player/player_camera_basis.gd @@ -0,0 +1,8 @@ +extends Node3D + + +func _process(_delta): + # Copy only the Y rotation of the camera pivot. + # This avoids the problem of the transform.basis not pointing forward if you tilt the camera + # up or down, messing with the movement vector of the player + rotation = Vector3(0, get_parent().rotation.y, 0) diff --git a/Player/shooter.gd b/Player/shooter.gd new file mode 100644 index 0000000..0c43b33 --- /dev/null +++ b/Player/shooter.gd @@ -0,0 +1,15 @@ +extends Node3D + + +@export var ball_scene : PackedScene + + +func shoot(spawn_position ,direction = Vector3.FORWARD, strength = 7): + var ball = ball_scene.instantiate() + + ball.linear_velocity = direction * strength + ball.position = spawn_position + + # Add the ball to the highest node of the scene so it's not parented to the player + get_tree().root.get_child(0).add_child(ball) + diff --git a/World/worD3C3.tmp b/World/worD3C3.tmp new file mode 100644 index 0000000..7f53236 --- /dev/null +++ b/World/worD3C3.tmp @@ -0,0 +1,62 @@ +[gd_scene load_steps=8 format=3 uid="uid://b06nx3ofndgjy"] + +[ext_resource type="Texture2D" uid="uid://onahsd5he406" path="res://64x64_orange_grey.png" id="1_4apc2"] +[ext_resource type="PackedScene" uid="uid://ggl4tqcb5dbc" path="res://Player/player.tscn" id="1_n0nhi"] +[ext_resource type="Script" path="res://Misc/debug_cone.gd" id="3_nsiny"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bwr1w"] +albedo_texture = ExtResource("1_4apc2") +uv1_scale = Vector3(0.5, 0.5, 0.5) +uv1_triplanar = true +texture_filter = 2 + +[sub_resource type="PlaneMesh" id="PlaneMesh_6jpek"] +size = Vector2(3, 8) + +[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_iauoa"] +points = PackedVector3Array(1.5, 0, 4, -1.5, 0, 4, 1.5, 0, -4, -1.5, 0, -4) + +[sub_resource type="CylinderMesh" id="CylinderMesh_modx0"] +top_radius = 0.0 +bottom_radius = 0.3 +height = 0.6 + +[node name="World" type="Node3D"] + +[node name="Level" type="Node3D" parent="."] + +[node name="CSGBox3D" type="CSGBox3D" parent="Level"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0) +material_override = SubResource("StandardMaterial3D_bwr1w") +use_collision = true +size = Vector3(12, 8, 12) + +[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGBox3D"] +operation = 2 +size = Vector3(11.8, 7.8, 11.8) + +[node name="DiagonalWall" type="StaticBody3D" parent="Level"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 0, -5) + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Level/DiagonalWall"] +transform = Transform3D(0.707107, 0.707107, -3.09086e-08, 0, -4.37114e-08, -1, -0.707107, 0.707107, -3.09086e-08, 0, 4, 0) +mesh = SubResource("PlaneMesh_6jpek") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Level/DiagonalWall"] +transform = Transform3D(0.707107, 0.707107, -3.09086e-08, 0, -4.37114e-08, -1, -0.707107, 0.707107, -3.09086e-08, 0, 4, 0) +shape = SubResource("ConvexPolygonShape3D_iauoa") + +[node name="Player" parent="." instance=ExtResource("1_n0nhi")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.2, 0) + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.482579, -0.637736, -0.600342, 0, -0.685437, 0.728132, -0.875852, -0.351381, -0.330778, 0, 0, 0) + +[node name="DebugCone" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 0.5, 4.5) +script = ExtResource("3_nsiny") + +[node name="DebugConeMesh" type="MeshInstance3D" parent="DebugCone"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0) +mesh = SubResource("CylinderMesh_modx0") +skeleton = NodePath("../..") diff --git a/World/world.tscn b/World/world.tscn new file mode 100644 index 0000000..2b55ddb --- /dev/null +++ b/World/world.tscn @@ -0,0 +1,78 @@ +[gd_scene load_steps=10 format=3 uid="uid://b06nx3ofndgjy"] + +[ext_resource type="Texture2D" uid="uid://onahsd5he406" path="res://Misc/64x64_orange_grey.png" id="1_k0u6d"] +[ext_resource type="PackedScene" uid="uid://ggl4tqcb5dbc" path="res://Player/player.tscn" id="1_n0nhi"] +[ext_resource type="Script" path="res://Misc/debug_cone.gd" id="3_nsiny"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bwr1w"] +albedo_texture = ExtResource("1_k0u6d") +uv1_scale = Vector3(0.5, 0.5, 0.5) +uv1_triplanar = true +texture_filter = 2 + +[sub_resource type="PlaneMesh" id="PlaneMesh_6jpek"] +size = Vector2(3, 8) + +[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_iauoa"] +points = PackedVector3Array(1.5, 0, 4, -1.5, 0, 4, 1.5, 0, -4, -1.5, 0, -4) + +[sub_resource type="SphereMesh" id="SphereMesh_0a0pq"] +radius = 3.0 +height = 6.0 + +[sub_resource type="SphereShape3D" id="SphereShape3D_hjh1m"] +radius = 3.0 + +[sub_resource type="CylinderMesh" id="CylinderMesh_modx0"] +top_radius = 0.0 +bottom_radius = 0.3 +height = 0.6 + +[node name="World" type="Node3D"] + +[node name="Level" type="Node3D" parent="."] + +[node name="CSGBox3D" type="CSGBox3D" parent="Level"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0) +material_override = SubResource("StandardMaterial3D_bwr1w") +use_collision = true +size = Vector3(12, 8, 12) + +[node name="CSGBox3D2" type="CSGBox3D" parent="Level/CSGBox3D"] +operation = 2 +size = Vector3(11.8, 7.8, 11.8) + +[node name="DiagonalWall" type="StaticBody3D" parent="Level"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 0, -5) + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Level/DiagonalWall"] +transform = Transform3D(0.707107, 0.707107, -3.09086e-08, 0, -4.37114e-08, -1, -0.707107, 0.707107, -3.09086e-08, 0, 4, 0) +mesh = SubResource("PlaneMesh_6jpek") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Level/DiagonalWall"] +transform = Transform3D(0.707107, 0.707107, -3.09086e-08, 0, -4.37114e-08, -1, -0.707107, 0.707107, -3.09086e-08, 0, 4, 0) +shape = SubResource("ConvexPolygonShape3D_iauoa") + +[node name="Sphere" type="StaticBody3D" parent="Level"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 0, -6) + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Level/Sphere"] +mesh = SubResource("SphereMesh_0a0pq") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Level/Sphere"] +shape = SubResource("SphereShape3D_hjh1m") + +[node name="Player" parent="." instance=ExtResource("1_n0nhi")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.2, 0) + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.482579, -0.637736, -0.600342, 0, -0.685437, 0.728132, -0.875852, -0.351381, -0.330778, 0, 0, 0) + +[node name="DebugCone" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 0.5, 4.5) +script = ExtResource("3_nsiny") + +[node name="DebugConeMesh" type="MeshInstance3D" parent="DebugCone"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0) +mesh = SubResource("CylinderMesh_modx0") +skeleton = NodePath("../..") diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..b370ceb --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..78ab15a --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://wabpaapepcrh" +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/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +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=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..1491771 --- /dev/null +++ b/project.godot @@ -0,0 +1,56 @@ +; 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="Custom RigidBody Bounce Behaviour" +run/main_scene="res://World/world.tscn" +config/features=PackedStringArray("4.1", "Forward Plus") +config/icon="res://icon.svg" + +[input] + +move_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) +] +} +move_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) +] +} +move_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) +] +} +move_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) +] +} +jump={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"echo":false,"script":null) +] +} +shoot={ +"deadzone": 0.5, +"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":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":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":69,"key_label":0,"unicode":101,"echo":false,"script":null) +] +} + +[layer_names] + +3d_physics/layer_1="general" +3d_physics/layer_2="player" +3d_physics/layer_3="balls"