I am trying to create a falling effect when my player hits the ground after falling from a high distance. I have a part cloned from replicated storage with decals on it and I create an explosion and play a sound and animation. My problem is that it happens a second too late to look good. Should I go about it another way, like with raycasts (and how), or how can I make the animation, sound, decal part, etc. all happen 1 second sooner? This script is in startercharacterscripts:
local rs = game:GetService("ReplicatedStorage")
local effect = rs:FindFirstChild("Ground")
local debris = game:GetService("Debris")
local anim = rs.Ground.Animation
local animtrack = script.Parent.Humanoid:LoadAnimation(anim)
wait(5)
while true do
x = wait()
if script.Parent.Torso.Velocity.Y <= -20 then --Finds whether or not the player has begun falling and starts a timer
fallTime = fallTime + x
end
if script.Parent.Torso.Velocity.Y > -20 then --Finds when the player has stopped falling
if fallTime >= 1 then --Finds whether or not the player has been falling long enough to take damage
animtrack:Play()
local splod = Instance.new("Explosion")
splod.Position = script.Parent.HumanoidRootPart.Position + Vector3.new(0,-3,0)
splod.BlastPressure = 0
splod.BlastRadius = 0
splod.DestroyJointRadiusPercent = 0
splod.ExplosionType = Enum.ExplosionType.NoCraters
splod.Parent = game.Workspace
local falleffect = effect:Clone()
falleffect.Position = script.Parent.HumanoidRootPart.Position + Vector3.new(0,-2,0)
falleffect.Parent = game.Workspace
falleffect.Sound:Play()
for i = 0, 10 do
falleffect.Decal.Transparency = falleffect.Decal.Transparency + 0.1
falleffect.Part.Decal.Transparency = falleffect.Part.Decal.Transparency + 0.1
wait(0.1)
end
debris:AddItem(falleffect,1)
end
fallTime = 0
end
end
Also, is there any way to prevent a player from bouncing when they fall from a high distance?
I tried to anchor the player’s humanoid root part but that happened too late like everything else and it made the player hover in midair after the first bounce.
Instead of doing all of those velocity checks, you can just listen for the HumanoidStateType to change to “Landing” with the .StateChanged event of the Humanoid. This should cut down on delay times.
You should be able to anchor the HumanoidRootPart via the client when the event I explained above is fired and returns “Landing”, to stop the bouncing.
That works great, but how do I detect if they play has been falling for more than a second?
Now it plays every time the player jumps.
I tried using a statechanged to listen to falling and then an event inside that one to listen to landing and checking how long it was, but that isn’t working at all.
Here is what I have working
local fallTime = 0
local rs = game:GetService("ReplicatedStorage")
local effect = rs:FindFirstChild("Ground")
local debris = game:GetService("Debris")
local anim = rs.Ground.Animation
local animtrack = script.Parent.Humanoid:LoadAnimation(anim)
local hum = script.Parent:FindFirstChild("Humanoid")
wait(5)
hum.StateChanged:Connect(function(oldState, newState)
if newState == Enum.HumanoidStateType.Landed then
script.Parent.HumanoidRootPart.Anchored = true
hum.WalkSpeed = 0
animtrack:Play()
local splod = Instance.new("Explosion")
splod.Position = script.Parent.HumanoidRootPart.Position + Vector3.new(0,-3,0)
splod.BlastPressure = 0
splod.BlastRadius = 0
splod.DestroyJointRadiusPercent = 0
splod.ExplosionType = Enum.ExplosionType.NoCraters
splod.Parent = game.Workspace
local falleffect = effect:Clone()
falleffect.Position = script.Parent.HumanoidRootPart.Position + Vector3.new(0,-9,0)
falleffect.Parent = game.Workspace
falleffect.Sound:Play()
for i = 0, 10 do
falleffect.Decal.Transparency = falleffect.Decal.Transparency + 0.1
falleffect.Part.Decal.Transparency = falleffect.Part.Decal.Transparency + 0.1
if i == 5 then
script.Parent.HumanoidRootPart.Anchored = false
hum.WalkSpeed = 18
end
wait(0.1)
end
debris:AddItem(falleffect,1)
fallTime = 0
end
end)
Also, I think the anchoring thing isn’t helping much, so I will keep trying different things. I may need to also check if the state goes from falling to fallingdown because the impact flings the target 50% of the time.
You can yield [wait(n)] inside of the StateChanged Connection and wait how ever many seconds before it starts to count and then re-check if the HumanoidState is still “Freefall” and if it is then set a variable to true, then check if the variable is true next time when the HumanoidState is “Landing”.
Somehing like this:
local hasBeenFalling = false
hum.StateChanged:Connect(function(old,new)
if new == Enum.HumanoidState.Type.FreeFall then
wait(2)
if hum:GetState() == Enum.HumanoidState.Type.FreeFall then
hasBeenFalling = true
end
elseif new == Enum.HumanoidState.Type.Landing and hasBeenFalling then
--- play effect here
hasBeenFalling = false --- to prevent the effect from misfiring
end
)
You will also probably want to handle the edge-case of HumanoidState Event firing right before the hasBeenFalling variable gets changed, which will cause the effect to not work; I’ll leave this to you to figure out.