Sword script not working

Hey devs,

So I have a script under a sword I made and it is not working. There is an error: Players.TeamDreams123.Backpack.Sword.SwordScrpt:20: attempt to index nil with 'Character' - Server - SwordScrpt:20

Here’s the code:

local tool = script.Parent
local player = game.Players.LocalPlayer
local Players = game:GetService("Players")

function humanoidTakeDamage(humanoid, damage)
	character = tool.Parent
	player = Players:GetPlayerFromCharacter(character)

	local stat = player:FindFirstChild("Stats") and player.Stats:FindFirstChild("DamagePoints")
	if stat then
		local multiplier = 1 + (stat.Value * 0.01)
		local finalDamage = damage * multiplier
		humanoid:TakeDamage(finalDamage)
	else
		humanoid:TakeDamage(damage)
	end
end

local function onEquipped()
	local character = player.Character or player.CharacterAdded:Wait() -- this is where it is erroring
	local humanoid = character:WaitForChild("Humanoid")

	local animationFolder = tool:WaitForChild("Animations")
	local idleAnimation = animationFolder:WaitForChild("Idle")

	if humanoid then
		local animator = humanoid:FindFirstChildOfClass("Animator")
		if not animator then
			animator = Instance.new("Animator")
			animator.Parent = humanoid
		end

		local animationTrack = animator:LoadAnimation(idleAnimation)
		animationTrack:Play()

		tool.Unequipped:Connect(function()
			animationTrack:Stop()
		end)
	end
end

local function onActivated()
	if character then
		local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			local target = workspace:FindPartOnRayWithIgnoreList(Ray.new(humanoidRootPart.Position, humanoidRootPart.CFrame.LookVector * 5), {character})
			if target and target.Parent then
				local targetHumanoid = target.Parent:FindFirstChild("Humanoid")
				if targetHumanoid then
					humanoidTakeDamage(targetHumanoid, 10)
				end
			end
		end
	end
end

tool.Equipped:Connect(onEquipped)
tool.Activated:Connect(onActivated)

Thank you for helping me! :heart:

9 Likes

game.Players.LocalPlayer only works in LocalScripts
Try using Players.PlayerAdded to get the player

Btw, game.Players and game:GetService("Players") are the same. Just a tip for the future
Same thing applies with things like game.ReplicatedStorage and game:GetService("ReplicatedStorage") which are both equal

Edit: I forgot this is a script inside a tool script, there is definitely a better way to get the player. Give me a moment and I will mess around with the script to fix it

6 Likes

Are you still changing up the script? Just asking.

5 Likes

Yep, I actually just finished!
You had the right idea with the tool.Parent thing in the function. I also made a few minor changes to the code to make it cleaner

local tool = script.Parent
local Players = game:GetService("Players")

local function humanoidTakeDamage(player, damage)
	local character = player.Character
	local humanoid = character:WaitForChild("Humanoid")

	local stat = player:FindFirstChild("Stats") and player.Stats:FindFirstChild("DamagePoints")
	if stat then
		local multiplier = 1 + (stat.Value * 0.01)
		local finalDamage = damage * multiplier
		humanoid:TakeDamage(finalDamage)
	else
		humanoid:TakeDamage(damage)
	end
end

local function onEquipped()
	local character = tool.Parent -- When you equip the tool, the tool is parented to the character model
	local humanoid = character:WaitForChild("Humanoid")

	local animationFolder = tool:WaitForChild("Animations")
	local idleAnimation = animationFolder:WaitForChild("Idle")

	if humanoid then
		local animator = humanoid:FindFirstChildOfClass("Animator")
		if not animator then
			animator = Instance.new("Animator")
			animator.Parent = humanoid
		end

		local animationTrack = animator:LoadAnimation(idleAnimation)
		animationTrack:Play()

		tool.Unequipped:Connect(function()
			animationTrack:Stop()
		end)
	end
end

local function onActivated()
	local character = tool.Parent
	if character then
		local player = Players:GetPlayerFromCharacter(character)
		local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			local target = workspace:FindPartOnRayWithIgnoreList(Ray.new(humanoidRootPart.Position, humanoidRootPart.CFrame.LookVector * 5), {character})
			if target and target.Parent then
				local targetHumanoid = target.Parent:FindFirstChild("Humanoid")
				if targetHumanoid then
					humanoidTakeDamage(player, 10)
				end
			end
		end
	end
end

tool.Equipped:Connect(onEquipped)
tool.Activated:Connect(onActivated)

Tell me if it does not work, I didn’t really test it lol

7 Likes

No errors get printed, but the tool doesn’t work. The damaging doesn’t work, nor does the animation.

I edited the script a little bit, but it still doesn’t work:

local tool = script.Parent
local Players = game:GetService("Players")

local animationFolder = tool:WaitForChild("Animations")
local idleAnimation = animationFolder:WaitForChild("Idle")
local attackAnimation = animationFolder:WaitForChild("Swing")

local function humanoidTakeDamage(player, damage)
	local character = player.Character
	local humanoid = character:WaitForChild("Humanoid")
	local stat = player:FindFirstChild("Stats") and player.Stats:FindFirstChild("DamagePoints")

	if stat then
		local multiplier = 1 + (stat.Value * 0.01)
		local finalDamage = damage * multiplier
		humanoid:TakeDamage(finalDamage)
	else
		humanoid:TakeDamage(damage)
	end
end

local function onEquipped()
	local character = tool.Parent
	local humanoid = character:WaitForChild("Humanoid")

	if humanoid then
		local animator = humanoid:FindFirstChildOfClass("Animator")
		if not animator then
			animator = Instance.new("Animator")
			animator.Parent = humanoid
		end

		local animationTrack = animator:LoadAnimation(idleAnimation)
		animationTrack:Play()

		tool.Unequipped:Connect(function()
			animationTrack:Stop()
		end)
	end
end

local function onActivated()
	local character = tool.Parent
	if character then
		local player = Players:GetPlayerFromCharacter(character)
		local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			local ray = Ray.new(humanoidRootPart.Position, humanoidRootPart.CFrame.LookVector * 5)
			local target, targetPosition = workspace:FindPartOnRayWithIgnoreList(ray, {character})
			if target and target.Parent then
				local targetHumanoid = target.Parent:FindFirstChild("Humanoid")
				if targetHumanoid then
					humanoidTakeDamage(player, 10)
					local sound = tool:FindFirstChild("Cut")
					if sound then
						sound:Play()
						local humanoid = character:WaitForChild("Humanoid")
						if humanoid then
							local animator = humanoid:FindFirstChildOfClass("Animator")
							if animator then
								local attackTrack = animator:LoadAnimation(idleAnimation)
								attackTrack:Play()
							end
						end
					end
				end
			end
		end
	end
end

tool.Equipped:Connect(onEquipped)
tool.Activated:Connect(onActivated)
5 Likes

Can anyone else help as it seems this guy has gone offline?

4 Likes

Animations won’t work on server scripts. You need to have a remote event firing that triggers an animation function.

5 Likes

Forgot about that. Thanks! Literally had this issue yesterday…

6 Likes

Wait, it still won’t work, and the animations won’t play. Here are my 2 scripts right now:

In the tool:

local tool = script.Parent
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local startAnim = ReplicatedStorage:WaitForChild("Events"):WaitForChild("NPCAnimation")
local stopAnim = ReplicatedStorage:WaitForChild("Events"):WaitForChild("StopAnimation")

local function humanoidTakeDamage(player, damage)
	local character = player.Character
	local humanoid = character:WaitForChild("Humanoid")
	local stat = player:FindFirstChild("Stats") and player.Stats:FindFirstChild("DamagePoints")

	if stat then
		local multiplier = 1 + (stat.Value * 0.01)
		local finalDamage = damage * multiplier
		humanoid:TakeDamage(finalDamage)
	else
		humanoid:TakeDamage(damage)
	end
end

local function onEquipped()
	local character = tool.Parent
	local humanoid = character:WaitForChild("Humanoid")

	local animator = character:WaitForChild("Humanoid"):WaitForChild("Animator")

	local damageAnimation = tool:WaitForChild("Animations"):WaitForChild("Swing")
	local damageAnimTrack = animator:LoadAnimation(damageAnimation)

	local idleAnimation = tool:WaitForChild("Animations"):WaitForChild("Idle")
	local idleAnimTrack = animator:LoadAnimation(idleAnimation)

	if humanoid then
		startAnim:FireAllClients(humanoid, idleAnimation)
		
		tool.Unequipped:Connect(function()
			stopAnim:FireAllClients(humanoid, idleAnimation)
		end)
	end
end

local function onActivated()
	local character = tool.Parent
	if character then
		local player = Players:GetPlayerFromCharacter(character)
		local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			local ray = Ray.new(humanoidRootPart.Position, humanoidRootPart.CFrame.LookVector * 5)
			local target, targetPosition = workspace:FindPartOnRayWithIgnoreList(ray, {character})
			if target and target.Parent then
				local targetHumanoid = target.Parent:FindFirstChild("Humanoid")
				if targetHumanoid then
					humanoidTakeDamage(player, 10)
					local sound = tool:FindFirstChild("Cut")
					if sound then
						sound:Play()
						local humanoid = character:WaitForChild("Humanoid")

						local animator = character:WaitForChild("Humanoid"):WaitForChild("Animator")

						local damageAnimation = tool:WaitForChild("Animations"):WaitForChild("Swing")
						local damageAnimTrack = animator:LoadAnimation(damageAnimation)

						local idleAnimation = tool:WaitForChild("Animations"):WaitForChild("Idle")
						local idleAnimTrack = animator:LoadAnimation(idleAnimation)
						startAnim:FireAllClients(humanoid, damageAnimation)
					end
				end
			end
		end
	end
end

tool.Equipped:Connect(onEquipped)
tool.Activated:Connect(onActivated)

In the localscript under StarterPlayerScripts:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local AniamteEvent: RemoteEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("NPCAnimation")
local StopEvent: RemoteEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("StopAnimation")

AniamteEvent.OnClientEvent:Connect(function(humanoid: Humanoid, animation: Animation)
	local animator = humanoid:FindFirstChildOfClass("Animator")
	animator:LoadAnimation(animation):Play()
end)

StopEvent.OnClientEvent:Connect(function(humanoid: Humanoid, animation: Animation)
	local animator = humanoid:FindFirstChildOfClass("Animator")
	animator:LoadAnimation(animation):Stop()
end)

@omgbadusernameLOL @signupredirectlol

6 Likes

For your tool script, I recommend trying this out instead of using a ray to give damage

for i, target in pairs(game.Players:GetPlayers()) do
		if target.Name ~= player.Name then
			if (target.Character.HumanoidRootPart.Position - player.Character.HumanoidRootPart.Position).magnitude < 4 then
				target.Character.Humanoid:TakeDamage("your damage value here")
			end
		end
	end

for i, target in pairs(game.Workspace:GetDescendants()) do
		if target:IsA("Humanoid") and target.Parent.Name ~= player.Name then
			if (target.Parent.HumanoidRootPart.Position - player.Character.HumanoidRootPart.Position).magnitude < 4 then
				target:TakeDamage("your damage value here")
			end
		end
	end

also maybe try running all the animations on the the client side, and see if that works. I had the same problem before also, and most times the server is unreliable when it comes to running animations.

5 Likes

Why would you fire all clients… It will stilll show for the server, even though it isn’t local.

5 Likes

So then what should I change? Only :FireClient()?

5 Likes

Judging by your code, that won’t fix the issue.

3 Likes

Yes. You need to make the player variable

local plr  = game.Players:GetPlayerFromCharacter(script.Parent)
2 Likes

That won’t change it, because, in one of my other scripts, I did the exact same thing and it worked.

image
:point_up_2: (this is from the script right now by the way.)

3 Likes

This is getting frustrating, I still need help.

2 Likes

Hello? I haven’t had help for 30 minutes! I keep on trying different strategies, but nothing is working. The only thing that is working is the damaging, but it will only damage 1 humanoid instead of multiple:

local tool = script.Parent
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local startAnim = ReplicatedStorage:WaitForChild("Events"):WaitForChild("NPCAnimation")
local stopAnim = ReplicatedStorage:WaitForChild("Events"):WaitForChild("StopAnimation")

local function humanoidTakeDamage(player, targetHumanoid, damage)
	local stat = player:FindFirstChild("Stats") and player.Stats:FindFirstChild("DamagePoints")
	local finalDamage = damage

	if stat then
		local multiplier = 1 + (stat.Value * 0.01)
		finalDamage = damage * multiplier
	end

	targetHumanoid:TakeDamage(finalDamage)
end

local function onEquipped()
	local character = tool.Parent
	local humanoid = character:WaitForChild("Humanoid")

	local animationFolder = tool:WaitForChild("Animations")
	local idleAnimation = animationFolder:WaitForChild("Idle")

	if humanoid then
		local animator = humanoid:FindFirstChildOfClass("Animator")
		if not animator then
			animator = Instance.new("Animator")
			animator.Parent = humanoid
		end

		local idleAnimTrack = animator:LoadAnimation(idleAnimation)
		idleAnimTrack:Play()

		tool.Unequipped:Connect(function()
			idleAnimTrack:Stop()
		end)
	end
end

local debounce = false
local function onTouched(hit)
	if debounce then return end
	debounce = true

	local character = tool.Parent
	if character then
		local player = Players:GetPlayerFromCharacter(character)
		local targetHumanoid = hit.Parent:FindFirstChild("Humanoid") or hit.Parent.Parent:FindFirstChild("Humanoid")
		if targetHumanoid then
			humanoidTakeDamage(player, targetHumanoid, 10)

			local sound = tool:FindFirstChild("Cut")
			if sound then
				sound:Play()
			end

			local animator = character:WaitForChild("Humanoid"):WaitForChild("Animator")
			local damageAnimation = tool:WaitForChild("Animations"):WaitForChild("Swing")
			local damageAnimTrack = animator:LoadAnimation(damageAnimation)
			damageAnimTrack:Play()
		end
	end

	wait(1) -- Cooldown time
	debounce = false
end

tool.Equipped:Connect(onEquipped)
tool.Handle.Touched:Connect(onTouched)
5 Likes

I’m just going to close this since I worked it out myself and people stopped responding.

4 Likes