Godot Version
v4.6.1.stable.fedora [14d19694e]
Question
My CharacterBody3D object has been set to Add velocity in PlatformOnLeave option. as much i have understood about it is that it adds velocity to my object when it leaves platform as in real life we have same physics.
What does count as leaving platform? because this option didn’t work for me when i jumped on a horizontal moving platform (which is AnimatableBody3D and does animation by tweening).
In vertical moving platform, when i jump when platform is about to reach the final position, jump gets increased which results into my character jumping very higher. otherwise it works like normal jump
This moving platforms are in tweened Transition Type set to CUBIC. even if i change it to LINEAR, nothing changes.
I tired to make my character add velocity by get_platform_velocity() then adding to character velocity and it worked but why does this PlatformOnLeave doesn’t work? or am i not understanding it properly
Jump on Vertical Moving Platform
Jump on Horizontal Moving Platform
Moving Platform script
extends AnimatableBody3D
@export var a := Vector3()
@export var b := Vector3()
@export var time : float = 2.0
@export var pause : float = 0.7
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
move()
func move():
var mov_tween = create_tween().set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
mov_tween.set_loops()
mov_tween.tween_property(self, "position", b, time).set_trans(Tween.TRANS_CUBIC).set_delay(pause)
mov_tween.tween_property(self, "position", a, time).set_trans(Tween.TRANS_CUBIC).set_delay(pause)
await await mov_tween.finished
Player script
extends CharacterBody3D
const SPEED = 5.0
const JUMP_VELOCITY = 12
var xform : Transform3D
func _physics_process(delta: float) -> void:
# Get the input direction and handle the movement/deceleration.
var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
# Play robot animations
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
$AnimationPlayer.play("jump")
elif is_on_floor() and input_dir != Vector2(0,0):
$AnimationPlayer.play("run")
elif is_on_floor() and input_dir == Vector2(0,0):
$AnimationPlayer.play("idle")
# Rotate the camera left or right
if Input.is_action_just_pressed("cam_left"):
$Camera_Controller.rotate_y(deg_to_rad(30))
Global.battery -= Global.CAM_COST
if Input.is_action_just_pressed("cam_right"):
$Camera_Controller.rotate_y(deg_to_rad(-30))
Global.battery -= Global.CAM_COST
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
# Handle jump.
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
SoundManager.play_jump_sound()
velocity.y = JUMP_VELOCITY
Global.battery -= Global.JMP_COST
if input_dir != Vector2.ZERO:
Global.battery -= Global.MOV_COST * delta
var direction = ($Camera_Controller.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
# Rotate the character mesh so oriented towards the direction moving in relation to the camera
if input_dir != Vector2(0,0):
$Armature.rotation_degrees.y = $Camera_Controller.rotation_degrees.y - rad_to_deg(input_dir.angle()) -90
# Rotate the character to align with the floor
if is_on_floor():
align_with_floor($RayCast3D.get_collision_normal())
global_transform = global_transform.interpolate_with(xform, 0.3)
elif not is_on_floor():
align_with_floor(Vector3.UP)
global_transform = global_transform.interpolate_with(xform, 0.3)
if direction:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
velocity.z = move_toward(velocity.z, 0, SPEED)
move_and_slide()
# Update the hud after taking Input
var hud = get_tree().current_scene.get_node("HUD")
hud.get_node("BatteryLabel").text = str(int(Global.battery))
hud.get_node("BatteryBar").size.x = Global.BAR * ( float(Global.battery) / Global.MAX )
# Make Camera Controller match the position of player 'smoothly'
$Camera_Controller.position = lerp($Camera_Controller.position, position, 0.15)
func align_with_floor(floor_normal):
xform = global_transform
xform.basis.y = floor_normal
xform.basis.x = -xform.basis.z.cross(floor_normal)
xform.basis = xform.basis.orthonormalized()
func _on_fall_zone_body_entered(body: Node3D) -> void:
SoundManager.play_lose_sound()
body.position = Global.checkpoint_location
func bounce():
velocity.y = JUMP_VELOCITY * 0.7
func _on_finish_point_body_entered(_body: Node3D) -> void:
get_tree().change_scene_to_file("res://win_menu.tscn")
