Sword ground smash

ok so how would i go about making a sword ground smash. basically if u click midair you fall and then like smash the ground with the sword. how would i go about coding the anims:
problems include making the sword lift during click and then smashing ground when u hit ground.
making the anim clean (like not weird stop and starts)
possibly detecting ground touch earlier than a loop checking if freefalling/jumping ended

I would recommend doing it in steps. First do the animation, then think about how to script it and finally do the VFX.

1 Like

well i’m asking about configuring animation so that it pauses when sword above head and unpauses whrn you touch ground so like it’s a ground smash or (i think more preferable option) on how i would detect when player a bit before touching the ground so that anim will be in sync with hitting ground better

A valid question: Is this for a cinematic or an ability in your game?

Here is how i would do it:

  1. When the player attacks we get his HumanoidStateType and check if its freefalling.
  2. If not we do a regular attack, otherwise we play the falling animation with his sword above his head and listen to the Humanoid.StateChanged event to see if the humaoid is still freefalling.
  3. If not we play the slam animation, do VFX , do hitboxes , blah blah blah.

Here is a short script i made. I tested it so it should work just fine
Script(In StarterCharacterScripts):

--Services
local playerService = game:GetService("Players")
local UIS = game:GetService("UserInputService")
--Objects
local player = playerService.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum: Humanoid = char:FindFirstChild("Humanoid")
local animator: Animator = hum:FindFirstChild("Animator")
--Values
local debounce = false

local function attack()
	--A debounce to prevent spamming
	if debounce then return end
	debounce = true
	
	print("Attacking")
	
	if hum:GetState() == Enum.HumanoidStateType.Freefall then
		print("Falling")
		--We create an event that the code will yield until it is fired.
		local playerLanded = Instance.new("BindableEvent")
		
		local fallingAnim = animator:LoadAnimation("(AnimationObject)")
		local slamAnim  = animator:LoadAnimation("(AnimationObject)")
		
		fallingAnim:Play()
		
		--Listens to the .StateChanged event of the humanoid
		local stateChangeConnection = hum.StateChanged:Connect(function()
			--If the humanoid is no longer in freefall then it landed so don't yeild the code any longer
			if hum:GetState() ~= Enum.HumanoidStateType.Freefall then
				playerLanded:Fire()
			end
		end)
		
		--Wait until the player lands
		playerLanded.Event:Wait()
		
		fallingAnim:Stop()
		slamAnim:Play()
		
		--Clean up the Connection and the BinbaleEvent to prevent Memory Leaks
		stateChangeConnection:Disconnect()
		playerLanded:Destroy()
		
		--DO hitboxes and whatever you need here
		
		print("Slam")
		
		task.wait(1) --Cooldown
		debounce = false
		
		return --We return the code so we don't normal attack as well
	end
	
	--Do normal attack
	
	task.wait(1) --Cooldown
	debounce = false
end


local function inputBegan(input : InputObject , gameProcessed : boolean)
	--If you input an inputObject while focusing on a gui it won't fire
	if gameProcessed then return end
	
	if input.UserInputType== Enum.UserInputType.MouseButton1 then
		attack()
	end
end

UIS.InputBegan:Connect(inputBegan)

Hope this helped!

it’s just gonna be part of sword combat

Create your animation and check how many milliseconds pass until the character hits the ground.

Animations have an event when they reach a certain frame. The problem is that the client may take a long time or, in the case of an exploiters, may not even execute the animation and the server may crash at that moment. That is why I recommend a synchronization that does not depend on an animation event but on the time that passes.

How it should be done
1 - The player informs the server that he wants to use the skill.
2 - The server informs the player that he can use skill X.
3 - The player executes the animation.
4 - After informing the player, the server starts the countdown to execute the effect and cause damage.

Everything should be done through RemoteEvents or RemoteFunctions. (If you are going to use RemoteFunctions, it should only be from the Player to the Server and not from the Server to the Player)

i’m confused with what the bindable event is doing

if player is falling and they press a certain key, activate function that allows the impact to happen.
when the player has fallen (“running” state), do whatever

My initial thoughts on detecting the landing (I assume you want to go way up and then down):

local hum = script.Parent:WaitForChild("Humanoid")

hum.StateChanged:Connect(function(from_state, to_state)
	--print(to_state, "-------", from_state)
end)
hum.FreeFalling:Connect(function(bool)
	if bool==false then
		print("Finished falling")
	end
end)

And then make the character be way above the HumanoidRootPart in the falling animation.
Trigger the animation on finished falling.
The animation will then go straight down and strike the ground.

The bindable event is there just as a way to make sure that the code waits until the player lands, you can also do it like this:

--Listens to the .StateChanged event of the humanoid
		local stateChangeConnection --We need to declare the RBXSignalConnection like this, so we can disconnect it inside the function
        stateChangeConnection = hum.StateChanged:Connect(function()
			--If the humanoid is no longer in freefall then it landed so don't yeild the code any longer
			if hum:GetState() ~= Enum.HumanoidStateType.Freefall then
				--DO VFX and hit detection....

                --Disconnects the Event so it dosn't fire twice 
                stateChangeConnection:Disconnect()
			end
		end)