generated from krampus/template-godot4
Ball gets culled if velocity is low after rolling for a while
This commit is contained in:
parent
9bef191bda
commit
dafd425359
|
@ -14,7 +14,6 @@ enum Type {
|
||||||
POWER,
|
POWER,
|
||||||
}
|
}
|
||||||
|
|
||||||
const VELOCITY_SQ_EPSILON := 1e-4
|
|
||||||
const MAGNUS_SQ_EPSILON := 1e-3
|
const MAGNUS_SQ_EPSILON := 1e-3
|
||||||
|
|
||||||
## If enabled, ball ability cooldown is only reset at end of shot.
|
## If enabled, ball ability cooldown is only reset at end of shot.
|
||||||
|
@ -23,6 +22,10 @@ const MAGNUS_SQ_EPSILON := 1e-3
|
||||||
## Material physics configuration for this ball.
|
## Material physics configuration for this ball.
|
||||||
@export var terrain_physics: TerrainPhysics
|
@export var terrain_physics: TerrainPhysics
|
||||||
|
|
||||||
|
## Coefficient of the linear curve that determines the minimum speed at
|
||||||
|
## a given point in surface time below which the ball will be frozen.
|
||||||
|
@export var surface_cull_coefficient: float = 0.2
|
||||||
|
|
||||||
#@export var fluid_density := 1.225
|
#@export var fluid_density := 1.225
|
||||||
#@export var lift_coefficient := 0.05
|
#@export var lift_coefficient := 0.05
|
||||||
#@export var radius := 0.05
|
#@export var radius := 0.05
|
||||||
|
@ -116,6 +119,7 @@ func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
|
||||||
_position_on_last_wake = global_position
|
_position_on_last_wake = global_position
|
||||||
_last_contact_normal = Vector3.UP
|
_last_contact_normal = Vector3.UP
|
||||||
_shot_time_s = 0.0
|
_shot_time_s = 0.0
|
||||||
|
_surface_time_s = 0.0
|
||||||
# TODO something's fucky here... I think this gets called once after the ball sleeps
|
# TODO something's fucky here... I think this gets called once after the ball sleeps
|
||||||
|
|
||||||
if state.get_contact_count():
|
if state.get_contact_count():
|
||||||
|
@ -133,12 +137,19 @@ func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
|
||||||
primary_body = state.get_contact_collider_object(i)
|
primary_body = state.get_contact_collider_object(i)
|
||||||
|
|
||||||
_surface_terrain = Terrain.from_collision(global_position, primary_body)
|
_surface_terrain = Terrain.from_collision(global_position, primary_body)
|
||||||
_surface_time_s += state.step
|
|
||||||
|
var culling_speed_sq := pow(surface_cull_coefficient * _surface_time_s, 2) - 1
|
||||||
|
if linear_velocity.length_squared() < culling_speed_sq:
|
||||||
|
_manual_sleep()
|
||||||
else:
|
else:
|
||||||
# Ball is in the air
|
# Ball is in the air
|
||||||
_surface_terrain = Terrain.Type.NONE
|
_surface_terrain = Terrain.Type.NONE
|
||||||
_surface_time_s = 0.0
|
_surface_time_s = 0.0
|
||||||
|
|
||||||
|
var params := terrain_physics.get_params(_surface_terrain)
|
||||||
|
angular_damp = params.angular_damp
|
||||||
|
linear_damp = params.linear_damp
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
# Simulate magnus effect
|
# Simulate magnus effect
|
||||||
|
@ -146,24 +157,9 @@ func _physics_process(delta: float) -> void:
|
||||||
if magnus.length_squared() > MAGNUS_SQ_EPSILON:
|
if magnus.length_squared() > MAGNUS_SQ_EPSILON:
|
||||||
apply_central_force(magnus)
|
apply_central_force(magnus)
|
||||||
|
|
||||||
# Apply drag
|
|
||||||
var params := terrain_physics.get_params(_surface_terrain)
|
|
||||||
if linear_velocity.length() > params.linear_drag:
|
|
||||||
linear_velocity -= params.linear_drag * linear_velocity.normalized()
|
|
||||||
else:
|
|
||||||
linear_velocity = Vector3.ZERO
|
|
||||||
if angular_velocity.length() > params.angular_drag:
|
|
||||||
angular_velocity -= params.angular_drag * angular_velocity.normalized()
|
|
||||||
else:
|
|
||||||
angular_velocity = Vector3.ZERO
|
|
||||||
|
|
||||||
if linear_velocity.length_squared() < VELOCITY_SQ_EPSILON:
|
|
||||||
linear_velocity = Vector3.ZERO
|
|
||||||
if angular_velocity.length_squared() < VELOCITY_SQ_EPSILON:
|
|
||||||
angular_velocity = Vector3.ZERO
|
|
||||||
|
|
||||||
# Keep shot time
|
# Keep shot time
|
||||||
_shot_time_s += delta
|
_shot_time_s += delta
|
||||||
|
_surface_time_s += delta
|
||||||
|
|
||||||
|
|
||||||
func enter_zone(zone: BallZone) -> void:
|
func enter_zone(zone: BallZone) -> void:
|
||||||
|
@ -194,11 +190,17 @@ func _on_sleeping_state_changed() -> void:
|
||||||
_awake = false
|
_awake = false
|
||||||
|
|
||||||
|
|
||||||
|
func _manual_sleep() -> void:
|
||||||
|
freeze = true
|
||||||
|
linear_velocity = Vector3.ZERO
|
||||||
|
angular_velocity = Vector3.ZERO
|
||||||
|
manual_sleep_timer.start()
|
||||||
|
|
||||||
|
|
||||||
func _on_collision(body: Node) -> void:
|
func _on_collision(body: Node) -> void:
|
||||||
if is_sticky():
|
if is_sticky():
|
||||||
# Freeze physics as soon as we hit something
|
# Freeze physics as soon as we hit something
|
||||||
freeze = true
|
_manual_sleep()
|
||||||
manual_sleep_timer.start()
|
|
||||||
|
|
||||||
var terrain := Terrain.from_collision(global_position, body)
|
var terrain := Terrain.from_collision(global_position, body)
|
||||||
print_debug("Collision terrain: ", Terrain.Type.keys()[terrain])
|
print_debug("Collision terrain: ", Terrain.Type.keys()[terrain])
|
||||||
|
|
|
@ -19,53 +19,53 @@
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_casfi"]
|
[sub_resource type="Resource" id="Resource_casfi"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 0.0
|
linear_damp = 0.2
|
||||||
angular_drag = 1.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_3k63c"]
|
[sub_resource type="Resource" id="Resource_3k63c"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 0.0
|
linear_damp = 0.0
|
||||||
angular_drag = 0.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_xf73q"]
|
[sub_resource type="Resource" id="Resource_xf73q"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 0.0
|
linear_damp = 0.5
|
||||||
angular_drag = 1.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_nhn3l"]
|
[sub_resource type="Resource" id="Resource_nhn3l"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 0.0
|
linear_damp = 0.1
|
||||||
angular_drag = 1.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_m3wjo"]
|
[sub_resource type="Resource" id="Resource_m3wjo"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 0.0
|
linear_damp = 0.2
|
||||||
angular_drag = 1.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_h4rld"]
|
[sub_resource type="Resource" id="Resource_h4rld"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 0.0
|
linear_damp = 0.1
|
||||||
angular_drag = 1.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_j6lib"]
|
[sub_resource type="Resource" id="Resource_j6lib"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 0.0
|
linear_damp = 0.5
|
||||||
angular_drag = 1.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_7f7ql"]
|
[sub_resource type="Resource" id="Resource_7f7ql"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 0.0
|
linear_damp = 1.0
|
||||||
angular_drag = 3.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_pusmf"]
|
[sub_resource type="Resource" id="Resource_pusmf"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 1.0
|
linear_damp = 4.0
|
||||||
angular_drag = 10.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_edkxb"]
|
[sub_resource type="Resource" id="Resource_edkxb"]
|
||||||
script = ExtResource("4_onl6o")
|
script = ExtResource("4_onl6o")
|
||||||
linear_drag = 0.0
|
linear_damp = 0.2
|
||||||
angular_drag = 1.0
|
angular_damp = 0.0
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_3ngau"]
|
[sub_resource type="Resource" id="Resource_3ngau"]
|
||||||
script = ExtResource("3_52hui")
|
script = ExtResource("3_52hui")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class_name TerrainParameters extends Resource
|
class_name TerrainParameters extends Resource
|
||||||
## Physical parameters for an individual terrain type.
|
## Physical parameters for an individual terrain type.
|
||||||
|
|
||||||
@export var linear_drag := 0.0
|
@export var linear_damp := 0.0
|
||||||
@export var angular_drag := 0.0
|
@export var angular_damp := 0.0
|
||||||
|
|
|
@ -63,7 +63,8 @@ var _cached_vel: Vector3
|
||||||
|
|
||||||
func set_ball(ball: GameBall) -> void:
|
func set_ball(ball: GameBall) -> void:
|
||||||
global_position = ball.global_position
|
global_position = ball.global_position
|
||||||
linear_damp = ball.linear_damp
|
linear_damp = ball.terrain_physics.default.linear_damp
|
||||||
|
print("using linear damp: ", linear_damp)
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
|
|
Loading…
Reference in New Issue