Hello! So I added a “rocket jump” mechanic of sorts to my game, which adds a vector to an extra velocity variable, and then the velocity adds the extra velocity to itself. (so basically, extraVelocity += Vector3(blah,blah,blah), then velocity += extraVelocity)
What I want to happen is, when rocket jumping, you keep the impulse from the rocket jump but are also able to change directions and whatnot, but what actually happens is if you rocket jump, the vertical impulse gets applied, but all horizontal velocity still depends on whether you are holding a directional key or not, and has 0 horizontal velocity applied from the explosion.
My current code to handle the velocity and extra velocity looks like this (in _physics_process)
and the portion of the explosion code that applies impulse like this
func _physics_process(delta):
for o in get_overlapping_bodies():
if o is Player:
var force = (o.global_position - global_position).normalized()
force *= 3.25
o.add_extra_velocity(force)
Are you sure that you’re actually adding any horizontal extraVelocity?
Where is the explosion object located relative to the player?
Also, it would be nice to see the entire code for your movement script. Context is important.
This code moves extraVelocity towards (0, 0, 0).
Perhaps you would want to only do that if you’re grounded (i.e. is_on_floor())?
Another approach
Your velocity system is actually a little tricky. velocity is a variable inherited from CharacterBody3D and its value is modified not only in your code but also in the call to move_and_slide().
I think what you should do is modify add_extra_velocity() to be this instead:
func add_extra_velocity(vel: Vector3):
velocity += vel
…and then remove the extraVelocity altogether.
I’ve made a similar system before where I had two “extraVelocity” variables; one for each movement sub-system. The more I used that system, the more I realized how much of a headache it creates - having to select and administer multiple velocities whenever I wanted to modify the player’s velocity.
I reckon you shouldn’t be doing this. If you were to modify gravityMultiplier, your gravity would very quickly spiral to infinity. The same would happen to speed if not for the fact that you override the change through:
velocity += extraVelocity # Permanently adds extraVel every frame (not good)
# The x- and z-components are reset but the y is never.
# The y-velocity will keep increasing as long
# as extraVel is more than zero
extraVelocity.x = move_toward(extraVelocity.x, 0, speed)
extraVelocity.y = move_toward(extraVelocity.y, 0, speed)
extraVelocity.z = move_toward(extraVelocity.z, 0, speed)
…and replace them with
velocity += Vector3(extraVelocity.x, 0f, extraVelocity.y)
# Reset the extra velocity once the ground is hit
if is_on_floor() and extraVelocity.length() > 0:
extraVelocity = Vector3.ZERO
…and add this to the add_extra_velocity-function:
# Since the y-component of extraVelocity is no longer added
# in _physics_process(), it must be added here.
# (in add_extra_velocity)
velocity.y += vel.y
System Redesign
Here’s an alternate solution. This is what I usually do.
Code
I’m gonna use the variable names from your pre-existing script.
if direction:
# Movement (w. acceleration)
velocity.x = direction.x * speed * delta
velocity.z = direction.z * speed * delta
# The y-velocity and xz-velocity
var yVel = velocity.y
var xzVel = velocity.slide(Vector3.UP)
# The maximum velocity in the XZ-plane
# Here, the limit can be higher than "speed" if the player is not on the floor
var speedLimit = speed if is_on_floor() else xzVel.length()
# Clamp the XZ-velocity to the speed limit
velocity = xzVel.limit_length(speedLimit)
# Restore the y-velocity
velocity.y = yVel
else:
# Deceleration (for grounded and airborne)
if is_on_floor():
velocity.x = move_toward(velocity.x, 0, speed * delta)
velocity.z = move_toward(velocity.z, 0, speed * delta)
else
# Insert deceleration code for the air here.
# I suspect you want the player to keep flying even if they let go?
# In that case, just delete the else-statement
Let me know if either works for you. I always feel a little iffy with writing code like this without testing it. Might not work.