Works fairly well, although it doesn't account for changing acceleration which happens due to the changing gravity. I guess this is good enough, since it does hit if the player isn't careful
44 lines
1.3 KiB
GDScript
44 lines
1.3 KiB
GDScript
extends KinematicBody
|
|
class_name MovingPlatform
|
|
|
|
|
|
var time_passed := 0.0
|
|
var distance_to_pivot := 0.0
|
|
var velocity := Vector3.ZERO
|
|
|
|
export(float) var move_speed = 2.0
|
|
export(NodePath) var solar_system
|
|
|
|
|
|
func _process(delta):
|
|
# Move the platform using the pivot and sin/cos.
|
|
# Theoretically we could just use the gravity from the solar system and actually orbit, but
|
|
# that seems like it'd get unstable very easily.
|
|
|
|
if distance_to_pivot == 0.0:
|
|
distance_to_pivot = get_parent().global_transform.origin.distance_to(global_transform.origin)
|
|
|
|
time_passed += delta
|
|
var speed_multiplier = (1.0 / distance_to_pivot) * move_speed
|
|
|
|
var translation_before = translation
|
|
|
|
translation = Vector3(0.0,
|
|
cos(time_passed * speed_multiplier) * distance_to_pivot,
|
|
sin(time_passed * speed_multiplier) * distance_to_pivot
|
|
)
|
|
|
|
velocity = (translation - translation_before) / delta
|
|
|
|
# Rotate according to gravity
|
|
var gravity_acceleration = get_node(solar_system).get_gravitation_acceleration(global_transform.origin)
|
|
|
|
# Rotate down vector to face center of gravity
|
|
var down = gravity_acceleration
|
|
var local_down = transform.basis * Vector3.DOWN
|
|
var angle = local_down.angle_to(down)
|
|
var axis = local_down.cross(down).normalized()
|
|
|
|
if axis != Vector3.ZERO: # Happens if we're perfectly aligned already (local_down and down are equal)
|
|
rotate(axis, angle)
|