In trying to make a jump pad more consistent, I came across a problem with BasePart:ApplyImpulse(). It seems that no matter what I try, it will not work when used against a player’s character model. I even tried to change the humanoid state type to Physics which did nothing. Even task.wait() was inserted to make sure each part was executed in a different frame with the same results. I’m not sure if BasePart:ApplyImpulse() is broken for players or if there is something else that I need to do. I am using it against regular BaseParts which are not part of any player’s character and it seems to work fine for those. Furthermore, the documentation isn’t adequate since there’s no code examples and it does imply that it can be used on the player’s character model even when using a server script.
This issue occurs in both Studio and in a live game.
Additional Information
Field
Value
Problem Area
Engine
Problem Component
Physics (Luau API)
First Noticed
23 Jan 2024
Impact
Medium
Priority
Medium
Annoyance Level
Medium
It’s worth noting that directly setting the BasePart.AssemblyLinearVelocity directly will launch the player, but different values need to be calculated to achieve the same result. The documentation for this states that BasePart:ApplyImpulse() should be used “if you want instantaneous change in velocity.”
Visuals
Not really.
Expectations
What I expect to happen is that the impulse is applies to the player to launch them off the pad. With the given values, the player should be launched straight up and out of the game.
You can run the root:ApplyImpulse(vector) on the client and it will work
Since the character is controlled by the client, the :ApplyImpulse does not have any effects on it from a server script. Not sure why it doesn’t replicate however remote events can fix that for you.
Here is an updated script you can use to test:
--[[
Created by Maelstorm_1973
Copyright (C)2024 Dracolynxis Technologies Inc.
Jump Pad Script
--]]
local pad = workspace:WaitForChild("JumpPad")
local jumpVector = pad:GetAttribute("JumpVector")
local debounce = false
local refMass = .05
local function getCharParts(part)
local char = part:FindFirstAncestorOfClass("Model")
if char ~= nil then
local human = char:FindFirstChild("Humanoid")
local root = char:FindFirstChild("HumanoidRootPart")
return char, human, root
end
return nil
end
pad.Touched:Connect(function(part)
if debounce == false then
debounce = true
local char, human, root = getCharParts(part)
if char == nil then
debounce = false
return
end
local mass = root.AssemblyMass / refMass
local vector = jumpVector * refMass
print(vector)
root:ApplyImpulse(vector)
task.delay(0.1, function()
debounce = false
end)
end
end)
Put this script in a local script under StarterGui.
@arxweb is correct. This issue just boils down to network ownership. The server isn’t responsible for simulating the player so applying an impulse on the server does nothing. Switching the RunContext for the script under the JumpPad to Client seems to give the expected behavior.
The documentation should be updated to reflect this. I was going crazy trying to figure out why this wouldn’t work for players when it worked for parts.
I’ve had inconsistency with physics objects or methods like this one. It especially hardly works on players who are standing on the ground. Yes, even when done on the client on their own character.
Trying to make a jump pad that doesn’t use Humanoid.Jump = true to launch off the pad. The problem with that is in my game, the jump power can change for the player, so if they have a jump powerup, they will go much further than intended. So to launch, I’m forced to use HumanoidRootPart.AssemblyLinearVelocity to get them off the pad then VectorForce for about 1 second to get them the rest of the way on inertia. So the whole thing with apply impulse would be nice if it was on the server.
Running this on the client is better because the user should have immediate feedback for this action. This is not a matter of client security, as clients can already walk themselves through thin air if they have the means to do so. Putting the jump action on the client is harmless, better for feeling, and generally recommended. Everything for player movement is mostly.
The physics seems much more consistent with the new ControllerManagers, I think regular Humanoids run their own, custom physics simulation which makes it very difficult for the normal one to apply any forces to it.
-- Jump input
local function doJump(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin and isControllerActive(cm.GroundController) then
local jumpImpulse = cm:GetAttribute("JumpImpulse")
cm.RootPart:ApplyImpulse(jumpImpulse) <--- HERE
character.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
cm.ActiveController = cm.AirController
cc: @Maelstorm_1973 You will probably have a much easier time implementing any physics mechanics in your game if you use ControllerManagers, they are based entirely on the existing physics engine.
It does seem to work on the client when using HumanoidRootPart:ApplyImpulse() to the player. So network ownership is the issue. Humanoid.Jump = true can be done on the server. There’s a couple of other things I’m going to try with this.
I could not even figure out how to set this up. The player would not be able to walk correctly, they fall over, glitch, etc. Are you sure this is easier??
It’s much more customizable, and you have much more control. Did you use the example scripts? They should set everything up, disable the default humanoid, and then start controlling the ControllerManager.