Optimize boolean check for player skill

hello! I’m trying to make a boolean check for whenever the player performs a trick. the code works mostly as intended, but the boolean returns to false too early after the animation, allowing the player to input another trick if they mash a trick key hard enough. how can I optimize this so the player can only input another trick if and only if the animation has finally ended?
I’m also wondering if AnimationTrack.Ended would work, but my script doesn’t have references to AnimationTrack. Would using Trick.Animation.Ended work?

Code (see local function doGroundTrick)
local RS = game:GetService("ReplicatedStorage")
local CAS = game:GetService("ContextActionService")
local UIS = game:GetService("UserInputService")

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:WaitForChild("Animator")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")

local Animations = RS.Assets.Animations 

local Tricks = {
	["Compasso"] = {["Keybind"] = Enum.KeyCode.R};
	["Cartwheel"] = {["Keybind"] = Enum.KeyCode.F};
	["HookKick"] = {["Keybind"] = Enum.KeyCode.V};
}

for _, Animation in Animations:GetChildren() do
	local FoundAnimation = Tricks[Animation.Name]
	Tricks[Animation.Name] = {
		["Keybind"] = FoundAnimation and FoundAnimation.Keybind or false, 
		["Animation"] = Animator:LoadAnimation(Animation)
	}
end

isTricking = false
local function doGroundTrick(TrickName, State)
	if State ~= Enum.UserInputState.Begin then return end
	if isTricking == false then
		isTricking = true
		local Trick = Tricks[TrickName]
		assert(Trick.Animation, TrickName .. " has no animation") -- Check if the trick has an animation (assert isn't nessecary)
		Trick.Animation:Play()
	elseif isTricking == true then
		isTricking = false
	end
end

for Trick, Info in Tricks do
	if not Info.Keybind then continue end 
	CAS:BindAction(Trick, doGroundTrick, true, Info.Keybind)
end 



If the animation can play then it has a reference

AnimationTrack.Ended:Wait()

Use that, I think that will work

This 100% works, but it’s less responsive than I would like. I want the player to be able to immediately chain together tricks right after each one.

Then just do:

task.wait(AnimationTrack.Length - 0.1)

The lower the number, the closer it will be to the actual track length.

Didn’t work sadly. I can still mash and the animation will replay without going through the full duration. I also tried using Trick.Animation.Length but no dice.

Did you do the same method that @Laser_Gun5540 said but just replaced AnimationTrack.Ended:Wait() with the wait I suggested?

Also:

Here’s the function right now. Using AnimationTrack yields an error so I had to use Trick.Animation

local function doGroundTrick(TrickName, State)
	if State ~= Enum.UserInputState.Begin then return end
	local Trick = Tricks[TrickName]
	if isTricking == false then
		isTricking = true
		assert(Trick.Animation, TrickName .. " has no animation") -- Check if the trick has an animation (assert isn't nessecary)
		Trick.Animation:Play()
	elseif isTricking == true then
		Trick.Animation.Ended:Wait(Trick.Animation.Length - 0.25)
		isTricking = false
	end
end

Note that RBXScriptSignal:Wait() doesn’t accept any arguments.

You mean “how can I fix this”. The word “optimize” isn’t correct here.

I wrote your doGroundTrick function to be correct.

As a bonus, it’s now idiomatic and self-documenting.

local function doGroundTrick(trickName, inputState)
	if inputState ~= Enum.UserInputState.Begin or isTricking then
		return
	end

	local trick = Tricks[trickName]
	local animTrack = trick.Animation

	isTricking = true
	animTrack:Play()

	animTrack.Stopped:Once(function()
		isTricking = false
	end)
end

You should have better luck using the Stopped event rather than the Ended event since Ended fires after the animation’s fade-out has ended.

thank you! I’ll try this in a few hours since I’m at school right now.

Yeah you can’t just wait like that.

Fixed code:

local function doGroundTrick(TrickName, State)
	if State ~= Enum.UserInputState.Begin then return end
	local Trick = Tricks[TrickName]
	if isTricking == false then
		isTricking = true
		assert(Trick.Animation, TrickName .. " has no animation") -- Check if the trick has an animation (assert isn't nessecary)
		Trick.Animation:Play()
	elseif isTricking == true then
		task.wait(Trick.Animation.Length - 0.25)
		isTricking = false
	end
end

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