Inconsistent velocity cancel script

I’m trying to make a movement system where you can slide, and I want the player to be able to jump to cancel the slide.

I got the script to work but randomly it seems to just not work properly, jumping but not cancelling the slide or sometimes breaking the animations

I’ve tried to put a wait before the actual jump cancel can happen, but that didn’t really help me much tbh.

 -- Variables and get service
local UIS = game:GetService("UserInputService")
local keybind = Enum.KeyCode.LeftShift
local Cancel = Enum.KeyCode.Space
local canslide = true

local player = game:GetService('Players').LocalPlayer
local char = player.Character or player.CharacterAdded:wait()
local HumanoidRootPart = char:WaitForChild('HumanoidRootPart')
local Humanoid = char:FindFirstChild("Humanoid")
local loop = true
local HasDoubleJumped = false
local PreviousJump = tick()
local Dashed = false

-- Other settings


-- Animation stuff
local SlideAnim = Instance.new("Animation")
SlideAnim.AnimationId = "rbxassetid://14431552792"
local playAnim = Humanoid:LoadAnimation(SlideAnim)

-- Sound stuff
local RunSound = HumanoidRootPart:WaitForChild("Running", 10)
local JumpSound = HumanoidRootPart:WaitForChild("Jumping", 10)
local slideSound = Instance.new("Sound")
slideSound.SoundId = "rbxassetid://14433837493"
slideSound.Parent = char.HumanoidRootPart
slideSound.Volume = 0.1

-- Double jump
local function DoubleJump()
	if tick() - PreviousJump >= 0.2 then
		if Humanoid:GetState() == Enum.HumanoidStateType.Freefall and not HasDoubleJumped then
			HasDoubleJumped = true
			Humanoid.JumpPower = 70
			Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		end
	end
end

Humanoid.StateChanged:Connect(function(old, new)
	if new == Enum.HumanoidStateType.Landed then
		HasDoubleJumped = false
		Humanoid.JumpPower = 50
	elseif new == Enum.HumanoidStateType.Jumping then
		PreviousJump = tick()
	end
end)

-- This function limits Dash to only be usable once before landing
Humanoid.StateChanged:Connect(function(Landed) 
	if Landed == Enum.HumanoidStateType.Landed then
		Dashed = false
	else
		
	end
end)

UIS.JumpRequest:Connect(DoubleJump)

-- Dash and Slide part
UIS.InputBegan:Connect(function(input,gameProcessed)
	if gameProcessed then return end
	if not canslide then return end
	if input.KeyCode == keybind then
		if freefall == true and Dashed == false then -- dashes if in the air
			canslide = false
			Dashed = true
			print("You have dashed")
			
			local dash = Instance.new("BodyVelocity")
			dash.MaxForce = Vector3.new(math.huge,0,math.huge)
			dash.Velocity = char.HumanoidRootPart.CFrame.lookVector * 80
			dash.Parent = char.HumanoidRootPart
			
			for count = 1, 7 do
				
				if Humanoid.Jump == true then
					dash:Destroy()
					UIS.JumpRequest:Connect(DoubleJump)
				end
				wait(0.1)	
				dash.velocity *= 0.7
			end
			canslide = true
			dash:Destroy() -- destroys instance once finished
			
		elseif freefall == false then -- slides if on ground
			canslide = false 
			print("You have slided")
			
			playAnim:Play()
			RunSound.Volume = 0 -- disables running sound
			slideSound:Play()
			char.HumanoidRootPart.CanCollide = false
			
			local slide = Instance.new("BodyVelocity") -- creates a body velocity
			slide.MaxForce = Vector3.new(math.huge,0,math.huge)
			slide.Velocity = char.HumanoidRootPart.CFrame.lookVector * 60
			slide.Parent = char.HumanoidRootPart
			wait(0.1)
			for count = 1, 7 do
				if Humanoid.Jump == true then
					local position1 = HumanoidRootPart.CFrame.lookVector
					local position2 = HumanoidRootPart.CFrame.lookVector * 1
					local duration = 0.1
					local direction = position2 + position1
					local force = direction / duration + Vector3.new(0, workspace.Gravity * duration * 0.5, 0)
					
					char.HumanoidRootPart.CanCollide = true
					HumanoidRootPart:ApplyImpulse(force * HumanoidRootPart.AssemblyMass)
					RunSound.Volume = 1
					playAnim:Stop()
					slideSound:Stop()
					slide:Destroy()
					wait(0.2)
					canslide = true
				end
				wait(0.1)
				slide.velocity *= 0.7
			end
			char.HumanoidRootPart.CanCollide = true
			RunSound.Volume = 1
			playAnim:Stop()
			slide:Destroy()
			wait(0.2)
			canslide = true
		
			
		end	
			
	end
		
end)



while loop == true do wait(0.01) -- detects if the player is in the air or on the ground.
	if Humanoid:GetState() == Enum.HumanoidStateType.Freefall then
		freefall = true
	else
		freefall = false
	end
end

3 Likes

Based on the code, I assume that jumping at the start of the dash SHOULD dash but jumping mid dash should cancel the dash? Please describe as clearly as possible what exactly should be happening and what shouldn’t be.

The idea is that whenever shift is pressed while standing on the ground you should slide, but when you press shift while in the air. You dash forward. The next idea for it is that whenever you press jump after you have pressed shift, it will cancel the current ability where it be Shift and Dash and then jump upwards out of the current abilities movement.

My problem is that sometimes once I’ve Slided and then press jump to cancel the motion and replace the slide movement with the jump movement in it’s place I instead jump up but keeping the animation of the slide and the movement is not changed.

The other problem is sometimes the slide animation wont play even though the movement and sound is still working correctly.

The problem with the dash ability is that jumping once I have dashed is meant to replace it with a double jump. But sometimes it doesn’t launch me upwards like it should and just plays the jump animation with nothing else changed.

Hey! Sorry for the delay in response, I should be able to get back to you today.

1 Like

Your code uses varying methods to approach your goal, which is making readability more difficult than necessary. I’ve combined the while loop, and the two StateChanged functions for readability and simplicity, and I’ve reduced some lines by combining variable creations and if statements.

It’s best to use a common formatting for variable names, so I’ve edited that as well. They now all use Uppercase for objects and camalCase for variables/indexes. The DoubleJump function was connected a second time in the InputBegan function, so I’ve removed that as well. The loops had no breaks when jumping happens (which was causing the function to finish before removing the force, which is part of the reason that movement was not stopping), so I’ve fixed that. I also tracked all HumanoidStates through one function for simplicity and readability.

task.wait() is better than wait() so I’ve switched those as well. There were a couple other things that were causing code to not run at times that it should run, so I’ve made sure to fix those and test the fixes. All in all, it’s important to break down the code into simple steps and make sure everything is operating purposefully. I normally don’t fix a script like this (I would normally only assist with advice and examples) but I left you hanging for 3 days and felt a bit sorry for that. Please let me know if there is more/new problems! Good luck.

Edit: I was able to fully stop movement when a jump happens by applying the inverse of the current velocity X and Z *20 to account for assembly mass. This seemed to work excellently in tests!

-- Variables and get service
local UIS = game:GetService("UserInputService")
local Players = game:GetService("Players")

local Player = Players.LocalPlayer
local Char = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Char:WaitForChild('HumanoidRootPart')
local Humanoid = Char:FindFirstChild("Humanoid")

local keybind, cancel = Enum.KeyCode.LeftShift, Enum.KeyCode.Space
local canSlide, hasDoubleJumped = true, false
local dashed, freefall, jumping = false, false, false
local previousJump = tick()

-- Animation stuff
local SlideAnim = Instance.new("Animation")
SlideAnim.AnimationId = "rbxassetid://14431552792"
local PlayAnim = Humanoid:LoadAnimation(SlideAnim)

-- Sound stuff
local RunSound = HumanoidRootPart:WaitForChild("Running", 10)
local JumpSound = HumanoidRootPart:WaitForChild("Jumping", 10)
local SlideSound = Instance.new("Sound")
SlideSound.SoundId = "rbxassetid://14433837493"
SlideSound.Parent = Char.HumanoidRootPart
SlideSound.Volume = 0.1

-- Double jump
local function DoubleJump()
	if tick() - previousJump >= 0.2 and freefall and not hasDoubleJumped then
		previousJump = tick() -- this acts as a debounce so it needs to be here even though it is elsewhere already
		hasDoubleJumped = true
		Humanoid.JumpPower = 70
		Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
	end
end

Humanoid.StateChanged:Connect(function(old, new)
	if new == Enum.HumanoidStateType.Landed then
		canSlide = true
		jumping, hasDoubleJumped = false, false
		dashed, freefall = false, false
		Humanoid.JumpPower = 50
	elseif new == Enum.HumanoidStateType.Jumping then
		jumping, canSlide = true, false
		previousJump = tick()
	elseif new == Enum.HumanoidStateType.Freefall then
		freefall, canSlide = true, false
	end
end)

UIS.JumpRequest:Connect(DoubleJump)

-- Dash and Slide part
UIS.InputBegan:Connect(function(input,gameProcessed)
	if gameProcessed then return end
	if input.KeyCode == keybind then
		if freefall and not dashed then -- dashes if in the air
			dashed, jumping = true, false
			print("You have dashed")

			local dash = Instance.new("BodyVelocity")
			dash.MaxForce = Vector3.new(math.huge,0,math.huge)
			dash.Velocity = HumanoidRootPart.CFrame.lookVector * 80
			dash.Parent = HumanoidRootPart

			for count = 1, 7 do
				if jumping then
					HumanoidRootPart:ApplyImpulse(Vector3.new(-HumanoidRootPart.AssemblyLinearVelocity.X*20, 0, -HumanoidRootPart.AssemblyLinearVelocity.Z*20))
					break
				else
					task.wait(0.1)
					dash.velocity *= 0.7
				end
			end
			dash:Destroy() -- destroys instance once finished
		elseif not freefall then -- slides if on ground
			canSlide = false 
			print("You have slided")

			PlayAnim:Play()
			RunSound.Volume = 0 -- disables running sound
			SlideSound:Play()
			HumanoidRootPart.CanCollide = false

			local Slide = Instance.new("BodyVelocity") -- creates a body velocity
			Slide.MaxForce = Vector3.new(math.huge,0,math.huge)
			Slide.Velocity = HumanoidRootPart.CFrame.lookVector * 60
			Slide.Parent = HumanoidRootPart
			task.wait(0.1)
			for count = 1, 7 do
				if jumping then
					HumanoidRootPart:ApplyImpulse(Vector3.new(-HumanoidRootPart.AssemblyLinearVelocity.X*20, 0, -HumanoidRootPart.AssemblyLinearVelocity.Z*20))
					break
				else
					task.wait(0.1)
					Slide.velocity *= 0.7
				end
			end
			HumanoidRootPart.CanCollide = true
			RunSound.Volume = 1
			PlayAnim:Stop()
			Slide:Destroy()
		end	
	end
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.