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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user