How do we use the CanPierceFunction??
Does this module fix the client-server delay for projectiles
See CanPierceFunction in the docs for more information on this, including an example.
No, this does not perform any special networking compensation. It is strictly a means of firing projectiles.
I honestly can’t figure out why, maybe I’m really dumb and I overlooked something obvious, but the cosmetic bullets aren’t moving. When I fire my gun the VisualizeCasts shows the projectile moving, but the bullet spawns in front of the gun and stays there. When I unanchor the bullet part it just falls through the ground.
Edit: nvm I figured it out with a yt tutorial
I’m having an issue with FastCast. It goes on an infinite error loop and is causing horrible lag:
10:58:26.972 ReplicatedStorage.FastCastRedux.ActiveCast:122: attempt to perform arithmetic (mul) on table and number - Client - ActiveCast:122
I’m also getting another error before the loop starts:
11:57:23.933 WorldRoot is not a valid member of Vector3 - Server - FastCastRedux:140
This is how I’m firing the cast.
RaycastParams, CastBehavior and Caster:
local castBehaviour = fastCast.newBehavior()
local castParams = RaycastParams.new()
castParams.FilterDescendantsInstances = {plr.Character}
castParams.FilterType = Enum.RaycastFilterType.Blacklist
castParams.IgnoreWater = true
castBehaviour.RaycastParams = castParams
castBehaviour.MaxDistance = 1000
castBehaviour.CosmeticBulletTemplate = game.ReplicatedStorage.CosmeticBullet
castBehaviour.CosmeticBulletContainer = game.Workspace
Client:
direction = (mouse.Hit.p - gunModel.MuzzleFlash.Position).Unit
remoteEvent:FireServer(gunModel.MuzzleFlash.Position, direction, 300)
Server:
mouseEvent.OnServerEvent:Connect(function(client, origin, direction, velocity)
castParams.FilterDescendantsInstances = {client.Character}
caster.Fire(origin, direction, velocity, castBehaviour)
gunModel.MuzzleFlash.MuzzleEffect:Emit(60)
gunModel.BodyAttach["Fire" .. math.random(1, 3)]:Play()
end)
What’s happening? I believe that I used the function and made the cast behaviour correctly but it goes on an infinite error loop whenever I try to fire the cast.
sorry for any lack of information given, I’m kinda on a rush right now.
Edit: I switched the bullet firing to the server, but I’m still getting the same problem. I’ll try to update code samples when I can.
caster.Fire(origin, direction, velocity, castBehaviour)
caster:Fire()
, not caster.Fire
- that’s the only obvious error I can see right now. Other than that I’m not sure from the code you’ve provided.
The issue seems to have been fixed after replacing the dot with a semicolon. Thought it would be just a dot considering FastCast is a module script, but I guess there’s some differences with the two.
Thanks anyway.
Very interesting! I made a similar system like yours (before I discovered this) but with less features and lines of code. It works by having a table of all active rays then also the heartbeat event to update them all. It is a lot more simple as well.
Great work!
After the max distance is reached how do we destroy the projectile that was shot since it would just be frozen in the air? Is it terminate if so what do we pass through the event?
The best part is that since I use Heartbeat, the bullet will accommodate for lag. In the event of any lag, the cast will move how much it should’ve moved as if there was no lag at all, ensuring that it stays on time and remains consistent to the motion values you specifed.
How does Heartbeat work, then?
I’ve been wrestling with this issue for a bit and can’t seem to find a solution. How does one work around this problem? It works perfectly fine when my origin isn’t inside a block, but when it is, it doesn’t register hitting the block when it shoots.
Is there an efficient way I can solve/ work around this?
Have you tried blacklisting the player’s character and the cosmetic bullets from the raycast? I’ve come across that issue before and that’s what I had to do to fix it.
Also for blacklisting cosmetic bullets I recommend you just set the cosmetic bullet container to a good Folder in the workspace and then blacklist that container.
Yes, I have blacklisted both the cache folder and the character, but I don’t think that’s the issue. A bullet flying through other blocks shouldn’t have anything to do with blacklisting your character and bullet cache folder.
If you misunderstood, here’s a video of my issue ^^.
Heartbeat has a parameter when it fires that is the amount of time the heartbeat took. Under normal cases, this is 1/60
. If there is lag and the server is running at, say, 15 ticks/sec rather than the target 60 for heartbeating, that value will be 1/15
which is far larger than 1/60
. This time is used to stretch or compress the individual ray segments so they stay on track at the cost of accuracy.
You are correct in that this is not the issue. The issue actually comes from the fact that the end of the barrel is inside of the wall. A ray only hits from the outside. Spawning a ray inside of the object and firing outwards will cause it to completely miss the object.
An easy(?) solution is to cast a single custom raycast (unrelated to FC) from the butt of the gun to the barrel to see if it runs into any world objects. If it does, just play the fire sound but don’t actually fire a bullet.
You do use terminate. Have a look at the example gun – The terminate event gives you a reference to the bullet’s ActiveCast which contains its cosmetic bullet. You can dispose of it appropriately there.
what are the tuple arguments for the terminate event?
Anyone know where do I put the pierce function since right now I am putting it in the ray hit event.
It will print true but the bullets would not go through
local caster = FastCast.new()
local castParams = RaycastParams.new()
castParams.FilterType = Enum.RaycastFilterType.Blacklist
local newBullet = Instance.new("Part", Folder)
newBullet.Size = Vector3.new(0.1, 0.1, 1)
newBullet.Material = Enum.Material.Neon
newBullet.Shape = Enum.PartType.Block
newBullet.CanCollide = false
newBullet.Anchored = true
newBullet.Color = Color3.fromRGB(209, 130, 6)
local castBehavior = caster.newBehavior()
castBehavior.RaycastParams = castParams
castBehavior.Acceleration = Vector3.new(0,(-workspace.Gravity/2)+ (BulletDrop),0)
castBehavior.CosmeticBulletContainer = Folder
castBehavior.CosmeticBulletTemplate = newBullet
castBehavior.CanPierceFunction = nil
castBehavior.MaxDistance = 100
local function OnLengthChanged(cast, lastPoint, direction, length, velocity, bullet)
if bullet then
local bulletLength = bullet.Size.Z/2
local offset = CFrame.new(0,0, -(length - bulletLength))
bullet.CFrame = CFrame.lookAt(lastPoint, lastPoint + direction):ToWorldSpace(offset)
Debris:AddItem(bullet, .5)
end
end
local function OnRayHit(cast, result, velocity, bullet)
local hit = result.Instance
local ECharacter = hit.Parent
if ECharacter and ECharacter:FindFirstChildWhichIsA("Humanoid")and hit:IsA("BasePart") then
Debris:AddItem(bullet, .01)
local Humanoid = ECharacter:FindFirstChildWhichIsA("Humanoid")
if not game.Players:GetPlayerFromCharacter(ECharacter) then
Humanoid:TakeDamage(BulletDamage)
end
elseif not ECharacter:FindFirstChildWhichIsA("Humanoid") and hit:IsA("BasePart") then
local HitPierce = Pierce(cast, result, velocity)
print(HitPierce)
end
end
Event.OnServerEvent:Connect(function(player, mouseP)
if player == game.Players:GetPlayerFromCharacter(Tool.Parent) then
local Character = player.Character
local RNG = Random.new()
castParams.FilterDescendantsInstances = {Character, Tool, Folder}
castParams.IgnoreWater = false
Raycast_Params.FilterDescendantsInstances = {workspace}
Raycast_Params.FilterType = Enum.RaycastFilterType.Blacklist
spawn(function()
for i = pelletsShot, maxpellets do
local origin = Tip.CFrame.p
local length = 100
local UnitDirection = (mouseP - origin).Unit
local pelletSpread = Vector3.new(RNG:NextNumber(-maximumOffset, maximumOffset), RNG:NextNumber(-maximumOffset, maximumOffset), 0)
local NewDirection = (UnitDirection + pelletSpread) * length
local Laser = workspace:Raycast(origin, NewDirection, Raycast_Params)
if Laser then
else
Laser = {}
Laser.Position = origin + NewDirection
end
local direction = (Laser.Position - origin).Unit
caster:Fire(origin, direction, BulletSpeed, castBehavior)
end
end)
end
end)
caster.LengthChanged:Connect(OnLengthChanged)
caster.RayHit:Connect(OnRayHit)
is it possible to force the CastTerminating event to run?
This is covered in the documentation for Caster.
Similarly, this is covered in the documentation for ActiveCast.