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!
9 Likes
game.Players.LocalPlayer only works in LocalScript
s
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.
(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