diff --git a/Assets/arena_placeholder_v01.glb b/Assets/arena_placeholder_v01.glb index 23413a1..af0bd77 100644 Binary files a/Assets/arena_placeholder_v01.glb and b/Assets/arena_placeholder_v01.glb differ diff --git a/Blender/bull_v11.blend b/Blender/bull_v11.blend index ff7c094..4ce3a70 100644 Binary files a/Blender/bull_v11.blend and b/Blender/bull_v11.blend differ diff --git a/Blender/bull_v11.blend.import b/Blender/bull_v11.blend.import index b1a2d48..5403b97 100644 --- a/Blender/bull_v11.blend.import +++ b/Blender/bull_v11.blend.import @@ -16,8 +16,6 @@ dest_files=["res://.godot/imported/bull_v11.blend-0dd387f5e964c51fff069fa50a9998 nodes/root_type="" nodes/root_name="" nodes/root_script=null -mesh_library/use_node_names_as_mesh_names=false -array_mesh/deduplicate_surfaces=true nodes/apply_root_scale=true nodes/root_scale=1.0 nodes/import_as_skeleton_bones=false @@ -46,7 +44,7 @@ blender/nodes/punctual_lights=true blender/nodes/cameras=true blender/nodes/custom_properties=true blender/nodes/modifiers=1 -blender/meshes/vertex_colors=1 +blender/meshes/colors=false blender/meshes/uvs=true blender/meshes/normals=true blender/meshes/export_geometry_nodes_instances=false @@ -60,4 +58,3 @@ blender/animation/limit_playback=true blender/animation/always_sample=true blender/animation/group_tracks=true gltf/naming_version=2 -gltf/texture_map_mode=1 diff --git a/Blender/matador_v01.blend b/Blender/matador_v01.blend index be1a614..578917d 100644 Binary files a/Blender/matador_v01.blend and b/Blender/matador_v01.blend differ diff --git a/Blender/matador_v01.blend.import b/Blender/matador_v01.blend.import index ae52598..9565a10 100644 --- a/Blender/matador_v01.blend.import +++ b/Blender/matador_v01.blend.import @@ -16,8 +16,6 @@ dest_files=["res://.godot/imported/matador_v01.blend-ca770df72393bcfc88aeadbf3f9 nodes/root_type="" nodes/root_name="" nodes/root_script=null -mesh_library/use_node_names_as_mesh_names=false -array_mesh/deduplicate_surfaces=true nodes/apply_root_scale=true nodes/root_scale=1.0 nodes/import_as_skeleton_bones=false @@ -46,7 +44,7 @@ blender/nodes/punctual_lights=true blender/nodes/cameras=true blender/nodes/custom_properties=true blender/nodes/modifiers=1 -blender/meshes/vertex_colors=1 +blender/meshes/colors=false blender/meshes/uvs=true blender/meshes/normals=true blender/meshes/export_geometry_nodes_instances=false @@ -60,4 +58,3 @@ blender/animation/limit_playback=true blender/animation/always_sample=true blender/animation/group_tracks=true gltf/naming_version=2 -gltf/texture_map_mode=1 diff --git a/Blender/matador_v01.blend1 b/Blender/matador_v01.blend1 index ac8eb74..18577dd 100644 Binary files a/Blender/matador_v01.blend1 and b/Blender/matador_v01.blend1 differ diff --git a/Blender/matador_v02.blend.import b/Blender/matador_v02.blend.import index de22397..3951eab 100644 --- a/Blender/matador_v02.blend.import +++ b/Blender/matador_v02.blend.import @@ -16,8 +16,6 @@ dest_files=["res://.godot/imported/matador_v02.blend-78c935c19487a89cf2e8e43e696 nodes/root_type="" nodes/root_name="" nodes/root_script=null -mesh_library/use_node_names_as_mesh_names=false -array_mesh/deduplicate_surfaces=true nodes/apply_root_scale=true nodes/root_scale=1.0 nodes/import_as_skeleton_bones=false @@ -46,7 +44,7 @@ blender/nodes/punctual_lights=true blender/nodes/cameras=true blender/nodes/custom_properties=true blender/nodes/modifiers=1 -blender/meshes/vertex_colors=1 +blender/meshes/colors=false blender/meshes/uvs=true blender/meshes/normals=true blender/meshes/export_geometry_nodes_instances=false @@ -60,4 +58,3 @@ blender/animation/limit_playback=true blender/animation/always_sample=true blender/animation/group_tracks=true gltf/naming_version=2 -gltf/texture_map_mode=1 diff --git a/Blender/matador_v02.fbx.import b/Blender/matador_v02.fbx.import index 6a24977..4a013ad 100644 --- a/Blender/matador_v02.fbx.import +++ b/Blender/matador_v02.fbx.import @@ -16,8 +16,6 @@ dest_files=["res://.godot/imported/matador_v02.fbx-220033ca52e262349a727eddc79dc nodes/root_type="" nodes/root_name="" nodes/root_script=null -mesh_library/use_node_names_as_mesh_names=false -array_mesh/deduplicate_surfaces=true nodes/apply_root_scale=true nodes/root_scale=1.0 nodes/import_as_skeleton_bones=false diff --git a/Player.tscn b/Player.tscn index 6d70160..db6a829 100644 --- a/Player.tscn +++ b/Player.tscn @@ -6,7 +6,7 @@ [ext_resource type="PackedScene" uid="uid://qy6qrxdfgx2g" path="res://Assets/bull_v10.fbx" id="4_e80uo"] [sub_resource type="SphereShape3D" id="SphereShape3D_kne1u"] -radius = 0.3 +radius = 0.5 [sub_resource type="SphereShape3D" id="SphereShape3D_chest"] radius = 0.35 @@ -37,9 +37,10 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.22, 0) script = ExtResource("2_kpjcp") [node name="SpringArm3D" type="SpringArm3D" parent="SpringArmPivot" unique_id=141439848] -collision_mask = 2 +collision_mask = 3 shape = SubResource("SphereShape3D_kne1u") spring_length = 7.0 +margin = 0.5 [node name="SpringPosition" type="Node3D" parent="SpringArmPivot/SpringArm3D" unique_id=1307131677] diff --git a/camera_follow.gd b/camera_follow.gd index 543dc1e..d8b2cd4 100644 --- a/camera_follow.gd +++ b/camera_follow.gd @@ -2,8 +2,8 @@ extends Camera3D @export var spring_arm: Node3D -@export var lerp_power: float = 1.0 func _process(delta: float) -> void: + var lerp_power: float = DP.f("cam_lerp_power") position = position.lerp(spring_arm.position, delta * lerp_power) diff --git a/camera_spring_arm.gd b/camera_spring_arm.gd index 116ba52..d683874 100644 --- a/camera_spring_arm.gd +++ b/camera_spring_arm.gd @@ -1,24 +1,25 @@ extends Node3D -@export var mouse_sensitivity: float = 0.005 -@export_range(-90.0, 0.0, 0.1, "radians_as_degrees") var min_vertical_angle: float = -PI / 2 -@export_range(0.0, 90.0, 0.1, "radians_as_degrees") var max_vertical_angle: float = PI / 4 -@export var min_zoom: float = 2.0 -@export var max_zoom: float = 12.0 - @onready var spring_arm: SpringArm3D = $SpringArm3D func _ready() -> void: Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + spring_arm.spring_length = DP.f("cam_spring_length") func _unhandled_input(event: InputEvent) -> void: + var sensitivity: float = DP.f("cam_sensitivity") + var min_vert: float = deg_to_rad(DP.f("cam_min_vert_angle")) + var max_vert: float = deg_to_rad(DP.f("cam_max_vert_angle")) + var min_zoom: float = DP.f("cam_min_zoom") + var max_zoom: float = DP.f("cam_max_zoom") + if event is InputEventMouseMotion: - rotation.y -= event.relative.x * mouse_sensitivity + rotation.y -= event.relative.x * sensitivity rotation.y = wrapf(rotation.y, 0.0, TAU) - rotation.x -= event.relative.y * mouse_sensitivity - rotation.x = clamp(rotation.x, min_vertical_angle, max_vertical_angle) + rotation.x -= event.relative.y * sensitivity + rotation.x = clamp(rotation.x, min_vert, max_vert) if event.is_action_pressed("zoom_in"): spring_arm.spring_length = clamp(spring_arm.spring_length - 1.0, min_zoom, max_zoom) @@ -30,3 +31,7 @@ func _unhandled_input(event: InputEvent) -> void: Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) else: Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + + +func _process(_delta: float) -> void: + spring_arm.spring_length = DP.f("cam_spring_length") diff --git a/debug_menu.gd b/debug_menu.gd index b3053a3..357f05a 100644 --- a/debug_menu.gd +++ b/debug_menu.gd @@ -9,7 +9,6 @@ var _prev_mouse_mode: Input.MouseMode = Input.MOUSE_MODE_CAPTURED func _ready() -> void: _build_ui() - DP.any_changed.connect(_on_dp_changed) func _build_ui() -> void: @@ -64,6 +63,11 @@ func _build_ui() -> void: save_btn.pressed.connect(_on_save) toolbar.add_child(save_btn) + var rand_all_btn := Button.new() + rand_all_btn.text = "Randomize All" + rand_all_btn.pressed.connect(_on_randomize_all) + toolbar.add_child(rand_all_btn) + var reset_btn := Button.new() reset_btn.text = "Reset All" reset_btn.pressed.connect(DP.reset_all) @@ -113,8 +117,6 @@ func _build_params(content: VBoxContainer) -> void: var meta: Dictionary = DP.get_all()[key] if meta["type"] == TYPE_FLOAT: _add_float_row(content, key, meta) - elif meta["type"] == TYPE_BOOL: - _add_bool_row(content, key, meta) func _add_float_row(parent: VBoxContainer, key: String, meta: Dictionary) -> void: @@ -145,6 +147,16 @@ func _add_float_row(parent: VBoxContainer, key: String, meta: Dictionary) -> voi spin.custom_minimum_size.x = 85 row.add_child(spin) + var rand_btn := Button.new() + rand_btn.text = "🎲" + rand_btn.tooltip_text = "Randomize" + rand_btn.pressed.connect(func() -> void: + var v := randf_range(meta["min"], meta["max"]) + v = snappedf(v, meta["step"]) + slider.value = v + ) + row.add_child(rand_btn) + # Slider → SpinBox + DP (use no_signal to avoid echo) slider.value_changed.connect(func(v: float) -> void: spin.set_value_no_signal(v) @@ -165,46 +177,6 @@ func _add_float_row(parent: VBoxContainer, key: String, meta: Dictionary) -> voi ) -func _add_bool_row(parent: VBoxContainer, key: String, meta: Dictionary) -> void: - var row := HBoxContainer.new() - row.size_flags_horizontal = Control.SIZE_FILL - parent.add_child(row) - - var lbl := Label.new() - lbl.text = key.replace("_", " ") - lbl.custom_minimum_size.x = 140 - lbl.vertical_alignment = VERTICAL_ALIGNMENT_CENTER - row.add_child(lbl) - - var btn := Button.new() - btn.toggle_mode = true - btn.button_pressed = meta["value"] - btn.text = "HIDDEN" if not meta["value"] else "SHOWN" - _update_btn_style(btn, meta["value"]) - row.add_child(btn) - - btn.toggled.connect(func(v: bool) -> void: - btn.text = "HIDDEN" if not v else "SHOWN" - _update_btn_style(btn, v) - DP.set_value(key, v) - ) - - DP.any_changed.connect(func(changed_key: String, _val: Variant) -> void: - if changed_key != key and changed_key != "__all__": - return - var v_b: bool = DP.b(key) - btn.set_pressed_no_signal(v_b) - btn.text = "HIDDEN" if not v_b else "SHOWN" - _update_btn_style(btn, v_b) - ) - - -func _update_btn_style(btn: Button, active: bool) -> void: - if active: - btn.add_theme_color_override("font_color", Color(0.4, 1.0, 0.5)) - else: - btn.add_theme_color_override("font_color", Color(1.0, 0.4, 0.4)) - func _on_save() -> void: DP.save() @@ -214,21 +186,6 @@ func _on_save() -> void: ) -func _on_dp_changed(key: String, _value: Variant) -> void: - if key == "show_collisions" or key == "__all__": - var active: bool = DP.b("show_collisions") - get_tree().debug_collisions_hint = active - # Force refresh of all collision shapes - _refresh_collisions(get_tree().root, active) - - -func _refresh_collisions(node: Node, active: bool) -> void: - if node is CollisionShape3D or node is CollisionPolygon3D: - node.visible = !node.visible # Trigger a notification - node.visible = !node.visible - - for child in node.get_children(): - _refresh_collisions(child, active) func _input(event: InputEvent) -> void: @@ -248,3 +205,12 @@ func _unhandled_input(event: InputEvent) -> void: else: Input.mouse_mode = _prev_mouse_mode get_viewport().set_input_as_handled() + + + +func _on_randomize_all() -> void: + for key: String in DP.get_all(): + var meta: Dictionary = DP.get_all()[key] + if meta["type"] == TYPE_FLOAT: + var v := snappedf(randf_range(meta["min"], meta["max"]), meta["step"]) + DP.set_value(key, v) diff --git a/debug_params.gd b/debug_params.gd index 323fb2c..658d198 100644 --- a/debug_params.gd +++ b/debug_params.gd @@ -17,18 +17,20 @@ func _ready() -> void: func _register_all() -> void: # ── Movement ────────────────────────────────────────────────────────────── - _reg_f("Movement", "kick_impulse", 7.0, 0.5, 200.0) - _reg_f("Movement", "kick_interval", 0.22, 0.05, 2.0, 0.01) - _reg_f("Movement", "kick_vertical", 3.5, 0.0, 100.0) - _reg_f("Movement", "kick_spread", 12.0, 0.0, 90.0) - _reg_f("Movement", "kick_force_var", 0.20, 0.0, 2.0, 0.05) - _reg_f("Movement", "charge_kick_mult", 3.0, 1.0, 50.0) - _reg_f("Movement", "roll_damping", 0.30, 0.01, 0.99, 0.01) - _reg_f("Movement", "max_speed", 20.0, 2.0, 1000.0) - _reg_f("Movement", "jump_velocity", 4.5, 1.0, 200.0) - _reg_f("Movement", "visual_turn_speed", 12.0, 1.0, 200.0) - _reg_f("Movement", "bounce_restitution", 0.55, 0.0, 2.0, 0.05) - _reg_f("Movement", "bounce_min_impact", 1.0, 0.0, 20.0) + _reg_f("Movement", "thrust_impulse", 18.0, 1.0, 200.0) + _reg_f("Movement", "thrust_vertical", 2.0, 0.0, 20.0) + _reg_f("Movement", "max_speed", 30.0, 2.0, 1000.0) + _reg_f("Movement", "roll_damping", 0.15, 0.01, 0.99, 0.01) + _reg_f("Movement", "jump_velocity", 4.5, 1.0, 200.0) + _reg_f("Movement", "visual_turn_speed", 12.0, 1.0, 200.0) + _reg_f("Movement", "bounce_restitution", 0.55, 0.0, 2.0, 0.05) + _reg_f("Movement", "bounce_min_impact", 1.0, 0.0, 20.0) + _reg_f("Movement", "kick_impulse", 8.0, 1.0, 50.0) + _reg_f("Movement", "kick_interval", 0.25, 0.05, 1.0, 0.01) + _reg_f("Movement", "kick_vertical", 3.0, 0.0, 15.0) + _reg_f("Movement", "kick_force_var", 0.2, 0.0, 1.0, 0.01) + _reg_f("Movement", "kick_spread", 10.0, 0.0, 45.0, 1.0) + _reg_f("Movement", "charge_kick_mult", 2.0, 1.0, 5.0) # ── Dust speed thresholds ───────────────────────────────────────────────── _reg_f("Dust", "dust_walk_spd", 1.5, 0.1, 10.0) _reg_f("Dust", "dust_charge_spd", 7.0, 1.0, 20.0) @@ -45,32 +47,48 @@ func _register_all() -> void: _reg_f("Dust", "charge_scale_max", 2.2, 0.05, 6.0) _reg_f("Dust", "charge_vel_min", 2.8, 0.1, 20.0) _reg_f("Dust", "charge_vel_max", 5.5, 0.1, 20.0) - # ── Body wobble ─────────────────────────────────────────────────────────── - _reg_f("Body", "body_tilt_fwd", 0.035, 0.0, 0.15, 0.005) - _reg_f("Body", "body_tilt_side", 0.025, 0.0, 0.15, 0.005) - _reg_f("Body", "aerial_pitch_scale", 0.7, 0.0, 4.0, 0.05) - _reg_f("Body", "aerial_pitch_speed", 6.0, 0.5, 30.0) - # ── Legs ────────────────────────────────────────────────────────────────── - _reg_f("Legs", "gait_freq", 0.30, 0.0, 5.0, 0.01) - _reg_f("Legs", "leg_step_threshold", 0.12, 0.01, 1.5, 0.01) - _reg_f("Legs", "leg_step_height", 0.32, 0.0, 1.5, 0.01) - _reg_f("Legs", "leg_step_duration", 0.10, 0.02, 0.5, 0.01) - _reg_f("Legs", "leg_step_overshoot", 1.2, 0.0, 5.0, 0.1) - _reg_f("Legs", "jump_tuck_fwd", 0.2, -1.0, 1.0, 0.05) - _reg_f("Legs", "jump_tuck_up", 0.3, 0.0, 1.5, 0.05) - _reg_f("Legs", "jump_tuck_speed", 10.0, 1.0, 30.0) - _reg_f("Legs", "jump_land_threshold", 1.5, 0.0, 5.0, 0.1) - _reg_f("Legs", "launch_hold_time", 0.15, 0.0, 1.0, 0.01) - _reg_f("Legs", "ragdoll_wobble_amp", 0.15, 0.0, 1.0, 0.01) - _reg_f("Legs", "tuck_apex_threshold", 1.0, -5.0, 5.0, 0.1) # ── Tail ────────────────────────────────────────────────────────────────── _reg_f("Tail", "tail_gravity", 9.8, 0.0, 30.0) _reg_f("Tail", "tail_damping", 0.08, 0.0, 0.5, 0.01) _reg_f("Tail", "tail_body_radius", 0.35, 0.05, 2.0, 0.05) _reg_f("Tail", "tail_wag_freq", 4.0, 0.5, 15.0) _reg_f("Tail", "tail_wag_idle", 0.3, 0.0, 2.0, 0.05) + # ── Body ────────────────────────────────────────────────────────────────── + _reg_f("Body", "body_tilt_fwd", 0.015, 0.0, 0.1, 0.001) + _reg_f("Body", "body_tilt_side", 0.01, 0.0, 0.1, 0.001) + _reg_f("Body", "aerial_pitch_scale", 0.6, 0.0, 2.0) + _reg_f("Body", "aerial_pitch_speed", 5.0, 0.5, 20.0) + # ── Legs ────────────────────────────────────────────────────────────────── + _reg_f("Legs", "leg_step_threshold", 0.15, 0.01, 1.0, 0.01) + _reg_f("Legs", "leg_step_duration", 0.12, 0.02, 0.5, 0.01) + _reg_f("Legs", "leg_step_height", 0.15, 0.0, 0.5) + _reg_f("Legs", "leg_step_overshoot", 0.3, 0.0, 1.0) + _reg_f("Legs", "gait_freq", 1.5, 0.1, 5.0) + _reg_f("Legs", "launch_hold_time", 0.15, 0.0, 1.0, 0.01) + _reg_f("Legs", "ragdoll_wobble_amp", 0.15, 0.0, 1.0) + _reg_f("Legs", "tuck_apex_threshold", 0.5, -5.0, 5.0) + _reg_f("Legs", "jump_tuck_speed", 8.0, 1.0, 30.0) + _reg_f("Legs", "jump_tuck_up", 0.2, 0.0, 1.0) + _reg_f("Legs", "jump_tuck_fwd", -0.1, -0.5, 0.5) + _reg_f("Legs", "jump_land_threshold", 1.5, 0.5, 5.0) + # ── Camera ──────────────────────────────────────────────────────────────── + _reg_f("Camera", "cam_lerp_power", 6.0, 0.5, 30.0) + _reg_f("Camera", "cam_sensitivity", 0.005, 0.001, 0.05, 0.001) + _reg_f("Camera", "cam_min_zoom", 3.5, 0.5, 20.0) + _reg_f("Camera", "cam_max_zoom", 12.0, 2.0, 50.0) + _reg_f("Camera", "cam_spring_length", 7.0, 1.0, 30.0) + _reg_f("Camera", "cam_min_vert_angle", -60.0, -90.0, 0.0, 1.0) + _reg_f("Camera", "cam_max_vert_angle", 45.0, 0.0, 90.0, 1.0) + # ── Matador ─────────────────────────────────────────────────────────────── + _reg_f("Matador", "mat_spawn_count", 8.0, 1.0, 30.0, 1.0) + _reg_f("Matador", "mat_walk_speed", 2.5, 0.5, 10.0) + _reg_f("Matador", "mat_wander_radius", 22.0, 5.0, 50.0) + _reg_f("Matador", "mat_idle_min", 0.5, 0.0, 5.0, 0.1) + _reg_f("Matador", "mat_idle_max", 2.5, 0.5, 10.0, 0.1) + _reg_f("Matador", "mat_hit_threshold", 4.0, 1.0, 30.0) + _reg_f("Matador", "mat_ragdoll_impulse", 8.0, 1.0, 50.0) # ── Debug ───────────────────────────────────────────────────────────────── - _reg_b("Debug", "show_collisions", false) + _reg_b("Debug", "show_collisions", false) func _reg_f(section: String, key: String, default: float, diff --git a/player.gd b/player.gd index d04f4af..e5eb304 100644 --- a/player.gd +++ b/player.gd @@ -13,7 +13,6 @@ const HOOF_OFFSETS: Array = [ var _hoof_emitters: Array[CPUParticles3D] = [] var _legs: Node -var _debug_shapes: Array[MeshInstance3D] = [] var _kick_timer: float = 0.0 var _was_on_floor: bool = false @@ -24,10 +23,10 @@ var _dust_state: _DustState = _DustState.NONE func _ready() -> void: + add_to_group(&"player") _setup_hoof_dust() _setup_legs() DP.any_changed.connect(_on_dp_changed) - _sync_debug_vis() func _setup_legs() -> void: @@ -109,10 +108,7 @@ func _set_dust_state(new_state: _DustState) -> void: p.emitting = true -func _on_dp_changed(key: String, _val: Variant) -> void: - if key == "show_collisions" or key == "__all__": - _sync_debug_vis() - +func _on_dp_changed(_key: String, _val: Variant) -> void: if _hoof_emitters.is_empty() or _dust_state == _DustState.NONE: return var prev := _dust_state @@ -120,41 +116,20 @@ func _on_dp_changed(key: String, _val: Variant) -> void: _set_dust_state(prev) -func _sync_debug_vis() -> void: - _clear_debug_vis() - if not DP.b("show_collisions"): - return - - # Material for wireframes - var mat := StandardMaterial3D.new() - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.no_depth_test = true - mat.albedo_color = Color(0, 1, 0, 0.5) - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - - # Find all collision shapes in self and children - _create_debug_meshes(self, mat) -func _create_debug_meshes(node: Node, mat: Material) -> void: - if node is CollisionShape3D and node.shape: - var mi := MeshInstance3D.new() - mi.mesh = node.shape.get_debug_mesh() - mi.material_override = mat - # We add it as child of the collision shape to follow its transform - node.add_child(mi) - _debug_shapes.append(mi) - - for child in node.get_children(): - _create_debug_meshes(child, mat) - - -func _clear_debug_vis() -> void: - for mi in _debug_shapes: - if is_instance_valid(mi): - mi.get_parent().remove_child(mi) - mi.queue_free() - _debug_shapes.clear() +func _apply_thrust(dir: Vector3) -> void: + var impulse := DP.f("thrust_impulse") + velocity.x += dir.x * impulse + velocity.z += dir.z * impulse + if is_on_floor(): + velocity.y += DP.f("thrust_vertical") + var flat := Vector2(velocity.x, velocity.z) + var spd := flat.length() + if spd > DP.f("max_speed"): + var s := DP.f("max_speed") / spd + velocity.x *= s + velocity.z *= s func _apply_kick(direction: Vector3, charging: bool) -> void: @@ -202,6 +177,17 @@ func _physics_process(delta: float) -> void: var charging := Input.is_action_pressed(&"charge") var on_floor := is_on_floor() + # ── Left / right click thrust (only when mouse is captured) ───────────── + # Left click → thrust NE (forward-right diagonal) + # Right click → thrust NW (forward-left diagonal) + if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + if Input.is_action_just_pressed(&"thrust_left"): + var ne := (flat_forward + flat_right).normalized() + _apply_thrust(ne if ne.length() > 0.1 else flat_forward) + if Input.is_action_just_pressed(&"thrust_right"): + var nw := (flat_forward - flat_right).normalized() + _apply_thrust(nw if nw.length() > 0.1 else flat_forward) + # Reset kick timer on landing so the first kick after a bounce is immediate if on_floor and not _was_on_floor and direction: _kick_timer = 0.0 diff --git a/project.godot b/project.godot index 5be191f..941a565 100644 --- a/project.godot +++ b/project.godot @@ -15,6 +15,11 @@ config/features=PackedStringArray("4.7", "Forward Plus") config/icon="res://icon.svg" config/run/main_scene="res://scene.tscn" +[autoload] + +DP="*res://debug_params.gd" +DebugMenu="*res://debug_menu.gd" + [editor_plugins] enabled=PackedStringArray("res://addons/rider-plugin/plugin.cfg") @@ -70,11 +75,16 @@ charge={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":1,"echo":false,"script":null) ] } - -[autoload] - -DP="*res://debug_params.gd" -DebugMenu="*res://debug_menu.gd" +thrust_left={ +"deadzone": 0.2, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +} +thrust_right={ +"deadzone": 0.2, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":2,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +} [physics] diff --git a/scene.tscn b/scene.tscn index 3393b51..8be86e1 100644 --- a/scene.tscn +++ b/scene.tscn @@ -2,6 +2,7 @@ [ext_resource type="PackedScene" uid="uid://crtm0xtiql3r8" path="res://Player.tscn" id="1_ulcgi"] [ext_resource type="PackedScene" uid="uid://dio67r8ambe7h" path="res://Assets/arena_placeholder_v01.glb" id="2_nxogm"] +[ext_resource type="Script" path="res://matador_spawn.gd" id="3_spawn"] [sub_resource type="BoxShape3D" id="BoxShape3D_ulcgi"] @@ -25,3 +26,6 @@ shape = SubResource("BoxShape3D_ulcgi") [node name="arena_placeholder_v01" parent="Node3D" unique_id=1341659233 instance=ExtResource("2_nxogm")] transform = Transform3D(0.28002706, 0, 0, 0, 1, 0, 0, 0, 0.43545616, -0.2506242, 0, 0) + +[node name="MatadorSpawner" type="Node3D" parent="." unique_id=3001000001] +script = ExtResource("3_spawn")