local rs = game:GetService("ReplicatedStorage")
local players = game.Players
local punchDebounces = {}
local punchDebounceDuration = 2
local punchDist = 4
local function hit(char, dmg)
print("Hit function is running")
char.Humanoid:TakeDamage(dmg)
local vF = Instance.new("VectorForce")
vF.Attachment0 = char.PrimaryPart.RootRigAttachment
vF.Force = Vector3.new(0,0,40000)
vF.Parent = char.PrimaryPart
local particle = script.PunchParticle:Clone()
particle.Parent = char.PrimaryPart
particle:Emit(30)
task.wait(0.03)
if vF.Parent ~= nil then
vF:Destroy()
end
task.wait(1)
if particle.Parent ~= nil then
particle:Destroy()
end
end
local function punch(plr)
local char = plr.Character or plr.CharacterAdded:Wait()
local punchDmg = 30
if char == nil then return end
if not char:FindFirstChild("Humanoid") then return end
if char.Humanoid.Health == 0 then return end
if punchDebounces[plr] then return end
punchDebounces[plr] = true
local punchAnim = char.Humanoid.Animator:LoadAnimation(script:WaitForChild("Punch - 1"))
punchAnim:Play()
punchAnim.KeyframeReached:Connect(function(keyframeName)
if keyframeName ~= "Damage" then
return
end
for _, player in pairs(players:GetPlayers()) do
local char = plr.Character
if char or player == plr then continue end
if (char.PrimaryPart.Position - char.PrimaryPart.Position).Magnitude <= punchDist then
coroutine.wrap(hit)(char, punchDmg)
break
end
end
for _, dummy in pairs(workspace.EnemyDummys:GetChildren()) do
if (dummy.PrimaryPart.Position - char.PrimaryPart.Position).Magnitude <= punchDist then
coroutine.wrap(hit)(dummy, punchDmg)
break
end
end
end)
task.spawn(function()
task.wait(punchDebounceDuration)
if punchDebounces[plr] then
punchDebounces[plr] = nil
end
end)
end
rs.Punch.OnServerEvent:Connect(punch)
The error message âattempt to index nil with âPositionââ suggests that you are trying to access the âPositionâ property of a nil value. This error is occurring in the following line of code:
if (char.PrimaryPart.Position - char.PrimaryPart.Position).Magnitude <= punchDist then
The issue seems to be that you are using char as the variable name for both the playerâs character and the character of another player or dummy in the loop. This causes the loop to skip over the correct character and throws an error when trying to access the âPositionâ property of a non-existent character.
To fix the error, you need to change the variable name inside the loop to something different than char. Hereâs an updated version of the loop:
for _, player in pairs(players:GetPlayers()) do
local otherChar = player.Character
if otherChar or player == plr then continue end
if (otherChar.PrimaryPart.Position - char.PrimaryPart.Position).Magnitude <= punchDist then
coroutine.wrap(hit)(otherChar, punchDmg)
break
end
end
By changing the variable name to otherChar, you avoid conflicts and correctly access the position of the other playerâs character. Make sure to replace the existing code with the updated loop in your script. Hope this helps. Let me know if I am incorrect though.
It looks like in the for loop for players:GetPlayers(), it only does the check for position if the character does not exist, which will raise and error. Try putting not in front of the char variable (if not char or player == plr then continue end).
Okay well itâs either the character or dummy doesnât have a primary part. Print both the character primary part and dummy primary part to see which exists, and probably put in an if statement to check for them.
for _, dummy in pairs(workspace.EnemyDummys:GetChildren()) do
if (dummy.PrimaryPart.Position - otherChar.PrimaryPart.Position).Magnitude <= punchDist then
coroutine.wrap(hit)(dummy, punchDmg)
break
end
end
-- Check the positions of other players
for _, player in pairs(players:GetPlayers()) do
local otherChar = player.Character
if not otherChar or player == plr then continue end
if not otherChar.PrimaryPart or not char.PrimaryPart then continue end
if (otherChar.PrimaryPart.Position - char.PrimaryPart.Position).Magnitude <= punchDist then
coroutine.wrap(hit)(otherChar, punchDmg)
break
end
end
-- Check the positions of the dummies
for _, dummy in pairs(workspace.EnemyDummys:GetChildren()) do
if not dummy.PrimaryPart or not char.PrimaryPart then continue end
if (dummy.PrimaryPart.Position - char.PrimaryPart.Position).Magnitude <= punchDist then
coroutine.wrap(hit)(dummy, punchDmg)
break
end
end
I added checks to make sure that PrimaryPart exists before trying to get its Position. If PrimaryPart does not exist, the script skips that player or dummy and continues with the next one. Another small note, in the for loop where you are checking other players, you mistakenly tried to subtract char.PrimaryPart.Position from itself instead of otherChar.PrimaryPart.Position. This has been corrected in the updated script. Hope It helps!