Detecting when a player is falling from inside a tool,but only when the tool has been activated once,is equipped,and the player has not landed(SOLVED)

  1. What do you want to achieve?
    I have been making a nifty little umbrella that makes a player float up a bit and then back down when used. as far as actually moving goes, it works just fine, but the Client side of things is getting a little complicated as far as humanoid state detection for falling goes. The fall animation playing, and the disabling of the vector force inside of the umbrella, all depend on the tool detecting that the player is in the process of floating down (falling), and when they hit the ground (which would then send a remote event to the server side to disable the force providing lift, which I cant do yet since the detection is all wonky, which is why in the upcoming video I jump really high after using it)

  2. What is the issue?
    The issue is that, while the script can detect when the humanoids state is changed, it will continue to do so even after the tool is unequipped, and when the tool has already been used once(its only able to be used once every time it is equipped, the player would then have to unequip it and reequip it to use it again after a short cool down), and it seems to duplicate its detections every time the tool is activated, which I fear will cause lag. I have the script print “checking state” every time the humanoid state is changed, and you can see the print number go up faster when the tool has been unequipped and reused. (the print is not visible in the video sadly)
    robloxapp-20221013-2152217.wmv (4.1 MB)
    The Falling animation should not play after the umbrella has been used once, the player has hit the ground, and the idle animations begins again. As you can see, if I jump again, the falling animation will play again, as if its my new character falling animation. This does not persist after the umbrella has been unequipped, but it does interfere with how it operates. As I said before, the print message duplicates after every usage, as shown here:

This is the script on the client: --its a little bit long sorry!

local character = game.Players.LocalPlayer

local tool = script.Parent
local storage = game:GetService(“ReplicatedStorage”)
local event = storage:WaitForChild(“UmbrellaTakeOff”)–remote event and some other usual stuff above

local IdleAnim = script.Parent:WaitForChild(“Idle”) --loading in animations
local OpenAnim = script.Parent:WaitForChild(“Open”)
local FallAnim = script.Parent:WaitForChild(“Fall”)

local handle = script.Parent.handlePiece – handle of tool and a sound
local sound = handle:WaitForChild(“WOOSH”)

local CoolDown = false – various variables I used to try and fix the issues
local equipped = false

local M6D --unspecified variables that are specified later on so that functions can see them from within other functions
local Humanoid
local idleAnimation
local openAnimation
local fallAnimation

tool.Equipped:Connect(function()–equipped
equipped = true
M6D = Instance.new(“Motor6D”)
M6D.Parent = script.Parent.Parent:FindFirstChild(“UpperTorso”)–create a new motor 6d for animations to work (this one runs on the client side just to make it look nicer)
M6D.Part0 = script.Parent.Parent:FindFirstChild(“UpperTorso”)
M6D.Part1 = handle

Humanoid = tool.Parent:FindFirstChildWhichIsA("Humanoid")
IdleAnimation = Humanoid.Animator:LoadAnimation(IdleAnim)--Idle Anim
openAnimation = Humanoid.Animator:LoadAnimation(OpenAnim)--Open Anim
fallAnimation = Humanoid.Animator:LoadAnimation(FallAnim)--fall anim
IdleAnimation:Play()

end)

tool.Activated:Connect(function()–activated
if CoolDown == false then
print(“ToolActivated”)
CoolDown = true
IdleAnimation:Stop()
openAnimation:Play()
event:FireServer(character)

	Humanoid.StateChanged:Connect(function()
		print("checking state!")
		if Humanoid:GetState() == Enum.HumanoidStateType.Freefall and equipped == true then
		fallAnimation:Play()
		else
			if equipped == true then
				fallAnimation:Stop()
				IdleAnimation:Play()
			end
			
		end
	end)
end

end)

tool.Unequipped:Connect(function()–unequipped
print(“ToolUnequipped!”)
equipped = false
CoolDown = false
fallAnimation:Stop()
IdleAnimation:Stop()
openAnimation:Stop()
M6D:Destroy()
wait(2)
end)
3. What solutions have you tried so far?
I have tried using multiple true/false variables as you can see above, and I have tried detecting using “get floor material”, but nothing has worked. The duplication problem persists, and the detection continues detecting even after the player has landed. The duplication problem seems like something that could really lag a server if left to sit over time, and I don’t even need it to be checking after that point. It seems to run in a similar way to a “while loop” in the sense that it just repeats forever, but I cant fathom why it doesn’t acknowledge the fact that the “equipped” variable is equal to false when the umbrella is unequipped, or why the checks multiply every time the umbrella is unequipped.

This is my first time ever making a post on the dev forum (if you cant already tell, haha), and I am far from a pro scripter, so I am sorry if I messed any of this up or made it hard to read. I really am stumped, and I really don’t want to change how the umbrella operates in order to fix this issue. I might not respond very fast, since I have school, but some advice from the pros would be really nice.

Thanks a ton in advance, even if you don’t end up being able to help me and just skimmed this.

1 Like

I have found a solution, but It has changed how the umbrella functions, and I have figured out why the print messages kept duplicating. I would still love to hear peoples thoughts on potential solutions for this problem, because I would be very happy to have a functioning version that works the way this one would have. Thanks.

The issue is your StateChanged function is completely referenced inside the activated function and there’s no way for the unequipped function to disconnect it.

What you want to do is put a variable outside the functions that the tool.Activated function can attach the StateChanged function to.

local HumanoidStateChangedConnection = nil

You then would change the initial line for the StateChanged function in your tool.Activated function:

-- Assigns our new variable above the connection
HumanoidStateChangedConnection = Humanoid.StateChanged:Connect(function()

In your tool.Unequipped function you then put in the following to disconnect the connection:

-- Checks if there is a connection incase the player never clicked
if HumanoidStateChangedConnection then
   HumanoidStateChangedConnection:Disconnect()
end
1 Like

Nice, I will go and try that out in a bit and see if it works! thanks a ton!

What a bona fide, certified hero. Thanks a million.