Making a combat game with ranged weapons? FastCast may be the module for you!

Its a display bug. The bullet’s speed is so high that LengthChanged fires once, but the ray terminates immediately, so you never get a chance to see the bullet. This has nothing to do with fire rate, just projectile velocity.

1 Like

Oh alright got it. Thanks for replying!

I’ve just realised that the camera orientation affects the direction of the ray from a player’s gun to their cursor position. Is there a setting to make it so that it’s only a straight ray from the origin?

Great module, unclear instructions.

1 Like

I’m not sure if you’re aware of this already, but there is currently a very annoying bug in fast cast redux. The bug from what I have experienced mostly happens when using tools, and what it is is that it makes your origin position lower than it actually is, making your bullets come from the ground or your feet.

https://streamable.com/pbi77p

This clip here shows the problem.
Also Clarifications:
I did use an attachment for the position and I used world position
I did weld everything Correctly
I am also pretty sure I scripted it correctly
The bullets are being created server side, not client side

This is my Client side script

local plyr = game.Players.LocalPlayer

local tool = script.Parent

local fastcast = require(tool:WaitForChild("FastCastRedux"))

local eventfire = tool:WaitForChild("Fire")

local m = plyr:GetMouse()

tool.Activated:Connect(function()

local mpos = m.Hit.Position

eventfire:FireServer(mpos)

end)

This is my Server Side

local tool = script.Parent

local eventfire = tool.Fire

local fastcast = require(tool:WaitForChild("FastCastRedux"))

local firepos = tool.Hole:WaitForChild("Attachment")

local bf = workspace.Terrain:FindFirstChild("BulletsFolder") or Instance.new("Folder")

bf.Name = "BulletsFolder"

bf.Parent = workspace.Terrain

local BT = Instance.new("Part")

BT.Anchored = true

BT.CanCollide = false

BT.Size = Vector3.new(.25,.25,1)

fastcast.VisualizeCasts = false

local caster = fastcast.new()

local castParams = RaycastParams.new()

castParams.FilterType = Enum.RaycastFilterType.Blacklist

castParams.IgnoreWater = true

local castBehavior = fastcast.newBehavior()

castBehavior.RaycastParams = castParams

castBehavior.Acceleration = Vector3.new(0,math.random(-2.5,2.5),0)

castBehavior.AutoIgnoreContainer = false

castBehavior.CosmeticBulletContainer = bf

castBehavior.CosmeticBulletTemplate = BT

local function onEquipped()

castParams.FilterDescendantsInstances = {tool,bf}

end

local function onLengthChanged(cast,lp,d,length,vel,bullet)

if bullet then

local BL = bullet.Size.Z/2

local offset = CFrame.new(0,0,-(length-BL))

bullet.CFrame = CFrame.lookAt(lp,lp+d):ToWorldSpace(offset)

end

end

local function onRayHit(cast,result,velocity,bullet)

local hit = result.Instance

local e = Instance.new("Explosion")

e.Parent= workspace

e.Position = bullet.Position

bullet:Destroy()

end

local function fire(plyr, pos)

local o = firepos.WorldPosition

local d = (pos-o).Unit

caster:Fire(o,d,50, castBehavior)

end

eventfire.OnServerEvent:Connect(fire)

tool.Equipped:Connect(onEquipped)

caster.LengthChanged:Connect(onLengthChanged)

caster.RayHit:Connect(onRayHit)

I remember seeing this problem before though I don’t remember where it was in community resources.

Without looking at the script I believe the issue is caused by the velocity inheritance because the view model is unanchored and so it’s still experiencing gravity though it may not be visible if the viewmodel is constantly being CFramed during renderstep which causes the bullet to be spawning down because of the high velocity going downwards.

Hopefully, I can find the other post where the guy has experienced the same problems.

Edit: Searching online I found this which confirms anchoring solved the problem but it’s not the exact post I was looking for:

Edit 2: Found the specific post in this other tutorial not resource

1 Like

this is very helpful for viewmodels, but doing this on a tool is impossible.

edit: I said view models cause i didn’t know if the guy was aware, but I’ll remove the view model part now since he I know he is aware and there is a fix for it.

that is due to the speed you set the bullet to. The faster the speed, the more distance from the gun it will be. The bullet is still technically starting from the starting point, but it’s just moving so fast that our eyes can’t see it. You can compensate for this by making the bullet longer.

1 Like

Not one that’s built in. You just need to cast a ray from gun end to mouse position. That’s what I do, so I’m not sure why the direction changes.

Yeah I’m also confused then, when looking down for example with your camera and clicking instead of travelling in a straight line the ray travels downwards because the mouse is facing downwards due to the camera influencing the mouse’s 3d position.

Having the same issue here, I mean I understand that by logic you should not be terminating a cast in events. However, I am working on a ping compensation system which uses regions as hitboxes, instead of instancing actual parts for performance reasons.

However this means, that I want the cast to stop if it hit a player hitbox, which is checked each segment.

You should be able to instance a single part for every player and recycle it (i.e. one part per player slot) – CFraming parts is the fastest update possible for them. Size is a bit slower, but I don’t think it’ll have any performance loss even if you do it every frame (and afaik, if your hitbox size is constant, you only need to CFrame - very good!) Disabling CanTouch would further help that.

1 Like

Hmm, yes. I’ve thought about implementing it that way before, using partCache for hitboxes, however I ran into multiple issues in the logic.

  1. Instance x (8 - client = 7 for example) amount of hitboxes for each caster
  2. Add the shooter’s ping into userdata
  3. When caster fires cframe those hitboxes based on previously saved player cframes and shooter’s ping
    However, since projectiles are not instant this means players have quite possibly moved while the projectile is travelling.
  4. That means cframing again for every segment to make sure they are moved ahead in time
  5. Projectile hits an instance, casting is complete.

There are two issues with this method:

  1. Let’s say the maximum travel time on a projectile is two seconds, and the gun can fire every 0.5 seconds. That means we can be tracking up to 4 projectiles in a span of two seconds, which means I need 7players x 4 instances in just those two seconds for one player firing. Now combine that with other 7 players firing and we get a total of: 196 hitbox instances required at a time for the server to calculate the hitboxes, also keep in mind this is a slow firing tool. 2 bullets per seconds is nothing.
  2. Furthermore since they are instances I cannot easily contain the hitboxes to only one cast. Then I am forced to create extra logic which makes sure that casts do not collide with other casts hitboxes. CanPierce can be used for this so I don’t think it’s a huge limitation.

Still adding a 1000 instances of a hitbox so the server always has enough, for high firerate guns and even if I increase the player count. Sure this would happen only once, but how much memory is that going to take up among other performance concerns.

EDIT: For anyone wondering, I managed to go around this limitation. Since I have a function which is fired whenever the cast hit something I trigger it when a player has been hit. I also save a boolean into cast.UserData which is set to true when a player has been hit, and the server sends information to stop rendering this bullet to all clients. Since HitPlayer is true now, the script ignores any other hits the ray makes from this point on. Basically it’s still casting until reaching maximum distance or hitting something, but it has no effect.

1 Like

How do we use the CanPierceFunction??

Does this module fix the client-server delay for projectiles

Fast cast is too powerful. Made a minigun:

https://we.tl/t-C6WThdzfbj

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.

2 Likes

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.

1 Like