The title says it all. I don’t know why or how this happens. Even when their CanCollide is set to false, the projectiles in my game ricochet off of parts. Is there some other property that can be affecting this?
Are there any related scripts that may affect the projectile in any way?
No, just one a ModuleScript called “Projectiles”
Can you show me the code for this modulescript?
Sorry for being afk, my Icelandic internet gave way:
local projectile = {}
local data = {
Cannonball = {
Model = projectilesFolder.Cannonball;
Damage = 1000;
Size = Vector3.new(2, 2, 2)
};
Musketball = {
Model = projectilesFolder.Musketball;
Damage = 150;
Size = Vector3.new(0.144, 0.144, 0.144)
};
GatlingBullet = {
Model = projectilesFolder.GatlingBullet;
Damage = 25;
Size = Vector3.new(0.105, 0.115, 0.205)
};
NavyBullet = {
Model = projectilesFolder.GatlingBullet;
Damage = 15;
Size = Vector3.new(0.105, 0.115, 0.205)
};
}
projectile.fire = function(plr : Player, LookVector : CFrame, projectileName : string, position : Vector3, speed : number, spread : number, ignore : SharedTable)
if not data[projectileName] then return end
local projectile = data[projectileName].Model:Clone()
projectile.CFrame = CFrame.new(position)
projectile.Parent = workspace.Projectiles
projectile:SetNetworkOwner(plr)
local BV = Instance.new("BodyVelocity")
BV.Velocity = LookVector * speed
BV.Parent = projectile
BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
spawner(function()
RS.Heartbeat:Connect(function(dt)
local ray = Ray.new(projectile.CFrame.Position, ((projectile.CFrame * CFrame.new(0, 0, -300)).Position - projectile.CFrame.Position).Unit * 3)
local part, position = workspace:FindPartOnRayWithIgnoreList(ray, ignore, false, true)
if part and position and projectile then
local cf = CFrame.new(position)
local size = projectile.Size
if part.Parent:FindFirstChild("Humanoid") then
projectile:Destroy()
part.Parent.Humanoid:TakeDamage(data[projectileName].Damage)
--part.Transparency = 1
part.Color = Color3.new(0.45, 0, 0)
plr.leaderstats.Cash.Value += 15
else
projectile:Destroy()
end
end
end)
end)
end
return projectile
Using workspace:FindPartOnRay
and workspace:FindPartOnRayWithIgnoreList
is deprecated, you should use workspace:Raycast
instead:
local projectile = {}
local data = {
Cannonball = {
Model = projectilesFolder.Cannonball;
Damage = 1000;
Size = Vector3.new(2, 2, 2)
};
Musketball = {
Model = projectilesFolder.Musketball;
Damage = 150;
Size = Vector3.new(0.144, 0.144, 0.144)
};
GatlingBullet = {
Model = projectilesFolder.GatlingBullet;
Damage = 25;
Size = Vector3.new(0.105, 0.115, 0.205)
};
NavyBullet = {
Model = projectilesFolder.GatlingBullet;
Damage = 15;
Size = Vector3.new(0.105, 0.115, 0.205)
};
}
projectile.fire = function(plr : Player, LookVector : CFrame, projectileName : string, position : Vector3, speed : number, spread : number, ignore : SharedTable)
if not data[projectileName] then return end
local projectile = data[projectileName].Model:Clone()
projectile.CFrame = CFrame.new(position)
projectile.Parent = workspace.Projectiles
projectile:SetNetworkOwner(plr)
local BV = Instance.new("BodyVelocity")
BV.Velocity = LookVector * speed
BV.Parent = projectile
BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
spawner(function()
RS.Heartbeat:Connect(function(dt)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = ignore
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
-- You might need to adjust the direction (The second argument of workspace:Raycast)
local raycastResult = workspace:Raycast(projectile.Position, projectile.CFrame.LookVector * 300, raycastParams)
if raycastResult then
local part, position = raycastResult.Instance, raycastResult.Position
local cf = CFrame.new(position)
local size = projectile.Size
if part.Parent:FindFirstChild("Humanoid") then
projectile:Destroy()
part.Parent.Humanoid:TakeDamage(data[projectileName].Damage)
--part.Transparency = 1
part.Color = Color3.new(0.45, 0, 0)
plr.leaderstats.Cash.Value += 15
else
projectile:Destroy()
end
end
end)
end)
end
return projectile
You might need to edit the direction (It’s the second argument of workspace:Raycast), as I’ve set it up so that the raycast uses the projectile’s LookVector as the direction, and you also might need to edit the raycast’s magnitude (The 300 I’m multiplying with the direction) if they don’t match how your original script behaved
How will that help my problem?
I misinterpreted the problem as FindPartOnRayWithIgnoreList detecting parts even though it shouldn’t, but I’d still recommend replacing deprecated functions whenever possible
You could try adding the projectiles into their own collision group:
Thanks for that, but I do need to do some work on the direction. The bullets kill NPCs from all the way across the map
or its the ricochet character limit
CollisionGroups? Never tried that
It could be that the ricochet isn’t bouncing the projectile off the object correctly, if the projectile’s orientation isn’t changed that much when they hit an object it would explain why they’re able to travel a great distance
They’re quite useful when dealing with assemblies that use a lot of physics constrains as well
There is supposed to be NO ricochet, that’s what I’m trying to remove
Having the projectiles in their own collision group will prevent them from being able to hit other parts (so long as the collision group is configured correctly), which would fix the ricochet issue, unless you do want the projectiles to hit other parts
As for why the raycast is able to hit people from great distances, if the issue isn’t being caused by the ricochet (as I explained in my previous comment), then either you’d need to change the 300
to a smaller value, or something else is causing the raycast to be extended
I set up the CollisionGroup so that it would not collide with ANYTHING. Is that ideal, because my game lags more now?
It most definitely should’nt have caused your game to lag, if anything it should’ve improved the performance by a bit since the engine no longer needs to calculate collisions for the projectiles
I’ve also identified a possible cause for the long distance hit issue, and I’m working on a fix now
This should fix the long distance issue:
local projectile = {}
local data = {
Cannonball = {
Model = projectilesFolder.Cannonball;
Damage = 1000;
Size = Vector3.new(2, 2, 2)
};
Musketball = {
Model = projectilesFolder.Musketball;
Damage = 150;
Size = Vector3.new(0.144, 0.144, 0.144)
};
GatlingBullet = {
Model = projectilesFolder.GatlingBullet;
Damage = 25;
Size = Vector3.new(0.105, 0.115, 0.205)
};
NavyBullet = {
Model = projectilesFolder.GatlingBullet;
Damage = 15;
Size = Vector3.new(0.105, 0.115, 0.205)
};
}
projectile.fire = function(plr : Player, LookVector : CFrame, projectileName : string, position : Vector3, speed : number, spread : number, ignore : SharedTable)
if not data[projectileName] then return end
local projectile = data[projectileName].Model:Clone()
projectile.CFrame = CFrame.new(position)
projectile.Parent = workspace.Projectiles
projectile:SetNetworkOwner(plr)
local BV = Instance.new("BodyVelocity")
BV.Velocity = LookVector * speed
BV.Parent = projectile
BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
spawner(function()
local overlapParams = OverlapParams.new()
overlapParams.FilterDescendantsInstances = ignore
overlapParams.FilterType = Enum.RaycastFilterType.Exclude
local originalPosition = projectile.Position
local connection
connection = RS.Heartbeat:Connect(function(dt)
if (projectile.Position - originalPosition).Magnitude >= 300 then
connection:Disconnect()
projectile:Destroy()
return
end
for _, part in workspace:GetPartsInPart(projectile, overlapParams) do
local model = part:FindFirstAncestorOfClass("Model")
if model then
local humanoid = model:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid:TakeDamage(data[projectileName].Damage)
part.Color = Color3.new(0.45, 0, 0)
plr.leaderstats.Cash.Value += 15
end
end
end
connection:Disconnect()
projectile:Destroy()
end)
end)
end
return projectile
Essentially what was causing it was that since the projectile is a moving object and the raycast is originating from its current position, and the raycast was being fired inside of a loop, the raycast was extending beyond the 300 distance that was originally intended
Using workspace:GetPartsInPart
should also make the collision detection for the projectile more accurate than when using raycasts
If can collide is false, the parts shouldn’t interact with other parts, unless:
- They are connected to parts with can collide on
- There is code that detects parts any programmatically causes them to ricochet
CanCollide being off overrides all collision group settings.
The projectiles just never appear, i think the connection messed my code up and I’m narrowing down the problem
That would mean that the projectiles are already 300 studs past the original position that they were when originally fired
I don’t know how you’re handling the projectile’s movement, and the programming style/system you’re using is significantly different than the one I use, which is why I’m getting confused
I use a more rough approach to programming, and I notice you use a more cautious approach. I have never really used connections, so I think that’s why the code messed up