Hello, I am trying to make a game where you throw things at NPCs out of boredom, but the linear velocity has stumped me as it is completely broken with only one item. I have tried 3 different meshes and made 2 unions just for the same result, and it still keeps going insane. Here is the script, the layout, and a video of what is going on.
local ss = game:GetService("ServerStorage")
local ts = game:GetService("TweenService")
local rep = game:GetService("ReplicatedStorage")
local killEffects = require(script.KillEffects)
local ragdoll = require(script.Ragdoll)
local sfx = ss.SFX
local cooldowns = {}
local killnum = 1
local dollarsforkill = 1
local function addkills(player, char)
if player.KillEffect.Value ~= "None" then
killEffects[player.KillEffect.Value](char)
player.trueKills.Value += killnum
player.Bucks.Value += dollarsforkill
else
player.trueKills.Value += killnum
player.Bucks.Value += dollarsforkill
end
end
rep.Throw.OnServerEvent:Connect(function(player, name, lookvector)
local cooldown = rep.Throwables:FindFirstChild(name):GetAttribute("Cooldown") or 1
cooldowns[player] = cooldowns[player] or {}
local now = tick()
local lastUsed = cooldowns[player][name] or 0
if now - lastUsed < cooldown then
return
end
cooldowns[player][name] = now
if not player.Character:FindFirstChild(name) then return end
local throwable : Part = rep.Throwables:FindFirstChild(name):Clone()
throwable.Parent = workspace
throwable.CFrame = player.Character:FindFirstChild(name).Handle.CFrame + Vector3.new(0,-1,0)
local att = Instance.new("Attachment", throwable)
local lv = Instance.new("LinearVelocity")
lv.Attachment0 = att
lv.VectorVelocity = lookvector * throwable:GetAttribute("Speed")
lv.MaxForce = math.huge
lv.Parent = throwable
if throwable:FindFirstChild("Trail") then throwable.Trail.Enabled = true end
local randori = Vector3.new(math.random(-360,360),math.random(-360,360),math.random(-360,360))
local tween = ts:Create(throwable, TweenInfo.new(2), {Orientation = randori}):Play()
local touched = {}
throwable.Hitbox.Touched:Connect(function(hit)
if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
--if not (hit.Parent.Parent == workspace.NPCs) then return end --allows PVP
if hit.Parent.Name == player.Character.Name then return end
if table.find(touched, hit.Parent) then return end
table.insert(touched, hit.Parent)
if throwable:HasTag("Explosive") then
local impactsfx : Sound = sfx.Impact:FindFirstChild(name):Clone()
impactsfx.Parent = hit.Parent.HumanoidRootPart
impactsfx.PitchShiftSoundEffect.Octave = math.random(95,115)/100
impactsfx:Play()
game.Debris:AddItem(impactsfx, impactsfx.TimeLength)
local temp = Instance.new("Part")
temp.Parent = workspace
temp.CanCollide = false
temp.Anchored = true
temp.Transparency = 1
temp.CFrame = throwable.CFrame
local attachment = Instance.new("Attachment")
attachment.Parent = temp
if throwable:FindFirstChild("Particles") then
for i,v in pairs(throwable.Particles:GetChildren()) do
v = v:Clone()
v.Parent = temp.Attachment
task.wait()
v:Emit()
end
end
local hitlist = {}
local radius = throwable:GetAttribute("Radius")
local position = temp.Position
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances = {workspace.NPCs}
local nearbyParts = workspace:GetPartBoundsInRadius(position, radius, params)
local function getDamage(dist)
local maxDamage = throwable:GetAttribute("Damage")
local minDamage = (throwable:GetAttribute("Damage")*30)/100
local fullDamageRadius = 5
local maxDistance = 20
if dist <= fullDamageRadius then
return maxDamage
elseif dist >= maxDistance then
return minDamage
else
local falloff = (1 - (dist - fullDamageRadius) / (maxDistance - fullDamageRadius))
return minDamage + (maxDamage - minDamage) * falloff
end
end
for _, hit2 in ipairs(nearbyParts) do
if hit2 and hit2.Parent then
local humanoid = hit2.Parent:FindFirstChild("Humanoid")
if humanoid and not table.find(hitlist, hit2.Parent) then
table.insert(hitlist, hit2.Parent)
local dist = (temp.Position - hit2.Position).Magnitude
local beam = Instance.new("Part")
beam.Anchored = true
beam.CanCollide = false
beam.Size = Vector3.new(0.2, 0.2, dist)
beam.CFrame = CFrame.new(temp.Position, hit2.Position) * CFrame.new(0, 0, -dist/2)
beam.Color = Color3.fromRGB(255, 0, 0)
beam.Parent = workspace
beam.Transparency = 1
local lv = Instance.new("LinearVelocity")
lv.Attachment0 = hit2.Parent.HumanoidRootPart.RootAttachment
lv.VectorVelocity = (beam.CFrame.LookVector * Vector3.new(1, 0, 1)).Unit * throwable:GetAttribute("Speed")
lv.MaxForce = math.huge
lv.Parent = hit2.Parent
game.Debris:AddItem(lv, 3)
if throwable:HasTag("Gamepass") or throwable:HasTag("Admin") then
humanoid:TakeDamage(throwable:GetAttribute("Damage"))
if humanoid.Health <= 0 then
addkills(player, hit2.Parent)
ragdoll.Ragdoll(hit2.Parent, 10)
else
ragdoll.Ragdoll(hit2.Parent, 1)
end
else
local damage = getDamage(dist)
humanoid:TakeDamage(damage)
if humanoid.Health <= 0 then
addkills(player, hit2.Parent)
ragdoll.Ragdoll(hit2.Parent, true, 10)
else
ragdoll.Ragdoll(hit2.Parent, true, 1)
end
end
end
end
end
local nearbyPlayers = workspace:GetPartBoundsInRadius(position, radius * 4)
for _, hit3 in ipairs(nearbyPlayers) do
if hit3 and hit3.Parent then
local humanoid = hit3.Parent:FindFirstChild("Humanoid")
if humanoid and not table.find(hitlist, hit3.Parent) and game.Players:GetPlayerFromCharacter(hit3.Parent) then
table.insert(hitlist, hit3.Parent)
local eplayer = game.Players:GetPlayerFromCharacter(hit3.Parent)
local dist = (temp.Position - hit3.Position).Magnitude
if dist <= radius then
rep.ShakeEvents.BigShake:FireClient(eplayer)
if hit3.Parent.Name == player.Character.Name then return end
if not throwable:HasTag("Gamepass") then
throwable:Destroy()
end
local damage = getDamage(dist)
humanoid:TakeDamage(damage)
local dist = (temp.Position - hit3.Position).Magnitude
local beam = Instance.new("Part")
beam.Anchored = true
beam.CanCollide = false
beam.Size = Vector3.new(0.2, 0.2, dist)
beam.CFrame = CFrame.new(temp.Position, hit3.Position) * CFrame.new(0, 0, -dist/2)
beam.Color = Color3.fromRGB(255, 0, 0)
beam.Parent = workspace
beam.Transparency = 1
local lv = Instance.new("LinearVelocity")
lv.Attachment0 = hit3.Parent.HumanoidRootPart.RootAttachment
lv.VectorVelocity = (beam.CFrame.LookVector * Vector3.new(1, 0, 1)).Unit * throwable:GetAttribute("Speed")
lv.MaxForce = math.huge
lv.Parent = hit3.Parent
game.Debris:AddItem(lv, 0.2)
if throwable:HasTag("Gamepass") then
humanoid:TakeDamage(throwable:GetAttribute("Damage"))
if humanoid.Health <= 0 then
addkills(player, hit3.Parent)
ragdoll.Ragdoll(hit3.Parent, true, 10)
else
ragdoll.Ragdoll(hit3.Parent, true, 1)
end
else
local damage = getDamage(dist)
humanoid:TakeDamage(damage)
if humanoid.Health <= 0 then
addkills(player, hit3.Parent)
ragdoll.Ragdoll(hit3.Parent, true, 10)
else
ragdoll.Ragdoll(hit3.Parent, true, 1)
end
end
elseif dist > radius then
rep.ShakeEvents.MiniShake:FireClient(eplayer)
end
end
end
end
game.Debris:AddItem(temp, 5)
if not throwable:HasTag("Gamepass") then
throwable:Destroy()
end
else
if hit.Parent.Name == player.Character.Name then return end
local humanoid = hit.Parent:FindFirstChild("Humanoid")
humanoid:TakeDamage(throwable:GetAttribute("Damage"))
local impactsfx : Sound = sfx.Impact:FindFirstChild(name):Clone()
impactsfx.Parent = hit.Parent.HumanoidRootPart
impactsfx.PitchShiftSoundEffect.Octave = math.random(95,115)/100
impactsfx:Play()
game.Debris:AddItem(impactsfx, impactsfx.TimeLength)
local bv = Instance.new("BodyVelocity")
bv.Parent = hit
bv.MaxForce = Vector3.one * math.huge
bv.Velocity = lookvector * throwable:GetAttribute("Knockback")
game.Debris:AddItem(bv, 0.2)
local temp = Instance.new("Part")
temp.Parent = workspace
temp.CanCollide = false
temp.Anchored = true
temp.Transparency = 1
temp.CFrame = throwable.CFrame
local attachment = Instance.new("Attachment")
attachment.Parent = temp
if throwable:FindFirstChild("Particles") then
for i,v in pairs(throwable.Particles:GetChildren()) do
v = v:Clone()
v.Parent = temp.Attachment
task.wait()
v:Emit()
end
end
if humanoid.Health <= 0 then
addkills(player, hit.Parent)
ragdoll.Ragdoll(hit.Parent, true, 10)
else
ragdoll.Ragdoll(hit.Parent, true, 1)
end
game.Debris:AddItem(temp, 5)
if not throwable:HasTag("Gamepass") then
throwable:Destroy()
end
end
end
end)
task.wait(3)
throwable:Destroy()
end)
Each throwable has the same attributes apart from the “radius” on explosives, the parts are turned into useable tools by selecting them in the menu, its most certainly not the problem. The parts are all CanCollide false, Anchored false, and Massless false, and the hitboxes are the same just that they are massless.
Any help will be greatly appreciated. Thanks!