generated from krampus/template-godot4
Multi-terrain physics
This commit is contained in:
parent
5b56f9cd58
commit
cd9a58a660
|
@ -41,6 +41,7 @@ _shader_parameters = {
|
|||
"vertex_normals_distance": 128.0
|
||||
}
|
||||
texture_filtering = 1
|
||||
show_navigation = true
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ly4sm"]
|
||||
cull_mode = 2
|
||||
|
@ -199,3 +200,12 @@ mesh = SubResource("BoxMesh_20p1k")
|
|||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="DebugTable/StaticBody3D"]
|
||||
shape = SubResource("BoxShape3D_g31tw")
|
||||
|
||||
[node name="Fairway" type="Area3D" parent="."]
|
||||
script = ExtResource("9_jwlau")
|
||||
terrain_angular_damping = 2.0
|
||||
|
||||
[node name="CollisionPolygon3D" type="CollisionPolygon3D" parent="Fairway"]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 209.788, 6.20358, 256.527)
|
||||
depth = 10.0
|
||||
polygon = PackedVector2Array(-1.47594, 8.77969, -12.788, 19.9447, -17.7778, 31.2864, -19.2001, 41.1398, -19.2001, 55.4081, -16.3465, 66.9813, -15.7123, 75.8594, -14.9196, 82.6765, -12.383, 89.9692, -5.6736, 102.186, 2.88742, 115.027, 9.22891, 125.332, 14.7777, 133.893, 23.4973, 146.417, 35.7046, 159.893, 44.1071, 167.661, 55.8437, 178.18, 64.5632, 185.314, 69.7949, 189.753, 73.7584, 193.082, 80.734, 200.85, 94.5267, 212.899, 106.576, 221.46, 127.915, 233.827, 139.647, 240.802, 170.403, 256.181, 183.721, 262.839, 204.489, 271.717, 216.062, 274.571, 224.465, 279.485, 235.727, 283.429, 246.983, 289.929, 253.958, 290.88, 265.373, 296.27, 275.044, 298.965, 288.995, 299.282, 302.154, 299.599, 330.056, 297.063, 356.532, 289.612, 370.483, 282.636, 382.057, 270.112, 388.081, 259.648, 392.679, 245.221, 395.849, 226.989, 395.863, 185.922, 391.266, 164.52, 381.913, 148.636, 362.889, 133.417, 344.657, 121.051, 327.059, 111.063, 306.291, 103.136, 292.974, 102.66, 277.913, 102.66, 264.913, 105.99, 241.347, 117.315, 222.323, 125.558, 203.457, 127.144, 182.371, 123.973, 157.322, 119.534, 132.908, 107.644, 108.651, 86.0827, 88.8301, 59.386, 82.6471, 48.764, 75.6715, 25.7761, 65.063, 10.562, 56.819, 3.7449, 48.5751, -0.852661, 35.2579, -3.07219, 20.8311, -3.38925, 7.35541, 1.36685)
|
||||
|
|
|
@ -151,7 +151,10 @@ select_putter={
|
|||
[physics]
|
||||
|
||||
3d/physics_engine="JoltPhysics3D"
|
||||
3d/sleep_threshold_angular=0.3
|
||||
3d/sleep_threshold_linear=0.1
|
||||
3d/sleep_threshold_angular=2.0
|
||||
jolt_3d/sleep/velocity_threshold=0.1
|
||||
jolt_3d/sleep/time_threshold=1.0
|
||||
jolt_3d/limits/max_temporary_memory=64
|
||||
|
||||
[rendering]
|
||||
|
|
|
@ -3,14 +3,61 @@ class_name GameBall extends RigidBody3D
|
|||
|
||||
signal entered_water
|
||||
|
||||
const TERRAIN_DAMPING_EPSILON := 1e-6
|
||||
const IRON_DAMPING := 9999.0
|
||||
|
||||
## Angular damping while in air
|
||||
@export var air_damping := 0.0
|
||||
## Angular damping while in collision with rough terrain
|
||||
@export var rough_damping := 8.0
|
||||
## Angular damping for iron balls
|
||||
@export var iron_damping := 9999.0
|
||||
|
||||
## Causes the ball to act more like a brick
|
||||
@export var iron_ball := false:
|
||||
set(value):
|
||||
if value:
|
||||
physics_material_override = iron_physics
|
||||
else:
|
||||
physics_material_override = normal_physics
|
||||
iron_ball = value
|
||||
|
||||
var _zones: Array[BallZone] = []
|
||||
|
||||
@onready
|
||||
var normal_physics: PhysicsMaterial = preload("res://src/player/physics_ball/normal_physics.tres")
|
||||
@onready
|
||||
var iron_physics: PhysicsMaterial = preload("res://src/player/physics_ball/iron_physics.tres")
|
||||
|
||||
|
||||
## Called by a water area when this ball enters it
|
||||
func enter_water() -> void:
|
||||
entered_water.emit()
|
||||
|
||||
|
||||
func _total_terrain_angular_damping() -> float:
|
||||
return _zones.reduce(
|
||||
func(a: float, b: BallZone) -> float: return a + b.terrain_angular_damping, 0.0
|
||||
)
|
||||
|
||||
|
||||
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
|
||||
if state.get_contact_count():
|
||||
angular_damp = rough_damping
|
||||
else:
|
||||
angular_damp = air_damping
|
||||
var damping := air_damping
|
||||
if iron_ball:
|
||||
damping = iron_damping
|
||||
elif state.get_contact_count():
|
||||
damping = _total_terrain_angular_damping()
|
||||
if damping <= TERRAIN_DAMPING_EPSILON:
|
||||
damping = rough_damping
|
||||
angular_damp = damping
|
||||
|
||||
|
||||
func enter_zone(zone: BallZone) -> void:
|
||||
_zones.push_back(zone)
|
||||
|
||||
if zone.water_hazard:
|
||||
entered_water.emit()
|
||||
|
||||
|
||||
func exit_zone(zone: BallZone) -> void:
|
||||
_zones.erase(zone)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
[gd_resource type="PhysicsMaterial" format=3 uid="uid://cfd56nhaods5a"]
|
||||
|
||||
[resource]
|
||||
friction = 0.8
|
||||
rough = true
|
||||
bounce = 1.0
|
||||
absorbent = true
|
|
@ -0,0 +1,5 @@
|
|||
[gd_resource type="PhysicsMaterial" format=3 uid="uid://3bih72l068ic"]
|
||||
|
||||
[resource]
|
||||
friction = 0.8
|
||||
bounce = 0.5
|
|
@ -1,13 +1,10 @@
|
|||
[gd_scene load_steps=8 format=3 uid="uid://dfttci386ohip"]
|
||||
|
||||
[ext_resource type="Script" path="res://src/player/physics_ball/game_ball.gd" id="1_iwh2u"]
|
||||
[ext_resource type="PhysicsMaterial" uid="uid://3bih72l068ic" path="res://src/player/physics_ball/normal_physics.tres" id="1_l23pw"]
|
||||
[ext_resource type="Texture2D" uid="uid://ckhiq6rfjv63u" path="res://assets/textures/gfolfball/gfolfball.png" id="1_y3q5j"]
|
||||
[ext_resource type="Texture2D" uid="uid://btntjs7mbdigu" path="res://assets/textures/gfolfball/gfolfball_normal.png" id="2_mx7l6"]
|
||||
|
||||
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_2gatw"]
|
||||
friction = 0.8
|
||||
bounce = 0.5
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_xqofq"]
|
||||
albedo_texture = ExtResource("1_y3q5j")
|
||||
albedo_texture_force_srgb = true
|
||||
|
@ -32,13 +29,15 @@ radius = 0.05
|
|||
|
||||
[node name="PhysicsBall" type="RigidBody3D"]
|
||||
mass = 0.05
|
||||
physics_material_override = SubResource("PhysicsMaterial_2gatw")
|
||||
physics_material_override = ExtResource("1_l23pw")
|
||||
continuous_cd = true
|
||||
contact_monitor = true
|
||||
max_contacts_reported = 1
|
||||
linear_damp_mode = 1
|
||||
angular_damp_mode = 1
|
||||
angular_damp = 8.0
|
||||
script = ExtResource("1_iwh2u")
|
||||
iron_damping = 1e+07
|
||||
|
||||
[node name="BallMesh" type="MeshInstance3D" parent="."]
|
||||
mesh = SubResource("SphereMesh_y0d13")
|
||||
|
|
|
@ -102,7 +102,7 @@ var _tracking_camera: OrbitalCamera
|
|||
@onready var curve_animation: AnimationPlayer = %CurveAnimation
|
||||
|
||||
@onready var ball_point: Node3D = %BallPoint
|
||||
@onready var physics_ball: RigidBody3D = %PhysicsBall
|
||||
@onready var physics_ball: GameBall = %PhysicsBall
|
||||
|
||||
@onready var drive_ref: RayCast3D = %DriveRef
|
||||
@onready var drive_arrow: Node3D = %DriveArrow
|
||||
|
@ -269,6 +269,7 @@ func _on_club_change(new_club: Club.Type) -> void:
|
|||
wedge_arrow.hide()
|
||||
iron_arrow.hide()
|
||||
putt_arrow.hide()
|
||||
physics_ball.iron_ball = false
|
||||
club_selector.value = new_club
|
||||
match new_club:
|
||||
Club.Type.DRIVER:
|
||||
|
@ -290,6 +291,7 @@ func _on_club_change(new_club: Club.Type) -> void:
|
|||
# TODO
|
||||
shot_ref = iron_ref
|
||||
iron_arrow.show()
|
||||
physics_ball.iron_ball = true
|
||||
character.hold_right(Club.catalog.debug_iron.get_model())
|
||||
Club.Type.SPECIAL:
|
||||
# TODO
|
||||
|
|
|
@ -641,8 +641,6 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.08, 0)
|
|||
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 = 1
|
||||
|
||||
[node name="BallImpulseDebug" type="Node3D" parent="BallPoint"]
|
||||
unique_name_in_owner = true
|
||||
|
@ -682,7 +680,7 @@ debug_shape_thickness = 4
|
|||
|
||||
[node name="IronRef" type="RayCast3D" parent="Direction"]
|
||||
unique_name_in_owner = true
|
||||
transform = Transform3D(0.7, 0, 0, 0, 0.494975, -0.494975, 0, 0.494975, 0.494975, 0, 0.08, 0)
|
||||
transform = Transform3D(0.7, 0, 0, 0, 0.449952, -0.536231, 0, 0.536231, 0.449952, 0, 0.08, 0)
|
||||
enabled = false
|
||||
target_position = Vector3(0, 0, -1)
|
||||
collision_mask = 0
|
||||
|
@ -750,7 +748,7 @@ loop_animation = 1
|
|||
|
||||
[node name="IronArrow" type="Node3D" parent="ArrowPivot/Arrow"]
|
||||
unique_name_in_owner = true
|
||||
transform = Transform3D(0.7, 0, 0, 0, 0.494975, -0.494975, 0, 0.494975, 0.494975, 0, 0, 0)
|
||||
transform = Transform3D(0.7, 0, 0, 0, 0.449952, -0.536231, 0, 0.536231, 0.449952, 0, 0, 0)
|
||||
visible = false
|
||||
|
||||
[node name="ArrowMesh" parent="ArrowPivot/Arrow/IronArrow" instance=ExtResource("2_s70wl")]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
class_name BallZone extends Area3D
|
||||
## A spatial area that has an effect on balls inside it.
|
||||
|
||||
@export var terrain_angular_damping := 1.0
|
||||
|
||||
@export var water_hazard := false
|
||||
|
||||
|
||||
|
@ -9,20 +11,11 @@ func _ready() -> void:
|
|||
body_exited.connect(_on_body_exited)
|
||||
|
||||
|
||||
func on_ball_entered(ball: GameBall) -> void:
|
||||
if water_hazard:
|
||||
ball.entered_water.emit()
|
||||
|
||||
|
||||
func on_ball_exited(_ball: GameBall) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func _on_body_entered(body: Node3D) -> void:
|
||||
if body is GameBall:
|
||||
on_ball_entered(body as GameBall)
|
||||
(body as GameBall).enter_zone(self)
|
||||
|
||||
|
||||
func _on_body_exited(body: Node3D) -> void:
|
||||
if body is GameBall:
|
||||
on_ball_exited(body as GameBall)
|
||||
(body as GameBall).exit_zone(self)
|
||||
|
|
Loading…
Reference in New Issue