I think the title is self explanatory. How can I stop the player from bouncing when they hit the ground after a high jump?
Here is a proposed solution… but it may be too hard to execute if you have multiple floors. May get boring if you have multiple floors after a while.
The floor has a script that has an Instance.Touched event. When fired, the script will attempt to identify if there is a HumanoidRootPart. If so, the script will temporarily anchor the HumanoidRootPart, then proceed to unanchor.
I actually do have a ton of different floors, I can always put them all in a folder and iterate through them and make all of them do that when they are touched with one relatively short script, but I’ll wait to see if there’s a better solution so I don’t have to bother
I mean you can just duplicate them all and manually go drag them. If your floors have a certain feature other objects don’t, you can perhaps use the command bar with a for loop in combination with an if statement to see if the objects have that one unique trait.
I think an easier solution, it doesn’t have the risk of not working if the script is too slow:
Add a body mover inside the character’s HumanoidRootPart with a really large amount of force and simply enable it once the right/left foot touches a part that has a tag.
Sample code:
local CollectionService = game:GetService("CollectionService")
-- tag everything that is a floor
local foot = -- same comment as below
local forceintherootpart = -- insert here
local debounce = false
foot.Touched:Connect(function(part)
if debounce or not CollectionService:HasTag(part, "Floor") then
return
end
debounce = true
forceintherootpart.Enabled = true
wait(2)
forceintherootpart.Enabled = false
debounce = false
end)
It’s also easier to use if you have a lot of floors.
Thanks, I’ll try that out when I can
Make sure you tag everything that’s a floor though. There are plugins that let you add tags easily.
Hey. I have no idea if you already know about the HumanoidStateType, well you could use it. There is actually an event for it, StateChanged, you could check if the Humanoid is freefalling (which is jumping from a heigh), and when the Humanoid landed, with the StateChanged event, then it would anchor the player, and then unanchor. I suggest using localscripts that would go to the Character.
I hope that this answer your needs. At least it is easier than copying a script in all floors as suggested above and it would be a reliable way.
I don’t know if you were talking about my script, but it doesn’t require copying a script in all floors. It’s a single script in ServerScriptService.
Also, using state changed is better. I’ll edit my post so it uses that instead of .Touched.
Oh sorry, the first comment was about making a script and add it in all floors. Though CollectionService could also work. However, if his game have a terrain, your script won’t be able to cancel the bounce as there is no “floors” on the terrain.
My game actually doesn’t have any terrain, so it should be ok
Alright, here’s the new script
I had to use raycasting with stateChanged because it doesn’t tell you the part that it hit along with the state.
Also, I used the new raycasting
local CollectionService = game:GetService("CollectionService")
-- tag everything that is a floor
local character = -- same as below
local humanoid = -- same as below
local rootpart = -- same as below
local forceintherootpart = -- insert here
local raycastParams = RaycastParams.new()
raycastParams.IgnoreWater = true
raycastParams.FilterDescendantsInstances = {character}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local downwardVector = Vector3.new(0, -10, 0)
humanoid.StateChanged:Connect(function(newState)
if newState == Enum.HumanoidStateType.Landed then
local raycastResult = workspace:Raycast(rootpart.Position, downwardVector, raycastParams)
if not raycastResult then return end
if CollectionService:HasTag(raycastResult.Instance, "Floor") then
forceintherootpart.Enabled = true
wait(1.25)
forceintherootpart.Enabled = false
end
end
end)
one thing, make sure to do this:
raycastParams.FilterDescendantsInstances[1] = newCharacter
whenever a person resets, because the character needs to be updated as well.
Yeah, I know how to use raycasting and :StateChanged(). I think instead of using collectionsService I’m gonna put all my parts in a folder and just iterate through them. Thanks for the help though!
The reason i used CollectionService is because it’s going to be faster than iterating through a bunch of parts, which is especially important because you have to enable the force quickly.
Ok, would it also enable the force quicker if I do this on the client? Earlier I had problems with a force jump script being very behind, but when I made it happen in a local script it wasn’t far behind at all.
It won’t make much of a difference if it’s on the client. Replicating a single property shouldn’t take that long.
Well, you weren’t obligated to use raycasting. ROBLOX made a script in StateChanged that creates a jumping cooldown at the bottom (can be found after scrolling down at the bottom). Their script use StateChanged and not raycasting.
I mean, if you want to have a lighter script that would work even in Terrain, then you should try to reproduce the jumping cooldown, but change the part of the cooldown to anchor and unanchor the player.
- I did use state changed.
- The raycasting was just to get the part, because there’s no other way since state changed doesn’t give you that.
I’m pretty sure roblox just checks if FloorMaterial isn’t air and the time to wait before the next jump is over for the jumping cooldown. They don’t need to find the part, so they don’t find the part.