Dive script is spammable

so I’ve been trying to make a dive script for a game I’m making, but when I used it, I noticed that the player is able to spam the move.

script (goes in starter character scripts):

local cas = game:GetService("ContextActionService")

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:wait()
local humanoid = character:WaitForChild('Humanoid')
local humanoidRootPart = character:WaitForChild('HumanoidRootPart')

local candive = false


local currenstate = humanoid:GetState()


local function Dive()
	if candive == false then
				
				
				if currenstate == Enum.HumanoidStateType.Freefall or Enum.HumanoidStateType.Jumping then
					candive = true
				
					humanoidRootPart.Velocity = humanoidRootPart.CFrame.UpVector*50
					wait(.1)
					humanoidRootPart.Velocity = humanoidRootPart.CFrame.lookVector*110
					print(currenstate)
					print("Dive")
					if currenstate == Enum.HumanoidStateType.PlatformStanding or Enum.HumanoidStateType.Running then
						candive = false
						print("Can Dive again")
					else
						print("Darn, can't Dive yet")
					end
				end
			else
				print("Dive2")
			end
		
end


local function buttonPressFunction()
	Dive()
end
local button = cas:BindAction("DiveButton", buttonPressFunction, true, Enum.KeyCode.E,Enum.KeyCode.ButtonX)
cas:SetPosition("DiveButton", UDim2.new(0.58, -80, 0.15, -20))

There’s a line of code in the script that’s supposed to make it so you can dive until the character has touched the ground, but it was still spammable. I tried to print the humanoids current state and it said it was “running” in the air. I’m so confused

I’m not 100% sure this will fix your issue of being able to spam the dive, but replace these two lines with the following respectively:

if (currenstate == Enum.HumanoidStateType.Freefall) or (currenstate == Enum.HumanoidStateType.Jumping) then
if (currenstate == Enum.HumanoidStateType.PlatformStanding) or (currenstate == Enum.HumanoidStateType.Running) then

Just by looking at your script, the layout seems to be a bit wrong. You are setting the Candice variable to true, but can never guarantee it will be set back to false since you put that line in an if statement (meaning you would never be able to dive again).
You also print “Darn, can’t dive yet” in the wrong place (at least, by the way I’m looking at it).

Incorporate the fixes mentioned above and perhaps restructure your code.

Hope this helps. :slight_smile:

This is because you only ever define the state at the beginning of the script and never grab it again, so the state you’re printing is the state the humanoid was in when the script started running. Before any line where you need to check the value of currenstate, you should recalculate it with currenstate = humanoid:GetState() so that you’re getting the most up-to-date information.


This if statement also isn’t written exactly right. You need to include currenstate on every possible state:

if currenstate == Enum.HumanoidStateType.PlatformStanding or currenstate == Enum.HumanoidStateType.Running then

This also goes for the state check right after if candive == false then.


Finally, if the humanoid isn’t in the correct state to be able to dive immediately after using the move, how will it ever be able to dive again? There doesn’t seem to be any part of the script that resets candive to false if the check here fails:

1 Like

after modifying my script to check the latest humanoid state, I’ve came up with a solution to the “how will the script make “candive” false again?” problem.

if currenstateT == Enum.HumanoidStateType.PlatformStanding or currenstateT == Enum.HumanoidStateType.Running then
				print(currenstateT)
				candive = false
				print("Can Dive again")
			else
				print("Darn, can't Dive yet")
				repeat
					wait()
					local currenstateY
					currenstateY = humanoid:GetState()
					if currenstateY == Enum.HumanoidStateType.PlatformStanding or currenstateY == Enum.HumanoidStateType.Running then
						print(currenstateY)
						candive = false
						end
				until 
				currenstateY == Enum.HumanoidStateType.PlatformStanding or currenstateY == Enum.HumanoidStateType.Running

other than that, thanks for the solution!

1 Like
local cas = game:GetService("ContextActionService")
local players = game:GetService("Players")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:wait()
local humanoid = character:WaitForChild("Humanoid")
local hrp = character:WaitForChild("HumanoidRootPart")

local debounce = false

local function diveAction()
	if debounce then
		return
	end
	
	local currentState = humanoid:GetState()
	if currentState == Enum.HumanoidStateType.Freefall or currentState == Enum.HumanoidStateType.Jumping then
		debounce = true
		
		hrp.Velocity = hrp.CFrame.UpVector*50
		task.delay(0.1, function()
			hrp.Velocity = hrp.CFrame.LookVector*110
		end)
		
		local connection
		connection = humanoid.StateChanged:Connect(function(oldState, newState)
			if oldState == Enum.HumanoidStateType.Freefall or oldState == Enum.HumanoidStateType.Jumping then
				if newState == Enum.HumanoidStateType.Landed then
					debounce = false
					connection:Disconnect()
				end
			end
		end)
	end
end

local function onButtonClicked()
	diveAction()
end

local button = cas:BindAction("DiveButton", onButtonClicked, true, Enum.KeyCode.E, Enum.KeyCode.ButtonX)
cas:SetPosition("DiveButton", UDim2.new(0.55, 0, 0.15, 0))

This worked well when testing.

2 Likes