Block System Animation

Hello! I’m making a blocking system for my game but I can’t get it the animation to freeze but I also don’t want the player to be stuck in place. It’s like those battlegrounds game where the player holds “F” to block and when the animation is completed, it will stay like that until the player lets go of F.

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Block_Event = script.Parent

local Animations = ReplicatedStorage:WaitForChild("Animations")
local Hand_Block = Animations:WaitForChild("Hand_Block")
local Sword_Block = Animations:WaitForChild("Sword_Block")

local Change_Block_Part_CFrame_Connection
local Current_Playing_Block_Animation_Track

local function Create_Block_Weld_Constraint(character, HRP, Block_Part)
	local Weld_Constraint = Instance.new("WeldConstraint")
	Weld_Constraint.Name = "Block_Weld_Constraint"
	Weld_Constraint.Part0 = HRP
	Weld_Constraint.Part1 = Block_Part
	Weld_Constraint.Parent = character
end

local function Create_Block_Part()
	local Block_Part = Instance.new("Part")
	Block_Part.Massless = true
	Block_Part.CustomPhysicalProperties = PhysicalProperties.new(0.001)
	Block_Part.Name = "Block_Part"
	Block_Part.CastShadow = false
	Block_Part.Material = Enum.Material.Neon
	Block_Part.Color = Color3.fromRGB(255, 0, 0)
	Block_Part.Transparency = 0.65
	Block_Part.CanTouch = false
	Block_Part.CanCollide = false
	Block_Part.Size = Vector3.new(4, 5.25, 2.5)

	return Block_Part
end

local function Update_Block_Part_CFrame(HRP, Block_Part)
	Block_Part.CFrame = HRP.CFrame * CFrame.new(0, 0, -2)
end

local function Create_Animation_Track(Block_Animation, Animator)
	local Block_Animation_Clone:Animation = Block_Animation:Clone()
	
	Block_Animation_Clone.Parent = Animator
	
	Current_Playing_Block_Animation_Track = Animator:LoadAnimation(Block_Animation_Clone)
	Current_Playing_Block_Animation_Track.Priority = Enum.AnimationPriority.Action
end

local function On_Event(player, Blocking_Boolean)
	local character = player.Character
	local Humanoid = character:WaitForChild("Humanoid")
	local HRP = character:WaitForChild("HumanoidRootPart")
	local Animator = Humanoid:WaitForChild("Animator")
	
	if not player or not character or not Humanoid or not HRP or Humanoid.Health <= 0 or typeof(Blocking_Boolean) ~= "boolean" then return end
	
	if Blocking_Boolean == false then -- If player lets go of Block Key then destroy Block_Part and Block_Weld_Constraint
		local Block_Part = character:FindFirstChild("Block_Part")
		local Block_Weld_Constraint = character:FindFirstChild("Block_Weld_Constraint")
		
		-- Add a lot of checks to ensure that the player is blocking before unblocking
		if Block_Part and Block_Weld_Constraint and Change_Block_Part_CFrame_Connection ~= nil and Current_Playing_Block_Animation_Track ~= nil and Animator:FindFirstChildOfClass("Animation") then return end
		
		Block_Part:Destroy()
		Block_Weld_Constraint:Destroy()
		
		Change_Block_Part_CFrame_Connection:Disconnect()
		Change_Block_Part_CFrame_Connection = nil
		
		Current_Playing_Block_Animation_Track:AdjustSpeed(-1)
		Current_Playing_Block_Animation_Track.Ended:Wait()
		Current_Playing_Block_Animation_Track:Destroy()
		return
	end
	
	local Block_Part = Create_Block_Part()
	local Block_Weld_Constraint = Create_Block_Weld_Constraint(character, HRP, Block_Part)
	
	Block_Part.CFrame = HRP.CFrame * CFrame.new(0, 0, -2)
	Block_Part.Parent = character
	
	Change_Block_Part_CFrame_Connection = HRP:GetPropertyChangedSignal("CFrame"):Connect(function()
		Update_Block_Part_CFrame(HRP, Block_Part)
	end)
	
	if character:FindFirstChild("ClassicSword") then
		Create_Animation_Track(Sword_Block, Animator)
		Current_Playing_Block_Animation_Track:Play()
		
		task.wait(Current_Playing_Block_Animation_Track.Length)
		Current_Playing_Block_Animation_Track:AdjustSpeed(0)
	else
		Create_Animation_Track(Hand_Block, Animator)
		Current_Playing_Block_Animation_Track:Play()
		
		task.wait(Current_Playing_Block_Animation_Track.Length)
		Current_Playing_Block_Animation_Track:AdjustSpeed(0)
	end
end

Block_Event.OnServerEvent:Connect(function(player, Block_Status)
	On_Event(player, Block_Status)
end)

In my code, I tried to make it so it wil wait for the Animation’s TimeLength and then it freezes it; however, my animation still resets. I’ve also tried waiting for a close time that is almost around the end of the animation but it looks terrible. I don’t know how to fix this?

(Not needed but nice: Feedback on meh code >:D)

2 Likes

https://create.roblox.com/docs/reference/engine/classes/AnimationTrack#GetMarkerReachedSignal

in the animation create a keyframe where u want the animation to be paused then use ;GetMarkerReachedSignal() and use AdjustSpeed(0) to pause it

Wait why does task.wait(x) not work though and I also want the animation to be fully played so the player looks like they’re actually blocking

Im not sure why the task.wait(x) doesn’t work but could u explain what u mean by “I also want the animation to be fully played so the player looks like they’re actually blocking” ? it plays the animation then pauses it when it reaches the desired keyframe. you can then unpause the animation

I want the animation to reach its end and then pause it there to make it look like the player is blocking but it’ll automatically reset

Add a marker event to your animation right before it ends and in your code when the animation reaches the marker adjust the speed to 0. Waiting the length of the animation and then pausing won’t work as the animation already ended.

i think there is a delay for the event to be fired like remote events right?

This event is completely different from a remote event, there would be no network delay here as seen in a remote event. Adding a marker should work just fine and convenient, that’s the best way to go.

Oh alright, I will try that! :smiley:

Wait, let’s say I put it at 0.99, will the animation still freeze or do I have to put it at an earleir time?

Why don’t you try it and see?‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎

How do I create a marker event without having to make a new keyframe or do I need another keyframe?

https://create.roblox.com/docs/animation/events

1 Like
Current_Playing_Block_Animation_Track:GetMarkerReachedSignal("Freeze_Sword_Block_Animation"):Connect(function()
			Current_Playing_Block_Animation_Track:AdjustSpeed(0)
		end)

Is this how to correctly do it?

Yes. Before posting , try it yourself first and if anything unexpected occurs then post with that information included.


I put it at 0.5 and this is definitely how it’s not supposed to look like lol

If you put it at .5, it will pause when it reaches 50% of the animation

I adjusted the marker to be at 0.9 but the results are still the same

Well that’s how you are supposed to pause your animation at a specific point of time. Debug your code, verify that you have implemented it properly and so and make sure to disconnect the connections.

image
Oh dang, I guess I do have to move it back a little bit? I thought there was no delay