Ball physics

This commit is contained in:
Rob Kelly 2024-11-02 19:05:49 -06:00
parent f1a6b9272d
commit d3ef8f445e
6 changed files with 132 additions and 88 deletions

File diff suppressed because one or more lines are too long

View File

@ -112,6 +112,11 @@ shot_accept={
[layer_names]
3d_physics/layer_1="Collision Geometry"
3d_physics/layer_2="Layer 3"
[physics]
3d/default_angular_damp=5.0
[rendering]

View File

@ -5,6 +5,7 @@
[sub_resource type="SphereShape3D" id="SphereShape3D_wmusx"]
[node name="FreeCamera" type="CharacterBody3D"]
collision_layer = 0
script = ExtResource("1_3gm3q")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]

View File

@ -1,5 +1,8 @@
[gd_scene load_steps=12 format=3 uid="uid://dfttci386ohip"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_2gatw"]
bounce = 0.5
[sub_resource type="Gradient" id="Gradient_66vtd"]
offsets = PackedFloat32Array(0, 0.213823)
@ -52,24 +55,21 @@ clearcoat_roughness = 0.0
material = SubResource("StandardMaterial3D_bhmcr")
radius = 0.05
height = 0.1
radial_segments = 6
rings = 6
[sub_resource type="SphereShape3D" id="SphereShape3D_0hvq6"]
radius = 0.05
[sub_resource type="SeparationRayShape3D" id="SeparationRayShape3D_psmc6"]
[node name="PhysicsBall" type="RigidBody3D"]
collision_layer = 0
mass = 0.05
physics_material_override = SubResource("PhysicsMaterial_2gatw")
continuous_cd = true
linear_damp_mode = 1
[node name="BallMesh" type="MeshInstance3D" parent="."]
mesh = SubResource("SphereMesh_l3o3t")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("SphereShape3D_0hvq6")
[node name="SpringArm3D" type="SpringArm3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.823711, 0.56701, 0, -0.56701, 0.823711, 0, 0, 0)
shape = SubResource("SeparationRayShape3D_psmc6")
spring_length = 2.0
[node name="Camera3D" type="Camera3D" parent="SpringArm3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2)

View File

@ -18,8 +18,14 @@ const ZOOM_MAX := 12.0
const ARROW_ACCELERATION := 8.0
const FREE_CAM_RETURN_TIME := 0.618
const BALL_RETURN_TIME := 0.618
@export var control_disabled := false
## In Driving Range mode, the ball can be retrieved in the shot phase.
@export var driving_range := false
@export_category("Shot Parameters")
@export var base_power := 1.0
@export var base_curve := 0.0
var base_speed: float = ProjectSettings.get_setting("game/config/controls/camera/free_camera_speed")
@ -38,6 +44,8 @@ var y_acceleration: float = ProjectSettings.get_setting(
var invert_pitch: bool = ProjectSettings.get_setting("game/config/controls/camera/invert_pitch")
var control_disabled := false
var phase: Phase:
set(value):
if value != phase:
@ -60,10 +68,15 @@ var _returning_free_camera := false
@onready var curve_bar: ProgressBar = %CurveBar
@onready var curve_animation: AnimationPlayer = %CurveAnimation
@onready var ball_point: Node3D = %BallPoint
@onready var physics_ball: RigidBody3D = %PhysicsBall
@onready var drive_ref: RayCast3D = %DriveRef
@onready var camera_distance := camera.position.z:
set = _set_camera_distance
@onready var phys_ball := preload("res://src/player/physics_ball/physics_ball.tscn")
@onready var phys_ball_scene := preload("res://src/player/physics_ball/physics_ball.tscn")
@onready var _target_rotation := Vector2(pitch.rotation.x, direction.rotation.y)
@ -100,6 +113,13 @@ func take_shot() -> void:
print("Power: ", power_bar.value)
print("Curve: ", curve_bar.value)
var impulse := drive_ref.global_basis * Vector3.ONE * base_power
print("Shot impulse: ", impulse)
physics_ball.freeze = false
physics_ball.apply_central_impulse(impulse.rotated(Vector3.UP, -PI / 2.0))
#ball_ref.visible = false
func _on_phase_change(new_phase: Phase) -> void:
match new_phase:
@ -137,6 +157,22 @@ func return_free_cam() -> void:
_returning_free_camera = false
func return_ball() -> void:
var tween := get_tree().create_tween()
physics_ball.freeze = true
(
tween
. tween_property(
physics_ball,
"global_transform",
ball_point.global_transform,
BALL_RETURN_TIME,
)
. set_trans(Tween.TRANS_SINE)
)
func _process(delta: float) -> void:
# Rotation
direction.rotation.y = lerp_angle(
@ -197,5 +233,22 @@ func _process(delta: float) -> void:
curve_animation.pause()
phase = Phase.SHOT
Phase.SHOT:
# DEBUG: reset to AIM phase
phase = Phase.AIM
# REMOVEME
if Input.is_action_just_pressed("camera_forward"):
insert_free_cam()
if driving_range and Input.is_action_just_pressed("shot_accept"):
phase = Phase.AIM
return_ball()
func _on_physics_ball_body_entered(body: Node) -> void:
print("BONK! ", body.name)
print("Rotation: ", physics_ball.rotation_degrees)
print(
"Linear velocity: ",
physics_ball.linear_velocity,
" (",
physics_ball.linear_velocity.length(),
")"
)
print("Angular velocity: ", physics_ball.angular_velocity)

View File

@ -1,42 +1,11 @@
[gd_scene load_steps=15 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/player/physics_ball/physics_ball.tscn" id="2_1i5j5"]
[ext_resource type="PackedScene" uid="uid://c2k88ns0h5ie1" path="res://src/ui/arrow.tscn" id="2_s70wl"]
[sub_resource type="SphereMesh" id="SphereMesh_bvjn0"]
radius = 0.05
height = 0.1
[sub_resource type="CapsuleMesh" id="CapsuleMesh_5uovl"]
[sub_resource type="Animation" id="Animation_dku72"]
resource_name = "show"
length = 0.42
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:visible")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:scale")
tracks/1/interp = 2
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.233333, 0.366667, 0.42),
"transitions": PackedFloat32Array(0.618, 1, 1, 1),
"update": 0,
"values": [Vector3(0.001, 0.001, 0.001), Vector3(1.1, 1.1, 1.1), Vector3(0.95, 0.95, 0.95), Vector3(1, 1, 1)]
}
[sub_resource type="Animation" id="Animation_ug2a7"]
length = 0.001
tracks/0/type = "value"
@ -93,6 +62,34 @@ tracks/1/keys = {
"values": [Vector3(1, 1, 1), Vector3(0.001, 0.001, 0.001)]
}
[sub_resource type="Animation" id="Animation_dku72"]
resource_name = "show"
length = 0.42
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:visible")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:scale")
tracks/1/interp = 2
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.233333, 0.366667, 0.42),
"transitions": PackedFloat32Array(0.618, 1, 1, 1),
"update": 0,
"values": [Vector3(0.001, 0.001, 0.001), Vector3(1.1, 1.1, 1.1), Vector3(0.95, 0.95, 0.95), Vector3(1, 1, 1)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_rw0cf"]
_data = {
"RESET": SubResource("Animation_ug2a7"),
@ -173,10 +170,17 @@ _data = {
[node name="ShotSetup" type="Node3D"]
script = ExtResource("1_r6ei4")
driving_range = true
[node name="BallMesh" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0)
mesh = SubResource("SphereMesh_bvjn0")
[node name="BallPoint" type="Node3D" parent="."]
unique_name_in_owner = true
[node name="PhysicsBall" parent="BallPoint" instance=ExtResource("2_1i5j5")]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0)
freeze = true
contact_monitor = true
max_contacts_reported = 3
[node name="PlayerReference" type="MeshInstance3D" parent="."]
unique_name_in_owner = true
@ -185,6 +189,7 @@ mesh = SubResource("CapsuleMesh_5uovl")
[node name="Direction" type="Node3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
[node name="Pitch" type="Node3D" parent="Direction"]
unique_name_in_owner = true
@ -194,12 +199,21 @@ transform = Transform3D(1, 0, 0, 0, 0.907777, 0.419452, 0, -0.419452, 0.907777,
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 6)
[node name="DriveRef" type="RayCast3D" parent="Direction"]
unique_name_in_owner = true
transform = Transform3D(-1, 6.18172e-08, -6.18172e-08, 0, 0.707107, 0.707107, 8.74228e-08, 0.707107, -0.707107, 0, 0, 0)
enabled = false
target_position = Vector3(0, 0, 1)
collision_mask = 0
collide_with_bodies = false
debug_shape_thickness = 4
[node name="Arrow" type="Node3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(0.001, 0, 0, 0, 0.000337095, 0.000941471, 0, -0.000941471, 0.000337095, 0, 0.1, 0)
transform = Transform3D(0.001, 0, 0, 0, 0.000707107, 0.000707107, 0, -0.000707107, 0.000707107, 0, 0.1, 0)
[node name="ArrowMesh" parent="Arrow" instance=ExtResource("2_s70wl")]
transform = Transform3D(0.2, 0, 0, 0, 1, 0, 0, 0, 0.2, 0, 1, 0)
transform = Transform3D(0.2, 0, 0, 0, 0.4, 0, 0, 0, 0.2, 0, 1, 0)
loop_animation = 1
[node name="ArrowAnimation" type="AnimationPlayer" parent="Arrow"]
@ -297,3 +311,5 @@ libraries = {
[node name="GaugeFlasher" type="AnimationPlayer" parent="ShotUI/ShotGauges"]
unique_name_in_owner = true
[connection signal="body_entered" from="BallPoint/PhysicsBall" to="." method="_on_physics_ball_body_entered"]