From 30dc7050beefd54ee32d0632635198a1056b4e4a Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Sun, 15 Dec 2024 16:33:31 -0700 Subject: [PATCH] Ball & player are repositioned based on ball radius --- .../balls/beach_ball/beach_ball.tscn | 3 ++- src/equipment/balls/physics_ball/game_ball.gd | 10 +++++---- src/player/shot_setup/ball_point.gd | 3 +++ src/player/shot_setup/shot_setup.gd | 15 +++++++++++-- src/player/shot_setup/shot_setup.tscn | 21 +++++++++++-------- 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/equipment/balls/beach_ball/beach_ball.tscn b/src/equipment/balls/beach_ball/beach_ball.tscn index bdfc551..6d360c2 100644 --- a/src/equipment/balls/beach_ball/beach_ball.tscn +++ b/src/equipment/balls/beach_ball/beach_ball.tscn @@ -29,7 +29,8 @@ mass = 0.1 physics_material_override = SubResource("PhysicsMaterial_867vn") linear_damp = 0.1 script = ExtResource("2_ay78j") -radius = 0.1 +base_damage = 5.0 +radius = 0.5 [node name="BallMesh" parent="." index="0"] mesh = SubResource("SphereMesh_iqcc5") diff --git a/src/equipment/balls/physics_ball/game_ball.gd b/src/equipment/balls/physics_ball/game_ball.gd index 7dfbc62..7b3d23e 100644 --- a/src/equipment/balls/physics_ball/game_ball.gd +++ b/src/equipment/balls/physics_ball/game_ball.gd @@ -32,8 +32,10 @@ const MAGNUS_EPSILON := 1e-3 ## This is approximately 1/2 * rho * C_L * pi * r^2 ## where `rho` is the fluid density of the medium, or 1.225 for air at sea level, ## and `C_L` is the lift coefficient which for our purposes is 0.05, -## and `r` is the radius of the ball, which is 5cm. -@export var magnus_coefficient := 0.00024 +## and `r` is the radius of the ball, which is variable. +## NOTE: Rather than use r^2 we use r * a constant 0.05 +#@export var magnus_coefficient := 0.00024 +@export var magnus_coefficient := 0.00481056 ## Causes the ball to stick to surfaces @export var magnetic := false @@ -44,7 +46,7 @@ const MAGNUS_EPSILON := 1e-3 ## Scaling factor for additional force-based damage @export var damage_force_scale := 0.01 -## Approximate average radius, for physics purposes +## Approximate average radius, for physics & positioning purposes @export var radius := 0.05 var current_gravity: Vector3 @@ -107,7 +109,7 @@ func _total_terrain_angular_damping() -> float: func _magnus_force() -> Vector3: - return magnus_coefficient * angular_velocity.cross(linear_velocity) + return magnus_coefficient * radius * angular_velocity.cross(linear_velocity) func _integrate_forces(state: PhysicsDirectBodyState3D) -> void: diff --git a/src/player/shot_setup/ball_point.gd b/src/player/shot_setup/ball_point.gd index c657d2f..aca354f 100644 --- a/src/player/shot_setup/ball_point.gd +++ b/src/player/shot_setup/ball_point.gd @@ -18,6 +18,8 @@ const SCENE_MAP: Dictionary = { ball = value ball_changed.emit(ball) +@export var height_offset := 0.08 + @onready var shot_setup: ShotSetup = $".." @@ -41,6 +43,7 @@ func spawn_ball(type: GameBall.Type) -> void: ball = get_instance(type) if is_instance_valid(ball): add_child(ball) + position.y = height_offset + ball.radius snap() diff --git a/src/player/shot_setup/shot_setup.gd b/src/player/shot_setup/shot_setup.gd index 1672b50..1ed7502 100644 --- a/src/player/shot_setup/shot_setup.gd +++ b/src/player/shot_setup/shot_setup.gd @@ -41,6 +41,7 @@ const WATER_DAMAGE := 10.0 const CURVE_INFLUENCE := PI / 16 ## Just enough to make things interesting! +const SHOT_OFFSET_X_FACTOR := 20.0 const SHOT_OFFSET_Z_FACTOR := 2.0 / 45.0 ## Impulse offset multiplier due to curve, in meters @@ -135,8 +136,9 @@ var _tracking_camera: OrbitalCamera @onready var camera: Camera3D = %Camera @onready var player_pivot: Node3D = %PlayerPivot +@onready var player_offset: Node3D = %PlayerOffset # TODO: genericize for selectable characters -@onready var character: CharacterController = $PlayerPivot/GfolfGirl +@onready var character: CharacterController = $PlayerPivot/PlayerOffset/GfolfGirl @onready var shot_animation: AnimationPlayer = %ShotAnimation @onready var shot_sfx: ShotSFX = %ShotSFX @@ -282,7 +284,10 @@ func take_shot() -> void: var curve := shot_curve * absf(shot_curve) * CURVE_FACTOR # Position where the ball is hit (imparts spin) - var offset := direction.global_basis.x.normalized() * -curve + var offset := ( + direction.global_basis.x.normalized() * -curve * game_ball.radius * SHOT_OFFSET_X_FACTOR + ) + print_debug("Curve offset magnitude: ", offset.length()) offset += ( direction.global_basis.z.normalized() * game_ball.radius @@ -383,6 +388,9 @@ func travel_to_ball() -> void: _target_rotation.y = 0 global_basis = game_ball.get_reoriented_basis() + # Adjust position downward to account for ball radius + global_position -= global_basis.y.normalized() * game_ball.radius + ball_point.snap() @@ -507,9 +515,12 @@ func _on_phase_change(new_phase: Phase) -> void: func _on_game_ball_changed(ball: GameBall) -> void: + var z_offset := 0.0 if ball: ball.entered_water.connect(_on_ball_entered_water) ball.sleeping_state_changed.connect(_on_ball_sleeping_state_changed) + z_offset = ball.radius + player_offset.position.z = z_offset func _process(delta: float) -> void: diff --git a/src/player/shot_setup/shot_setup.tscn b/src/player/shot_setup/shot_setup.tscn index 7ecba9b..f6f4cc2 100644 --- a/src/player/shot_setup/shot_setup.tscn +++ b/src/player/shot_setup/shot_setup.tscn @@ -456,36 +456,39 @@ bus = &"SFX" [node name="PlayerPivot" type="Node3D" parent="."] unique_name_in_owner = true -[node name="GfolfGirl" parent="PlayerPivot" instance=ExtResource("3_e4aur")] -transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -0.555968, 0, 0.0999683) +[node name="PlayerOffset" type="Node3D" parent="PlayerPivot"] +unique_name_in_owner = true -[node name="DemoCamera" type="Camera3D" parent="PlayerPivot" groups=["DemoCamera"]] +[node name="GfolfGirl" parent="PlayerPivot/PlayerOffset" instance=ExtResource("3_e4aur")] +transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -0.556, 0, 0.05) + +[node name="DemoCamera" type="Camera3D" parent="PlayerPivot/PlayerOffset" groups=["DemoCamera"]] transform = Transform3D(-0.311543, -0.0687373, 0.947743, 0, 0.99738, 0.0723374, -0.950232, 0.0225362, -0.310727, 0.845792, 0.706621, -0.383459) -[node name="DeathSequence" type="Node3D" parent="PlayerPivot"] +[node name="DeathSequence" type="Node3D" parent="PlayerPivot/PlayerOffset"] process_mode = 3 script = ExtResource("10_vakjm") -[node name="AudioStreamPlayer3D" type="AudioStreamPlayer" parent="PlayerPivot/DeathSequence"] +[node name="AudioStreamPlayer3D" type="AudioStreamPlayer" parent="PlayerPivot/PlayerOffset/DeathSequence"] stream = SubResource("AudioStreamRandomizer_7seum") volume_db = -4.0 bus = &"SFX" -[node name="DeathAnimation" type="AnimationPlayer" parent="PlayerPivot/DeathSequence"] +[node name="DeathAnimation" type="AnimationPlayer" parent="PlayerPivot/PlayerOffset/DeathSequence"] unique_name_in_owner = true libraries = { "": SubResource("AnimationLibrary_kc803") } -[node name="Camera3D1" type="Camera3D" parent="PlayerPivot/DeathSequence"] +[node name="Camera3D1" type="Camera3D" parent="PlayerPivot/PlayerOffset/DeathSequence"] transform = Transform3D(-0.00257592, 0.0226116, 0.999741, 0, 0.999744, -0.0226116, -0.999997, -5.82457e-05, -0.00257526, 1.6905, 0.831287, 0.0668699) far = 8192.0 -[node name="Camera3D2" type="Camera3D" parent="PlayerPivot/DeathSequence"] +[node name="Camera3D2" type="Camera3D" parent="PlayerPivot/PlayerOffset/DeathSequence"] transform = Transform3D(0.864734, -0.175509, 0.470564, 0, 0.936951, 0.349461, -0.502229, -0.302191, 0.810214, 0.386249, 1.16999, 0.906541) far = 8192.0 -[node name="Camera3D3" type="Camera3D" parent="PlayerPivot/DeathSequence"] +[node name="Camera3D3" type="Camera3D" parent="PlayerPivot/PlayerOffset/DeathSequence"] transform = Transform3D(0.00178714, 0.559853, 0.82859, 0, 0.828592, -0.559853, -0.999998, 0.00100054, 0.00148081, 0.334412, 0.629604, 0.136928) far = 8192.0