local ProjectileHandler = {}
local function ReturnDecimal(range)
return Random.new():NextNumber(-range, range)
end
local function Lerp(a, b, t)
return a + (b - a) * t
end
local DamageEnemy = game.ReplicatedStorage.RemoteEvents.DamageEnemy
function ProjectileHandler.Shoot(Properties, Viewmodel)
if Properties.Type == "Projectile" then
local Angle = 0
local AngleDirectionToTravel = 1
local RaycastParameters = RaycastParams.new()
RaycastParameters.FilterType = Enum.RaycastFilterType.Exclude
RaycastParameters.RespectCanCollide = true
if Properties.IsPlayerShooting then
RaycastParameters.FilterDescendantsInstances = {game.Players.LocalPlayer.Character, Viewmodel}
end
local Bullet = Instance.new("Part")
Bullet:SetAttribute("TimesRicocheted", 0)
Bullet:SetAttribute("EnemiesHit", 0)
Bullet:SetAttribute("FollowsGravity", Properties.FollowsGravity)
Bullet:SetAttribute("BulletVelocity", Vector3.new(Properties.Direction.X + ReturnDecimal(Properties.MaxInaccuracy), Properties.Direction.Y + ReturnDecimal(Properties.MaxInaccuracy), Properties.Direction.Z + ReturnDecimal(Properties.MaxInaccuracy)) * Properties.Speed)
Bullet.Name = Properties.Name or "Bullet"
Bullet.Size = Properties.Size or Vector3.new(1, 1, 1)
Bullet.Color = Properties.Color or Color3.new(0, 0, 0)
Bullet.Material = Properties.Material or Enum.Material.SmoothPlastic
Bullet.CFrame = Properties.Origin
Bullet.Parent = workspace
Bullet.CollisionGroup = "Extra"
game.CollectionService:AddTag(Properties.ExtraType)
Bullet.CastShadow = false
Bullet.AssemblyLinearVelocity = Bullet:GetAttribute("BulletVelocity")
game.Debris:AddItem(Bullet, Properties.LifeTime)
local Stepped = game:GetService("RunService").PreRender:Connect(function()
local BulletVelocity = Bullet:GetAttribute("BulletVelocity")
local CharacterCollisionRay = workspace:Blockcast(Bullet.CFrame, Bullet.Size, Bullet.AssemblyLinearVelocity.Unit * math.clamp(Properties.Speed / 25, 7, math.huge), RaycastParameters)
if Bullet:GetAttribute("FollowsGravity") == false then
Bullet.AssemblyLinearVelocity = BulletVelocity
end
Bullet.CFrame = CFrame.lookAt(Bullet.Position, Bullet.Position + Bullet.AssemblyLinearVelocity)
for i, v in pairs(game.CollectionService:GetTagged("Magnet")) do
if v:IsA("Part") and (v.Position - Bullet.Position).Magnitude < 10 then
local SawCollisionRaycast = workspace:Raycast(Bullet.Position, Bullet.AssemblyLinearVelocity.Unit * 2, RaycastParameters)
if Properties.MagneticType == "Swarm" then
Bullet:SetAttribute("BulletVelocity", Lerp(BulletVelocity, (v.Position - Bullet.Position).Unit * Properties.Speed, 0.5))
elseif Properties.MagneticType == "Circular" then
Angle += (math.clamp(Properties.Speed / 900, 0, math.huge) * AngleDirectionToTravel)
Angle = Angle % 360
print(Angle)
local NewX = v.Position.X + 8 * math.cos(Angle)
local NewZ = v.Position.Z + 8 * math.sin(Angle)
Bullet:SetAttribute("BulletVelocity", (Vector3.new(NewX, v.Position.Y, NewZ) - Bullet.Position).Unit * Properties.Speed / 2)
--this is where the issue is
if SawCollisionRaycast and SawCollisionRaycast.Instance then
AngleDirectionToTravel *= -1
print(SawCollisionRaycast.Instance.Name)
wait()
end
end
end
end
if CharacterCollisionRay and CharacterCollisionRay.Instance then
if not CharacterCollisionRay.Instance.Parent:FindFirstChildOfClass("Humanoid") and Bullet:GetAttribute("TimesRicocheted") < Properties.MaxRicochets then
Bullet:SetAttribute("TimesRicocheted", Bullet:GetAttribute("TimesRicocheted") + 1)
Bullet.AssemblyLinearVelocity = Bullet.AssemblyLinearVelocity - (2 * Bullet.AssemblyLinearVelocity:Dot(CharacterCollisionRay.Normal) * CharacterCollisionRay.Normal)
Bullet:SetAttribute("BulletVelocity", BulletVelocity - (2 * BulletVelocity:Dot(CharacterCollisionRay.Normal) * CharacterCollisionRay.Normal))
else
if Properties.IsPlayerShooting and CharacterCollisionRay.Instance.Parent == (game.Players.LocalPlayer.Character or Viewmodel) then return end
if CharacterCollisionRay.Instance.Parent:FindFirstChild("Humanoid") and CharacterCollisionRay.Instance.Parent:FindFirstChild("Humanoid").Health > 0 then
local HitHumanoid = CharacterCollisionRay.Instance.Parent:FindFirstChild("Humanoid")
if Bullet:GetAttribute("EnemiesHit") and Bullet:GetAttribute("EnemiesHit") < Properties.MaxEnemiesToHit and not HitHumanoid:HasTag("BeenHit") then
Bullet:SetAttribute("EnemiesHit", Bullet:GetAttribute("EnemiesHit") + 1)
HitHumanoid:AddTag("BeenHit")
DamageEnemy:FireServer(HitHumanoid, Properties.Damage * ((Properties.LocationalDamage == true and CharacterCollisionRay.Instance:GetAttribute("WeakpointMultiplier") ~= nil) and CharacterCollisionRay.Instance:GetAttribute("WeakpointMultiplier") or 1))
task.delay(0.75, function() HitHumanoid:RemoveTag("BeenHit") end)
--Hit effects like explosions.
for i = 1, Properties.ContinuousDamage.AmountOfLoops or 1 do
Bullet.Anchored = true
DamageEnemy:FireServer(HitHumanoid, Properties.ContinuousDamage.Damage * ((Properties.LocationalDamage == true and CharacterCollisionRay.Instance:GetAttribute("WeakpointMultiplier") ~= nil) and CharacterCollisionRay.Instance:GetAttribute("WeakpointMultiplier") or 1))
task.wait(Properties.ContinuousDamage.WaitPerLoop)
end
Bullet.Anchored = false
if Bullet:GetAttribute("FollowsGravity") == true and Properties.MaxEnemiesToHit > 1 and HitHumanoid.Health > 0 and Properties.ContinuousDamage.AmountOfLoops > 0 then
Bullet.AssemblyLinearVelocity = Vector3.yAxis * Properties.Speed / 2
Bullet:SetAttribute("TimesRicocheted", Properties.MaxRicochets)
else Bullet:Destroy() end
if Bullet:GetAttribute("EnemiesHit") >= Properties.MaxEnemiesToHit then Bullet:Destroy() end
end
elseif not (game.CollectionService:HasTag(CharacterCollisionRay.Instance, "Bullet") or CharacterCollisionRay.Instance.Name == "Bullet") then
Bullet:Destroy()
end
end
end
end)
Bullet.Destroying:Connect(function()
Stepped:Disconnect()
end)
return Bullet
end
end
return ProjectileHandler
i am making a system where you can make bullets by choosing a bunch of properties in a list. Bullets can have one of 3 magnetic types, swarm: the bullets all swarm around the magnet like bees to a hive, circular: the bullets spin in circles around the magnet, and none: not attracted to a magnet. when the magnet is close to a wall, the bullets should bounce off of the wall and begin moving in the opposite direction. The problem is that i haven't been able to find a way to properly detect this, using raycasts and blockcasts dont seem to work and there isn't anything else i can think of. is there any possible way to do this?
(also please tell me if my code is structured badly)