So I've been spending a bit of time trying to make some bullets to work for the guns used in a game I'm helping out with... After some issues Cframe's not being the greatest, and with Tween making it smoother (not actually implemented as of yet as I haven't worked with the service) but not fixing the issue I was looking to explore other options. It's fairly common knowledge that 2 anchored objects cannot touch. The issue is, both objects have to be anchored, as one is walls, and if the bullets are not anchored, they go under the effect of gravity far too quick. So a simple solution I have thought of is applying a body force to negate gravity. However when shooting at angles up or down, I'm not sure how realistic this is.
That became an option due to the issues I had with using :GetTouchingParts(), as the bullets start by touching the gun's handle, and then may make contact with each other as there is a gun with a multi-shot spray, and I've not really seen a good way to filter out certain touching parts.
The other option there is, is using FastCast. From reading the site and looking at the module scripts it seems really great, however being fairly new to scripting, is incredibly overwhelming and I have absolutely no idea where to start.
What I'd like to know is whether the bodyforce to negate gravity is actually feasible, and by combining that with tweening will work well enough (the max server size is only 6 players so it won't be overwhelmed with bullets), or whether changing to fast cast is really the only way forwards. And if that is the case, any pointers on how to implement it would be extremely helpful.
Here is the code for when the gun is fired and a bullet is created (which deals with getting the bullet data for that gun and also directing the offset for the spray of the bullets:
local GunData = require(game.ReplicatedStorage.GunData) local rep = 1 game.ReplicatedStorage.ShootGun.OnServerEvent:Connect(function(Player, TargetLocation, Handle) if Player.Character == nil then return end if Handle then local Tool = Handle.Parent if Tool:IsA("Tool")then if Tool.Parent == Player.Character then local relevantData = GunData[Tool.Name] if relevantData ~= nil then for count = 1,relevantData.REP do Handle.Sound:Play() local Beam = Instance.new("Part", workspace) Beam.Color = relevantData.COLOR Beam.FormFactor = "Custom" Beam.Transparency = 0.25 Beam.Material = "Neon" Beam.Anchored = true Beam.CanCollide = false Beam.Name = "Bullet" Beam:SetAttribute("Speed",relevantData.SPEED) Beam:SetAttribute("Damage",relevantData.DMG) Beam.CanTouch = true Beam:SetAttribute("Shooter",Tool.Parent.Name) local Distance = (TargetLocation - Handle.Position).magnitude if Distance >= relevantData.RANGE then Distance = relevantData.RANGE end local NewAngle = CFrame.Angles(math.rad(math.random(-relevantData.ANGLE,relevantData.ANGLE)),math.rad(math.random(-relevantData.ANGLE,relevantData.ANGLE)),math.rad(math.random(-relevantData.ANGLE,relevantData.ANGLE))) Beam.Size = Vector3.new(relevantData.WIDTH, relevantData.WIDTH, Distance) Beam.CFrame = CFrame.new(Handle.Position, TargetLocation) * CFrame.new(0, 0, -Distance/2) local offset = Handle.CFrame:Inverse()*Beam.CFrame local handleStartCFrame = Handle.CFrame local newCFrame = handleStartCFrame*NewAngle Beam.CFrame = newCFrame*offset local moveBullets = script.bulletMovement:Clone() moveBullets.Parent = Beam local hitBullets = script.hitDetection:Clone() hitBullets.Parent = Beam Beam.Parent = game.Workspace["Futuristic Tycoon"].Bullets if relevantData.DELAY ~= 0 then wait(relevantData.DELAY) end end end end end end end)
Here's the movement script:
scrpar = script.Parent speed = scrpar:GetAttribute("Speed") while true do if scrpar.Name == "Bullet" then wait() for count = 1,20 do scrpar.CFrame = scrpar.CFrame + scrpar.CFrame.lookVector * speed wait() end scrpar:Destroy() end end
Finally, the hit detection... only detects humanoids for now as they are not anchored:
local Players = game:GetService("Players") local scrpar = script.Parent local damage = scrpar:GetAttribute("Damage") local shooter = scrpar:GetAttribute("Shooter") scrpar.Touched:Connect(function(hit) print("touched") local humanoid = hit.Parent:FindFirstChild("Humanoid") or hit.Parent.Parent:FindFirstChild("Humanoid") if humanoid then local player = Players:GetPlayerFromCharacter(humanoid.Parent).Name if player ~= shooter then humanoid.Health -= damage scrpar:Destroy() end end end)