Double Jump Landing Effect Issue

Hi, I am trying to make a double jump effect at the feet of the user when HumanoidStateType.Landed is fired after the user’s double jump.

However, the problem is that the effect spawns above the user’s head like this:


(The little white circle is the effect)

So far, I have tried like 5-6 different refactors to fix this, but it’s still spawning above my head. :sob:

-- Client-side code:

local DoubleJumpLandingEvent = ReplicatedStorage.Events.DoubleJumpLanding
 
function onJumpRequest()
	if not character or not humanoid or not character:IsDescendantOf(workspace) or humanoid:GetState() == Enum.HumanoidStateType.Dead then
		return
	end
	
	if canDoubleJump and not hasDoubleJumped then
		hasDoubleJumped = true
		humanoid.JumpPower = oldPower * DOUBLE_JUMP_POWER_MULTIPLIER
		humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		animationTrack[1]:Play()
	end
end
 
local function characterAdded(newCharacter)
	character = newCharacter
	humanoid = newCharacter:WaitForChild("Humanoid")
	hasDoubleJumped = false
	canDoubleJump = false
	oldPower = humanoid.JumpPower
	
	local track = humanoid:LoadAnimation(doubleJumpAnimation)
	table.insert(animationTrack, track)
	
	humanoid.StateChanged:Connect(function(old, new)
		if new == Enum.HumanoidStateType.Landed then
			if hasDoubleJumped == true then
				DoubleJumpLandingEvent:FireServer()
			end
			canDoubleJump = false
			hasDoubleJumped = false
			humanoid.JumpPower = oldPower
		elseif new == Enum.HumanoidStateType.Freefall then
			wait(TIME_BETWEEN_JUMPS)
			canDoubleJump = true
		end
	end)
end
 
if localPlayer.Character then
	characterAdded(localPlayer.Character)
end
 
localPlayer.CharacterAdded:connect(characterAdded)
UserInputService.JumpRequest:connect(onJumpRequest)

As you can see, I fire the RemoteEvent DoubleJumpLanding when HumanoidStateType.Landed is triggered and the boolean variable hasDoubleJumped is true.

-- Server-side code:

DoubleJumpLanding.OnServerEvent:Connect(function(player)
	local new_ring = DoubleJumpRing:Clone()
	new_ring.Parent = player.Character
	local target_cframe = player.Character.LowerTorso.CFrame
	new_ring.CFrame = target_cframe
	TweenService:Create(
		new_ring.Mesh,
		TweenConfig,
		{
			Scale = Vector3.new(.05, .05, .05)
		}
	):Play()
	TweenService:Create(
		new_ring,
		TweenConfig,
		{
			Transparency = 1
		}
	):Play()
	wait(.2)
	new_ring:Destroy()
end)

On the server I just use routine CFraming and TweenService animations.
It’s like there is a 200ms delay between client and server… does this has something to do with character interpolation latency?

Anyway, any help would be much appreciated. Sidenote, I am aware I am setting the CFrame to the LowerTorso that’s just for testing purposes. If this worked, it would make the ring appear at the humanoid’s waste-level.

4 Likes

Is the double jump controlled by an animation?

If that’s the case, I believe the parts in the animation CFrames’ are not affected by the animation, which may be why the ring’s location is offset.

It’s late and my brain isn’t processing as well as it should be right now, so forgive me if I missed some details in your post.

I’m fairly certain the delay is caused by the client-server latency. Try making the client send the CFrame of their LowerTorso to the server on the event.
As a side-note, I strongly recommend letting the client handle all these effects (and just use the server to relay effects between players) for smooth visuals.

3 Likes

So, I do have a custom double jump animation for mid-air jumps, but that is not affecting the HumanoidStateType based on tests I’ve just run by commenting out the custom animation.

@sz_s Yes, client-side works, ty!

*Side-note: I did send the CFrame data to the server originally, but got the same behavior. So I’ll just do all of it on the client.

1 Like

This guy had same problem. He knows how to fix https://www.youtube.com/watch?v=9YqN8_VERps&t=281s