Did I use FastCast properly?

local function AttackPlayer(Player, character, attacktype, CurrentWeapon)

	if StunCheck(character) or AerialCheck(character) or ParryCheck(character) or StaggerCheck(character) then
		stopanimations(character)
	return end

		local caster = FastCast.new()

		local behavior = FastCast.newBehavior()

		local clone = game.ReplicatedStorage.VFX.WoodWandHeavyVFX:Clone()

		local params = RaycastParams.new()
		params.FilterType = Enum.RaycastFilterType.Exclude
		params.FilterDescendantsInstances = {}

		behavior.RaycastParams = params

		behavior.Acceleration = Vector3.new(0,-0-0)
		behavior.AutoIgnoreContainer = true
		behavior.CosmeticBulletTemplate = clone
		behavior.CosmeticBulletContainer = workspace.Projectiles

		charactersNewPunch[Player.UserId] = tick()
		
		if charactersLastPunch[Player.UserId] == nil then
			charactersLastPunch[Player.UserId] = 1
		end

		if charactersLastPunch[Player.UserId] ~= 0 then
			if charactersNewPunch[Player.UserId] - charactersLastPunch[Player.UserId] > ComboTimeuntilReset or charactersPunchCount[Player.UserId] > 4 then
				ResetCombo(Player)
			end
		end	

		charactersLastPunch[Player.UserId] = charactersNewPunch[Player.UserId]

		if charactersPunchCount[Player.UserId] <= 0 then
			charactersPunchCount[Player.UserId] = 1
		end

		local colorSequence = ColorSequence.new{
			ColorSequenceKeypoint.new(0, Color3.fromRGB(200, 206, 149)),
			ColorSequenceKeypoint.new(1, Color3.fromRGB(200, 206, 149))
		}
		
		local AttackHighlight = Instance.new("Highlight")
		AttackHighlight.Parent = character
		AttackHighlight.OutlineColor = Color3.fromRGB(235, 235, 235)
		AttackHighlight.FillColor = Color3.fromRGB(150, 150, 150)
		AttackHighlight.FillTransparency = 0.7
		AttackHighlight.OutlineTransparency = 0
		AttackHighlight.DepthMode = Enum.HighlightDepthMode.Occluded

		game.Debris:AddItem(AttackHighlight, 0.35)
		
	CantBlockModule.CantBlockWindow(character, 0.5)
		
	local CharacterIsCurrentlyRagdoll = character:GetAttribute("Ragdolled")
	local CharacterIsCurrentlyFeinting = character:GetAttribute("Feint")
	
	local function InterruptibleWait(duration, character)
		local startTime = tick()
		while tick() - startTime < duration do
			if character:GetAttribute("Feint") then
				print("Attack interrupted due to feint!")
				game.Debris:AddItem(AttackHighlight, 0)
				AttackingEvent:FireClient(Player)
				return false 
			end
			task.wait(0.05)
		end
		return true
	end
	
	local function CreateSpellCircle()
		local VFX = game.ReplicatedStorage.VFX["Magic Circle"] 
		Clone = VFX:Clone()
		Clone.Parent = workspace.Projectiles
		Clone.Anchored = true
		Clone.Transparency = 1
		Clone.CFrame = character.HumanoidRootPart.CFrame * CFrame.new(0,0,-5)

		local uniqueID = HttpService:GenerateGUID(false)
		Clone.Name = "SpellCircle_" .. character.Name .. "_" .. uniqueID -- Changed name format

		local VFXParticle = Clone.Attachment.Fire
		VFXParticle.Size = NumberSequence.new(4)
		VFXParticle.Lifetime = NumberRange.new(30)
		print(VFXParticle.Parent)

		local pointLight = Clone:FindFirstChildOfClass("PointLight")
		if pointLight then
			local tweenInfo = TweenInfo.new(
				1.5, -- Time to fade out
				Enum.EasingStyle.Quad,
				Enum.EasingDirection.Out
			)

			local goal = { Brightness = 0 }

			local tween = TweenService:Create(pointLight, tweenInfo, goal)
			tween:Play()
		else
			warn("No PointLight found in Attachment.")
		end

		task.wait(0.1)
		VFXParticle:Emit(1)
		local cloneName = Clone.Name

			clone:SetAttribute("LAST", true)
			local dir = Clone.CFrame.LookVector
			params.FilterDescendantsInstances = {character}
			behavior.RaycastParams = params
			local localcloneposition = (Clone.CFrame * CFrame.new(0,0,1.5)).Position
			caster:Fire(localcloneposition, dir, 10, behavior)

		game.Debris:AddItem(workspace.Projectiles:FindFirstChild(cloneName), 1.5)
	end
	
		caster.LengthChanged:Connect(function(ActiveCast, lastPoint, rayDir, displacement, segmentVelocity, cosmeticBulletObject)
			local newPos = lastPoint + (rayDir * displacement)

			cosmeticBulletObject.Position = newPos
		end)
		
		caster.RayHit:Connect(function(ActiveCast, RaycastResult, segmentVelocity, cosmeticBulletObject)
		coroutine.wrap(function()
			if cosmeticBulletObject:GetAttribute("LAST") == nil or cosmeticBulletObject:GetAttribute("LAST") == false then
				HitDetection.hitboxCheck(Player, character, Vector3.new(2, 2, 2), cosmeticBulletObject.CFrame, 1, 1, 0.001, CurrentWeapon, 0.5, nil, Clone.CFrame.LookVector)
			else
				HitDetection.hitboxCheck(Player, character, Vector3.new(2, 2, 2), cosmeticBulletObject.CFrame, 2, 1, 0.001, CurrentWeapon, 30, nil, Clone.CFrame.LookVector)
			end
		end)()
			cosmeticBulletObject:Destroy()
		end)

	local attackspeed = 0.45
	local recoveryspeed = 1.5

	local StrengthMultiplier = character:GetAttribute("StrengthMultiplier")
	
	if StrengthMultiplier then
		attackspeed = attackspeed / StrengthMultiplier
		recoveryspeed = recoveryspeed / StrengthMultiplier
	end
		
	local ContinueAttack = true
		
		if charactersPunchCount[Player.UserId] == 1 then
			AttackingEvent:FireClient(Player, 1)
			
		if not InterruptibleWait(attackspeed, character) then 
			print("Attack canceled mid-way!") 
			ContinueAttack = false
		end 

		if ContinueAttack and not StunCheck(character) and not CharacterIsCurrentlyRagdoll and not StaggerCheck(character) then
			coroutine.wrap(CreateSpellCircle)()
		else
			game.Debris:AddItem(AttackHighlight, 0)
		end
		elseif charactersPunchCount[Player.UserId] == 2 then
			AttackingEvent:FireClient(Player, 2)

		if not InterruptibleWait(attackspeed, character) then 
			print("Attack canceled mid-way!") 
			ContinueAttack = false
		end 

		if ContinueAttack and not StunCheck(character) and not CharacterIsCurrentlyRagdoll and not StaggerCheck(character) then
			coroutine.wrap(CreateSpellCircle)()
		else
			game.Debris:AddItem(AttackHighlight, 0)
		end
		elseif charactersPunchCount[Player.UserId] == 3 then
			AttackingEvent:FireClient(Player, 3)

		if not InterruptibleWait(attackspeed, character) then 
			print("Attack canceled mid-way!") 
			ContinueAttack = false
		end 

		if ContinueAttack and not StunCheck(character) and not CharacterIsCurrentlyRagdoll and not StaggerCheck(character) then
			coroutine.wrap(CreateSpellCircle)()
		else
			game.Debris:AddItem(AttackHighlight, 0)
		end
		elseif charactersPunchCount[Player.UserId] == 4 then
			AttackingEvent:FireClient(Player, 4)

		if not InterruptibleWait(attackspeed, character) then 
			print("Attack canceled mid-way!") 
			ContinueAttack = false
		end 

		if ContinueAttack and not StunCheck(character) and not CharacterIsCurrentlyRagdoll and not StaggerCheck(character) then
			coroutine.wrap(CreateSpellCircle)()
		else
			game.Debris:AddItem(AttackHighlight, 0)
		end
		task.wait(recoveryspeed)
		end
		charactersPunchCount[Player.UserId] += 1
	end

Hello, Basically I’m not sure if this is using the fastcast module correctly. The AttackPlayer functrion happens alot and I think I might be making to many casters. However, I haven’t found a way to do it any other way. It still works but I just want to be sure that this won’t cause any preformance issues. I’d be glad to share the whole script.

3 Likes