Godot Version
v4.4.1.stable.official [49a5bc7b6]
Background
I’m creating a train game and I’m using Path3D for the railways. I wanted some code to fake “centrifugal force”, so trains will fall off the railway if they go around a curve too quickly.
I put “centrifugal force” in quotes as what I’m actually calculating is a tilt_angle. When the tilt angle gets higher than a specified value that is when the train falls off.
My approach
I assumed I could do this by calculating the curve angle, using these steps:
- Calculate how far the train would move if it was moving in a straight line
- Find the closest point on the curve to the straight line point
- Get the direction from the starting point to the straight line point
- Get the direction from the starting point to the closest curve point
- Get the angle between these two directions
- Fiddle with this angle to work out the “centrifugal force”/tilt angle
Code!
Step 1:
var move_distance: float = current_speed * delta # current_speed is a float
var linear_pos: Vector3 = global_position + (-global_transform.basis.z * move_distance)
Step 2 - 5 :
class_name Railway extends Path3D
# When I call this:
# global_from = global_position of the train
# global_to = linear_pos calculated in step 1
func curve_angle(global_from: Vector3, global_to: Vector3) -> float:
var closest_from: Vector3 = to_global(curve.get_closest_point(to_local(global_from)))
# Step 2
var closest_to: Vector3 = to_global(curve.get_closest_point(to_local(global_to)))
# Step 3
var a: Vector3 = closest_from.direction_to(global_to)
# Step 4
var b: Vector3 = closest_from.direction_to(closest_to)
# Step 5
return a.signed_angle_to(b, Vector3.UP)
Step 6:
This is how I’m currently converting the curve angle into a tilt angle. This needs to be improved for sure.
# -curve_angle as I want the tilt to be towards the outside of the curve
-curve_angle * current_speed * delta
The problem
This seems to be dependent on the bake_interval of the Curve3D. Which makes sense but the outcome seems to vary more than I’d assume.
I’m not entirely sure how to convert the curve angle to “centrifugal force”/tilt angle.
Questions
- Is my approach correct?
1.1. If yes, is my code correct? - Can/should I adjust my curve code to be independent of the
bake_interval?
2.1 Or is “step 6” a better place? - Any advice for converting the curve angle into “centrifugal force”/tilt angle?