What do you want to achieve? Raycast working properly
What is the issue? Raycast after not hitting a humanoidrootpart errors " attempt to index nil with ‘Position’ " https://medal.tv/games/roblox-studio/clips/x3OTFmdhUTKxl/d1337BK0MxAy?invite=cr-MSx1dFYsOTEyNTA1OTks
What solutions have you tried so far? i looked on devforum,youtube and tried to fix it myself
local RS = game:GetService("ReplicatedStorage")
local DamageEvent = RS.Events:FindFirstChild("DamageEvent")
DamageEvent.OnServerEvent:Connect(function(player, DamagedPlayer, Damage,tool1,spread1)
local tool = workspace[player.Name][tool1]
local ShootPart = tool.ShootPart
local AlreadyShooting = tool.AlreadyShooting
local EquippedValue = tool.EquippedValue
local Ammo = tool.Ammo
if DamagedPlayer and DamagedPlayer:FindFirstChild("Humanoid") and player:DistanceFromCharacter(DamagedPlayer.HumanoidRootPart.Position) <= RS.GunStats[tool1].MaxRange.Value then
for i=1,RS.GunStats[tool.Name].AmmoPerVolley.Value do
if AlreadyShooting.Value == true and EquippedValue.Value == true and Ammo.Value > 0 and player:DistanceFromCharacter(DamagedPlayer.HumanoidRootPart.Position) <= RS.GunStats[tool1].MaxRange.Value and DamagedPlayer.Name ~= player.Name and DamagedPlayer.Humanoid.Health > 0 then
local RaycastParamss = RaycastParams.new() RaycastParamss.IgnoreWater = true
tool.Ammo.Value -= 1
tool.ToolTip = "["..tool.Ammo.Value.."/"..RS.GunStats[tool.Name].Ammo.Value.."]"
local distance = (ShootPart.Position - DamagedPlayer:FindFirstChild("HumanoidRootPart").Position).Magnitude
local spread = math.random((spread1 * 100 - spread1*100*2),spread1*100)/100
local HumanoidRootPartSpreded = DamagedPlayer:FindFirstChild("HumanoidRootPart").Position + Vector3.new(spread * distance,spread * distance,0)
local result = workspace:Raycast(ShootPart.Position,HumanoidRootPartSpreded - ShootPart.Position)
local distance2 = (ShootPart.Position - result.Position).Magnitude
if result and result.Instance.Parent:FindFirstChild("Humanoid") and result.Instance.Parent.Name ~= player.Name then
result.Instance.Parent.Humanoid:TakeDamage(Damage)
end
local p = Instance.new("Part")
p.Parent = workspace.RayCasts
p.CanQuery = false
p.Anchored = true
p.CanCollide = false
p.Size = Vector3.new(0.1,0.1,distance2)
p.BrickColor = BrickColor.new("Yellow flip/flop")
p.Material = Enum.Material .Neon
p.Transparency = 0.9
p.CFrame = CFrame.lookAt(ShootPart.Position,result.Position)*CFrame.new(0,0,-distance2/2)
p.Parent = workspace.RayCasts
local sound = tool.GunShotSound
local clonedsound = tool.GunShotSound:Clone()
wait(RS.GunStats[tool.Name].RPM.value)
clonedsound.Parent = tool.ShootPart
clonedsound:Play()
local a = RS.Items.EmitterShoot.a:Clone()
local b = RS.Items.EmitterShoot.b:Clone()
local Smoke = RS.Items.EmitterShoot.Smoke:Clone()
a.Parent = ShootPart
b.Parent = ShootPart
Smoke.Parent = ShootPart
a.Enabled = true
b.Enabled = true
Smoke.Enabled = true
coroutine.wrap(function()
a.Parent = ShootPart
b.Parent = ShootPart
Smoke.Parent = ShootPart
a.Enabled = true
b.Enabled = true
Smoke.Enabled = true
wait(0.1)
p:Destroy()
clonedsound:Destroy()
a.Enabled = false
b.Enabled = false
wait(0.2)
Smoke.Enabled = false
end)()
else
wait(RS.GunStats[tool1].Recovery.Value)
player.Character.Humanoid.WalkSpeed = 16
AlreadyShooting.Value = false
return end
end
wait(RS.GunStats[tool1].Recovery.Value)
player.Character.Humanoid.WalkSpeed = 16
AlreadyShooting.Value = false
end
end)
1 Like
Lunaryis
(Bluey)
August 17, 2022, 4:55pm
#2
before you define your distance variable, put
local HMR = DamagedPlayer:FindFirstChild("HumanoidRootPart")
then, again before the distance variable, put
if not HMR then return end
What the code above does is check if DamagedPlayer actually has a child called “HumanoidRootPart” and if it doesn’t it stops the script.
The error you’re getting is because, in the distance variable, you’re trying to find “HumanoidRootPart” but since you’re not actually shooting at a humanoid, there is no such instance
PS: I may be wrong since im not sure how you formatted your devforum post, if i am wrong, please point out where the error is happening in your script. (What i mean by this, if you check the console you will see there is a number at the end Server - GunHandler:20)
Hey, thanks for the response. My code now looks like this:
local RS = game:GetService("ReplicatedStorage")
local DamageEvent = RS.Events:FindFirstChild("DamageEvent")
DamageEvent.OnServerEvent:Connect(function(player, DamagedPlayer, Damage,tool1,spread1)
local tool = workspace[player.Name][tool1]
local ShootPart = tool.ShootPart
local AlreadyShooting = tool.AlreadyShooting
local EquippedValue = tool.EquippedValue
local Ammo = tool.Ammo
local HMR = DamagedPlayer:FindFirstChild("HumanoidRootPart")
if not HMR then return end
if DamagedPlayer and HMR and player:DistanceFromCharacter(HMR.Position) <= RS.GunStats[tool1].MaxRange.Value then
for i=1,RS.GunStats[tool.Name].AmmoPerVolley.Value do
if AlreadyShooting.Value == true and EquippedValue.Value == true and Ammo.Value > 0 and player:DistanceFromCharacter(DamagedPlayer.HumanoidRootPart.Position) <= RS.GunStats[tool1].MaxRange.Value and DamagedPlayer.Name ~= player.Name and DamagedPlayer.Humanoid.Health > 0 then
local RaycastParamss = RaycastParams.new()
RaycastParamss.IgnoreWater = true
tool.Ammo.Value -= 1
tool.ToolTip = "["..tool.Ammo.Value.."/"..RS.GunStats[tool.Name].Ammo.Value.."]"
local distance = (ShootPart.Position - HMR.Position).Magnitude
local spread = math.random((spread1 * 100 - spread1*100*2),spread1*100)/100
local HumanoidRootPartSpreded = HMR.Position + Vector3.new(spread * distance,spread * distance,0)
local result = workspace:Raycast(ShootPart.Position,HumanoidRootPartSpreded - ShootPart.Position,RaycastParamss)
local distance2 = (ShootPart.Position - result.Position).Magnitude
if result and result.Instance.Parent:FindFirstChild("Humanoid") and result.Instance.Parent.Name ~= player.Name then
result.Instance.Parent.Humanoid:TakeDamage(Damage)
end
local p = Instance.new("Part")
p.Parent = workspace.RayCasts
p.CanQuery = false
p.Anchored = true
p.CanCollide = false
p.Size = Vector3.new(0.1,0.1,distance2)
p.BrickColor = BrickColor.new("Yellow flip/flop")
p.Material = Enum.Material .Neon
p.Transparency = 0.9
p.CFrame = CFrame.lookAt(ShootPart.Position,result.Position)*CFrame.new(0,0,-distance2/2)
p.Parent = workspace.RayCasts
local sound = tool.GunShotSound
local clonedsound = tool.GunShotSound:Clone()
wait(RS.GunStats[tool.Name].RPM.value)
clonedsound.Parent = tool.ShootPart
clonedsound:Play()
local a = RS.Items.EmitterShoot.a:Clone()
local b = RS.Items.EmitterShoot.b:Clone()
local Smoke = RS.Items.EmitterShoot.Smoke:Clone()
a.Parent = ShootPart
b.Parent = ShootPart
Smoke.Parent = ShootPart
a.Enabled = true
b.Enabled = true
Smoke.Enabled = true
coroutine.wrap(function()
a.Parent = ShootPart
b.Parent = ShootPart
Smoke.Parent = ShootPart
a.Enabled = true
b.Enabled = true
Smoke.Enabled = true
wait(0.1)
p:Destroy()
clonedsound:Destroy()
a.Enabled = false
b.Enabled = false
wait(0.2)
Smoke.Enabled = false
end)()
else
wait(RS.GunStats[tool1].Recovery.Value)
player.Character.Humanoid.WalkSpeed = 16
AlreadyShooting.Value = false
return end
end
wait(RS.GunStats[tool1].Recovery.Value)
player.Character.Humanoid.WalkSpeed = 16
AlreadyShooting.Value = false
end
end)
but unfortunately it stills print error " ServerScriptService.GunSystem.GunHandler:23: attempt to index nil with ‘Position’ "
The problem is that if there is no raycast result (no hit), the result is nil. Since you have nothing that checks the result before, if you attempt to reference Position, you’ll get an error since result is nil. My suggestion is to use an if statement to check if result does not exist when first retrieving it, and continuing if so.
eg.
if not result then continue end
How could i make so the raycast will not set to nil? i want to make so even if ray didnt hit the player part will still be created and showed where did the raycast go
I think about adding function so when ray doesnt hit player it will shoot further until it hit something but i am not sure how i will be able to do this