Fixed post-shot reorientation weirdness

This commit is contained in:
Rob Kelly 2024-11-19 23:26:18 -07:00
parent be07ce40ed
commit 7c9403273f
5 changed files with 54 additions and 32 deletions

View File

@ -25,7 +25,9 @@ const IRON_DAMPING := 9999.0
## Base damage inflicted on impact with a player
@export var base_damage := 15.0
var last_contact_normal: Vector3
var _last_contact_normal: Vector3 = Vector3.UP
var _position_on_last_wake: Vector3
var _awake := false
var _zones: Array[BallZone] = []
@onready var normal_physics: PhysicsMaterial = preload(
@ -50,15 +52,20 @@ func _total_terrain_angular_damping() -> float:
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
if not _awake:
# Triggered on first frame after waking
_awake = true
_position_on_last_wake = global_position
_last_contact_normal = Vector3.UP
var damping := air_damping
if iron_ball:
damping = iron_damping
elif state.get_contact_count():
if state.get_contact_count():
_last_contact_normal = state.get_contact_local_normal(0)
damping = _total_terrain_angular_damping()
if damping <= TERRAIN_DAMPING_EPSILON:
damping = rough_damping
last_contact_normal = state.get_contact_local_normal(0)
_debug_draw.queue_redraw()
if iron_ball:
damping = iron_damping
angular_damp = damping
@ -71,3 +78,17 @@ func enter_zone(zone: BallZone) -> void:
func exit_zone(zone: BallZone) -> void:
_zones.erase(zone)
func get_reoriented_basis() -> Basis:
var up := _last_contact_normal.normalized()
var forward := (_position_on_last_wake - global_position).normalized()
var right := up.cross(forward).normalized()
forward = right.cross(up) # orthonormalize
return Basis(right, up, forward)
func _on_sleeping_state_changed() -> void:
if sleeping:
# Trigger to reassign on wake
_awake = false

View File

@ -31,17 +31,30 @@ radius = 0.05
resource_name = "debug_draw"
script/source = "extends Control
const COLOR := Color(0, 1, 0)
const COLOR_X := Color(1, 0, 0)
const COLOR_Y := Color(0, 1, 0)
const COLOR_Z := Color(0, 0, 1)
const WIDTH := 4
@onready var physics_ball: GameBall = $\"..\"
func _process(_delta: float) -> void:
if visible:
queue_redraw()
func _draw() -> void:
if physics_ball.last_contact_normal != null:
if physics_ball._last_contact_normal != null:
var camera := get_viewport().get_camera_3d()
var start := camera.unproject_position(physics_ball.global_transform.origin)
var end := camera.unproject_position(physics_ball.global_transform.origin + physics_ball.last_contact_normal)
draw_line(start, end, COLOR, WIDTH)
var start := camera.unproject_position(physics_ball.global_position)
var basis := physics_ball.get_reoriented_basis()
var end_x := camera.unproject_position(physics_ball.global_position + basis.x)
var end_y := camera.unproject_position(physics_ball.global_position + basis.y)
var end_z := camera.unproject_position(physics_ball.global_position + basis.z)
draw_line(start, end_x, COLOR_X, WIDTH)
draw_line(start, end_y, COLOR_Y, WIDTH)
draw_line(start, end_z, COLOR_Z, WIDTH)
"
[node name="PhysicsBall" type="RigidBody3D"]
@ -73,3 +86,5 @@ anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = SubResource("GDScript_p4v7o")
[connection signal="sleeping_state_changed" from="." to="." method="_on_sleeping_state_changed"]

View File

@ -6,7 +6,6 @@ signal ball_collision(ball: GameBall)
@export var ignored_balls: Array[GameBall] = []
@onready var shot_setup: ShotSetup = $".."
@onready var physics_ball: GameBall = %PhysicsBall
func _on_ball_entered(ball: GameBall) -> void:

View File

@ -293,14 +293,10 @@ func travel_to_ball() -> void:
# Re-orient to the ball's last contact normal if there is one.
# Normally this will just be Vector3.UP or something close to it.
var normal := game_ball.last_contact_normal
if normal == null:
normal = Vector3.UP
var up := Vector3.BACK
if not normal.cross(up):
up = Vector3.RIGHT
look_at(global_position + normal, up)
rotate_object_local(Vector3.RIGHT, -PI / 2)
direction.rotation.y = 0
_target_rotation.y = 0
global_basis = game_ball.get_reoriented_basis()
print_debug("REORIENTED BASIS: ", global_basis)
game_ball.global_transform = ball_point.global_transform

View File

@ -1,7 +1,6 @@
[gd_scene load_steps=20 format=3 uid="uid://cy7t2tc4y3b4"]
[gd_scene load_steps=19 format=3 uid="uid://cy7t2tc4y3b4"]
[ext_resource type="Script" path="res://src/player/shot_setup/shot_setup.gd" id="1_r6ei4"]
[ext_resource type="PackedScene" uid="uid://dfttci386ohip" path="res://src/equipment/balls/physics_ball/physics_ball.tscn" id="2_1i5j5"]
[ext_resource type="PackedScene" uid="uid://c2k88ns0h5ie1" path="res://src/ui/3d/arrow/arrow.tscn" id="2_s70wl"]
[ext_resource type="PackedScene" uid="uid://dcqxlbsrubapk" path="res://src/equipment/balls/plasma_ball/plasma_ball.tscn" id="3_8dte7"]
[ext_resource type="PackedScene" uid="uid://1s3gywmoi20e" path="res://src/characters/player_characters/gfolf_girl/gfolf_girl.tscn" id="3_e4aur"]
@ -215,12 +214,6 @@ script = ExtResource("1_r6ei4")
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.08, 0)
[node name="PhysicsBall" parent="BallPoint" instance=ExtResource("2_1i5j5")]
unique_name_in_owner = true
process_mode = 4
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0)
visible = false
[node name="PlasmaBall" parent="BallPoint" instance=ExtResource("3_8dte7")]
unique_name_in_owner = true
@ -357,7 +350,7 @@ visible = false
initial_speed = 50.0
time_step = 0.01
max_steps = 800
excluded_bodies = [NodePath("../../BallPoint/PhysicsBall")]
excluded_bodies = [NodePath("../../BallPoint/PlasmaBall")]
[node name="ProjectedTarget" parent="ArrowPivot/ShotProjection" instance=ExtResource("6_mynqj")]
@ -374,13 +367,11 @@ one_shot = true
[node name="Hitbox" type="Area3D" parent="." node_paths=PackedStringArray("ignored_balls")]
script = ExtResource("7_uh8kn")
ignored_balls = [NodePath("../BallPoint/PhysicsBall"), NodePath("../BallPoint/PlasmaBall")]
ignored_balls = [NodePath("../BallPoint/PlasmaBall")]
[node name="CollisionShape3D" type="CollisionShape3D" parent="Hitbox"]
shape = SubResource("SphereShape3D_xvvdi")
[connection signal="entered_water" from="BallPoint/PhysicsBall" to="." method="_on_ball_entered_water"]
[connection signal="sleeping_state_changed" from="BallPoint/PhysicsBall" to="." method="_on_ball_sleeping_state_changed"]
[connection signal="entered_water" from="BallPoint/PlasmaBall" to="." method="_on_ball_entered_water"]
[connection signal="sleeping_state_changed" from="BallPoint/PlasmaBall" to="." method="_on_ball_sleeping_state_changed"]
[connection signal="timeout" from="BallReturnTimer" to="." method="_on_ball_return_timer_timeout"]