Hello,
I look at many posts but couldn’t find my case. I want the ray to ignore player’s accessories and I saw on other posts how to do it with the ignore list but the code for raycasting that I use looks different and I’m unsure how to implement it into my code
code:
-- setup raycast parameters --
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player.Character, } -- blacklist player (thats shooting) character from being hit
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
-- send the raycast from gun to mouse position --
local raycastResult = workspace:Raycast(script.Parent.Handle.Position, (mousePos - script.Parent.Handle.Position) * range, raycastParams)
if raycastResult then -- if hit something
local hitPart = raycastResult.Instance
local model = hitPart:FindFirstAncestorOfClass("Model")
if model then -- if it's a model
if model:FindFirstChild("Humanoid") then -- if it contains humanoid
if hitPart.Name == "Head" then
model.Humanoid:TakeDamage(headDamage)
else if hitPart.Name == "UpperTorso" then
model.Humanoid:TakeDamage(torsoDamage)
end
end
model.Humanoid:TakeDamage(otherDamage)
else
end
else
local hitMark = Instance.new("Part")
hitMark.Parent = game.Workspace
hitMark.Anchored = true
hitMark.CanCollide = false
hitMark.Position = raycastResult.Position
hitMark.Size = Vector3.new(.15, .15, .15)
hitMark.BrickColor = BrickColor.Black()
end
The main and likely cleanest solution to this would be to simply loop through each player in the game, and then loop through the children of each of their character’s (if the character exists) and create an array that includes the shooting player’s character, as well as the accessories of each player. Then, set FilterDescendantsInstances to this array that we have created.
If you wanted to as well, you could also just reduce the hat hitboxes to a tiny size, avoiding having to loop through the characters each time you fire (or performing multiple raycasts.)
Hey, I have a question. How would I check if the character is loaded, I tried using “player.CharacterAdded:Wait()” but it seems to be stuck on that. And here is the code I did.
local ignoreList = {}
local igIndex = 1
for i, v in ipairs(game.Players:GetChildren()) do
v.CharacterAdded:Wait()
for i,v in ipairs(v:GetChildren()) do
if v:IsA("Accessory") then
table.insert(ignoreList, igIndex, v)
print(v)
igIndex += 1
end
end
end
table.insert(ignoreList, igIndex, player.Character)
igIndex = 1
.CharacterAdded results in waiting for the player’s character being loaded in each player that you are looping through. In this case, we can merely check if Player.Character exists, and if it does not, we can just continue as if the player does not have a character, they obviously won’t have any accessories we need to worry about.
As a side note, you do not need to include the index, as if you do not include an index it simply inserts into the end of the table, which is all we need for this to work. We can also just pre-include the player’s character in this table. Here are these two things implemented below:
local ignoreList = {player.Character}
for i, v in ipairs(game.Players:GetChildren()) do
if v.Character then -- Check if their character exists
for i,v in ipairs(v.Character:GetChildren()) do -- Do not loop through the player, but loop through their character.
if v:IsA("Accessory") then
table.insert(ignoreList, v)
print(v)
end
end
end
end
Keep in mind that you’ll need to run this every time the player fires (which isn’t too computationally expensive, and shouldn’t matter too much,) or go with a more complex solution. Stick to just running this every time the player fires for now.
Just noticed that section of the code, of which I will state a few things about:
To answer your question, it is because you check if the HitPart has been the Head or the Torso, and then deal damage, and then deal damage separately as otherDamage. This is what your code is doing right now:
What you want to do is make this a part of that statement, instead of having it outside of it. However, you have a second issue: else if is not the same as elseif.
Elseif (no space) makes the code a part of the same “block”, while else if makes a new “block” of conditionals. Your code is currently structured like this:
I will leave my comment about the Model issue up to you to deal with (unless if this is intended,) however, here’s how that inside part should be handled:
if model:FindFirstChild("Humanoid") then -- if it contains humanoid
if hitPart.Name == "Head" then
model.Humanoid:TakeDamage(headDamage)
elseif hitPart.Name == "UpperTorso" then -- Note the change of "else if" to "elseif"!
model.Humanoid:TakeDamage(torsoDamage)
-- The second end that was here before should have been an indication that something was amiss.
else
model.Humanoid:TakeDamage(otherDamage)
end
-- Forgot to mention, this else in here due to the issue above was linked to the Humanoid block, and not to the hitPart conditionals.
-- This is likely where you intended for your particle code to go, so I have left it in with proper identation.
else
end
You will encounter an issue on your code where if you attempt to shoot another player, the player will not actually take damage on their screen, and will only take damage on your screen. This is because of client server replication in ROBLOX, and to fix this, you will need to use RemoteEvents. The dev wiki provides a good intro this this concept here: Roblox Client-Server Model
Once you read that last article, read this for an idea on RemoteEvents and RemoteFunctions:
As a note, you should only need one server script to handle damage and effects in your game. Your remote event should be stored in a place accessible to both the Tool’s client script (preferably ReplicatedStorage) and the singular script should be in ServerScriptService.
I have dumped a lot of information in this post, and I’ll check back in if you need any other sort of help
Honestly thank you man for all of this. I structured the code like this and it works great now.
code:
if model then
if model:FindFirstChild("Humanoid") then -- if it contains humanoid
if hitPart.Name == "Head" then
model.Humanoid:TakeDamage(headDamage)
elseif hitPart.Name == "UpperTorso" then
model.Humanoid:TakeDamage(torsoDamage)
else
model.Humanoid:TakeDamage(otherDamage)
end
end
else
local hitMark = Instance.new("Part")
hitMark.Parent = game.Workspace
hitMark.Anchored = true
hitMark.CanCollide = false
hitMark.Position = raycastResult.Position
hitMark.Size = Vector3.new(.15, .15, .15)
hitMark.BrickColor = BrickColor.Black()
end
And I should probably show it earlier but I am using a local script for detecting the mouse input and reloading then it sends a remote event to the server script which I posted a bit of. Also for all the damage, reload time, range info I am using a module script located in replicated storage because I believe it is safe from exploiters.