I ended up fixing this issue by overriding the filter list in the CanRayPierce function, not OnRayPierced. Thanks for ADRENALXNE’s help, he had a similar post in this thread and found this solution.
This API member does not exist because it’s not so simple.
Imagine you do a hitreg with this hypothetical FastCast:Once()
and you detect a hit on the person you’re aiming at. Cool, all good so far. But what happens when you fire the bullet that has travel time and say, some dude happens along and walks into the path of the bullet before it hits the guy you were aiming it? Now your pre-calculated result is flat out wrong.
This is why the module comes with the hit simulation it does - because you should be simulating the bullet, travel time and all.
Ahh, I understand. Yeah I can see the complexity behind that and the issues that could arise. I appreciate you reading my reply and considering! I do really enjoy this module quite a lot, it’s been a major staple in many of my projects. Thanks a lot!
Is possible to make a projectile’s motion? I was looking on the dev forum and everything I didnt found I am trying to do something like this.
and I am doing something like:
caster.LengthChanged:Connect(function(cast, lastpoint, dir, length)
local offset = CFrame.new(0, 0, -length)
bullet.CFrame = CFrame.lookAt(lastpoint, lastpoint + dir):ToWorldSpace(offset)
end)
How do you make the bullet render immediately when the cast starts instead of when the cast first updates, since if you have it render when it updates, it’ll start rendering at various distances in front of the firepoint rather than actually at the firepoint. It really breaks immersion and I can’t seem to fix it, I’ve tried moving the bullet position to the firepoint after the first render as well, but it just doesn’t do anything.
you need to increase the downward acceleration, its in the castbehavior i believe
How can I make bullets pierce through the accessories?
How do I make both projectiles terminate when they hit each other? Right now only one random one gets terminated (usually the one that’s most recently fired).
EDIT: I’ve tried getting the bullet that it hit in OnRayHit, and returning it to PartCache in OnCastTerminating, but it didn’t work. The recently fired bullet gets returned, but it errors for the hit bullet saying that it’s not in-use (though it very obviously is as I tried doing table.find on the InUse table with the hit bullet, and it found it perfectly fine every time)
EDIT 2: Solved:) If anyone runs into this in the future, I keep all ActiveCasts in a table, storing them in the table on fire, having the projectile instance as the key, the ActiveCast as the value, and then when I determine that it hits a projectileI find the ActiveCast associated with the projectile instance from the table, and run :Terminate() on it.
Heya there!
There has been just one issue that I seemingly cannot solve.
Sometimes, the bullet ray shoots at the sky (past the zombie)? I’m guessing this is because of the muzzle being inside a zombie head. The video below showcases this: red part is muzzle position, green part is mouse position.
Here’s the module code that I use for the gun.
local setup = {}
setup.__index = setup
local PS = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local DBS = game:GetService("Debris")
local caster = require(script.Parent.Caster)
local partCache = require(script.Parent.Cache)
local damageDisplay = require(script.Parent.Parent.DamageDisplay)
local fx = RS.Events.FX
local effect = {
blood = "Blood",
hit = "Hit"
}
type params = {[string]: any}
local function VisualizeRay(dir: Vector3, origin: Vector3)
local mid = origin + dir / 2
local part = Instance.new("Part") do
part.Parent = workspace
part.Anchored = true
part.CFrame = CFrame.new(mid, origin)
part.Size = Vector3.new(.1, .1, dir.Magnitude)
part.Material = Enum.Material.Neon
part.BrickColor = BrickColor.Red()
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
task.delay(.2, function()
part:Destroy()
end)
end
end
local function VisualizePos(pos: Vector3, color: BrickColor)
local part = Instance.new("Part") do
part.Parent = workspace
part.Anchored = true
part.Position = pos
part.Size = Vector3.new(.5,.5,.5)
part.Material = Enum.Material.Neon
part.BrickColor = color
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
--task.delay(.2, function()
-- part:Destroy()
--end)
end
end
local function LoadBulletHole(parent: BasePart, pos: Vector3, normal: Vector3, hum: Humanoid)
local hole = Instance.new("Part") do
hole.CanCollide = false
hole.CanQuery = false
hole.CanTouch = false
hole.Transparency = 1
hole.Size = Vector3.new(.5, .5, .05)
hole.Parent = parent
hole.CFrame = CFrame.lookAt(pos, pos + normal)
end
local image = if hum then script.BloodHole:Clone() else script.PartHole:Clone() do
image.Parent = hole
end
local weld = Instance.new("WeldConstraint") do
weld.Parent = parent
weld.Part0 = parent
weld.Part1 = hole
end
DBS:AddItem(hole, 15)
end
function setup.new(params)
local self = {}
self.Tool = params.Tool
self.Owner = if self.Tool.Parent:IsA("Backpack") then self.Tool.Parent.Parent else PS:GetPlayerFromCharacter(self.Tool.Parent)
self.Character = self.Owner.Character or self.Owner.CharactedAdded:Wait()
self.Damage = params.Damage
self.AttackType = params.AttackType
self.Bullet = Instance.new("Part")
self.Multiplier = params.Multiplier
self.DistanceBeforeMultiply = params.DistanceBeforeMultiply
self.MinSpread = params.MinSpread
self.MaxSpread = params.MaxSpread
for i,v in pairs(params.BulletInfo) do
if i == "Trail" and v:IsA("Trail") then
local at0 = Instance.new("Attachment") do
at0.Parent = self.Bullet
at0.WorldPosition = (self.Bullet.CFrame * CFrame.new(0, 0, (self.Bullet.Size.Z / 2))).Position
end
local at1 = Instance.new("Attachment") do
at1.Parent = self.Bullet
at1.WorldPosition = (self.Bullet.CFrame * CFrame.new(0, 0, -(self.Bullet.Size.Z / 2))).Position
end
local clone = v:Clone() do
clone.Parent = self.Bullet
clone.Enabled = false
clone.Attachment0 = at0
clone.Attachment1 = at1
end
else
if self.Bullet[i] then
self.Bullet[i] = v
end
end
end
self.MaxDistance = params.MaxDistance
self.Speed = params.Speed
self.Gravity = params.Gravity
self.RaycastParameters = params.RaycastParameters
self.BulletParent = params.BulletParent
self.PartCache = partCache.new(self.Bullet, 100, self.BulletParent)
self.Hitbox = caster.new()
self.Behavior = caster.newBehavior() do
self.Behavior.RaycastParams = self.RaycastParameters
self.Behavior.HighFidelityBehavior = caster.HighFidelityBehavior.Default
self.Behavior.MaxDistance = self.MaxDistance
self.Behavior.Acceleration = self.Gravity
self.Behavior.CosmeticBulletContainer = self.BulletParent
self.Behavior.CosmeticBulletProvider = self.PartCache
self.Behavior.AutoIgnoreContainer = false
end
return setmetatable(self, setup)
end
function setup:Fire(mousePos, endPos)
local distBeforeMult = self.DistanceBeforeMultiply
local player = self.Owner
local hitbox = self.Hitbox
local speed = self.Speed
local damage = self.Damage
local gravity = self.Gravity
local multiplier = self.Multiplier
local behavior = self.Behavior
local cache = self.PartCache
local params = self.RaycastParameters
local attackType = self.AttackType
local maxSpread = self.MaxSpread
local minSpread = self.MinSpread
local direction = (mousePos - endPos).Unit
local debounce = {}
local connection = {}
VisualizePos(endPos, BrickColor.Red())
VisualizePos(mousePos, BrickColor.Green())
connection[1] = hitbox.LengthChanged:Connect(function(caster, origin, direction, length, velocity, bullet)
if not bullet then
return
end
if bullet:FindFirstChildWhichIsA("Trail") then
bullet:FindFirstChildWhichIsA("Trail").Enabled = true
end
local bulletLength = bullet.Size.Z / 2
local baseCFrame = CFrame.new(origin, origin + direction)
bullet.CFrame = baseCFrame * CFrame.new(0, 0, -(length - bulletLength))
end)
connection[2] = hitbox.RayHit:Connect(function(caster, ray, velocity, bullet)
local hitPart = ray.Instance
local hitPoint = ray.Position
local normal = ray.Normal
local model = ray.Instance:FindFirstAncestorOfClass("Model")
local hum = model and model:FindFirstChildOfClass("Humanoid")
fx:FireAllClients(if hum then effect.blood else effect.hit, hitPart, hitPoint)
LoadBulletHole(hitPart, hitPoint, ray.Normal, hum)
if hum and not PS:GetPlayerFromCharacter(model) then
if debounce[hum] then
return
end
--if attackType == "Destroying" then
-- local blacklist = {"Torso", "HumanoidRootPart"}
-- local rand = Random.new():NextInteger(1,65)
-- if rand <= 25 and hitPart and not table.find(blacklist, hitPart.Name) then
-- hitPart.Transparency = 1
-- task.delay(.4, function()
-- hitPart:Destroy()
-- end)
-- end
--end
local currDamage = if multiplier[hitPart.Name] then damage * multiplier[hitPart.Name] else damage
if player:DistanceFromCharacter(hitPoint) < distBeforeMult then
currDamage *= 1.3
end
debounce[hum] = true
hum:TakeDamage(currDamage)
damageDisplay.new(currDamage, hitPart)
end
end)
connection[3] = hitbox.CastTerminating:Connect(function(caster)
local cosmeticBullet = caster.RayInfo.CosmeticBulletObject
if cosmeticBullet then
if behavior.CosmeticBulletProvider then
pcall(function()
if cosmeticBullet:FindFirstChildWhichIsA("Trail") then
cosmeticBullet:FindFirstChildWhichIsA("Trail").Enabled = false
end
behavior.CosmeticBulletProvider:ReturnPart(cosmeticBullet)
for i,v in ipairs(connection) do
v:Disconnect()
end
end)
end
end
end)
pcall(function()
local dirCF = CFrame.lookAt(Vector3.new(), direction)
local spreadDir = CFrame.fromOrientation(0, 0, math.random(0, math.pi * 2))
local spreadAngle = CFrame.fromOrientation(math.rad(math.random(minSpread, maxSpread)), 0, 0)
local direction = (dirCF * spreadDir * spreadAngle).LookVector
local modifSpeed = (direction * speed)
hitbox:Fire(endPos, direction, modifSpeed, behavior)
end)
end
return setup
I’m not really sure how I can solve this. Any help is appreciated!
EDIT: I think I solved it. I just moved the muzzle point backwards by a few studs (it’s now practically in the player’s shoulder).
Hello, The module fastcast is really incredible but i’m having some maths problem.
Id like to use it to simulate a ball physics but i have 2 problems first of all i can’t quite understand how i could simulate real bounce from the ball and how i could change the velocity to make a curve to the right
https://gyazo.com/12d664dba0bc03494da717901cb21b1f
like this for exemple
if you have any tips i’m taking theù
Hi,
Does anyone know if for a bullet to hit / detect a part has to have transparency on?
I have a part with a decal, and the part is transparent, but it does not detect hits on the part. Meaning the bullets go through it.
If I turn transparency on then it hits it.
Is there anyway around this?
I have also checked that CanCollide and CanQuery are checked = set to True and the HumanoidRootPart, which is big enough to hit, and has Transparent = 1 On
Thanks
Would recommend adding another property to the Fire function to include userdata from the start.
I added it to my copy of fastcast and it’s very useful.
2 Questions,
How do I make the direction it shoots set to the way the barrel part is pointing. (Instead of shooting where the mouse is pointing.)
And also, how do I make multiple barrels?
this is probably a dumb question but is this module safe to be required in every tool without heavy performance issues?
How can I blacklist all no collide able parts?
An easy way is to set them all under the same collision group. That way when you set your raycast params, set the collision group to one that doesn’t collide with that one.
https://developer.roblox.com/en-us/api-reference/datatype/RaycastParams
Alternatively, if it suits you better, group them all under the same model and blacklist the whole model.
Anyone have any advice for optimising networking with fastcast? I’m using it for my 3rd person gun scripts and the communication between client-server is taking up a lot of data, more than that is acceptable. Anyone have some solutions?
That’s weird, how come? What data are you handing over to the server? A resource I’d refer to regardless: BridgeNet | Insanely optimized, easy-to-use networking library full of utilities, now with roblox-ts! | v1.9.8-beta
This is all im handing over
FireHandler:FireServer(Gun.Barrel.FirePoint.WorldPosition,mousePos,Settings)
2 Vector3s and a Settings table for all the guns characteristics