FastCast Bullet spawns ahead of fire point

I’m making an FPS, and using FastCast for bullets.

When firing, the bullet fires ahead of the fire point. The higher the velocity is, the farther it is.

100 Velocity Shot
(Velocity is 100)

1,000 Velocity Shot
(Velocity is 1,000)

Here is the code that moves the cosmetic bullet:
Cosmetic Code
(The size is for an older bullet that I might switch back to, I swapped it with a trail)

And here’s the code that fires it.

I think the problem is that the cast starts before the the bullet is created, but I’m not sure.

The fire point is on the tip of the gun.

You aren’t placing the bullet at the fire point, you are starting the bullet at
bullet.CFrame = CFrame.new(lastPoint + (direction * length))
Try rendering it at (or just slightly past) the fire point first, then add the (lastPoint + (direction * length))

I probably know how to set the bullet’s position to the fire point, but I don’t know when, I don’t think there’s an event for when the bullet fires, and the lengthChanged function fires immediately after the bullet is made

Where in the script is the onLengthChanged function fired?
I’d think you need to make sure that the first bullet.CFrame = CFrame.new(lastPoint + (direction * length)) has the lastPoint at whatever location the fire point is, but make sure that direction * length is set at 0 for the first render.

It’s below the function that fires when the ray hits something, and above the function that fires the bullet. Here’s the entire script:

local fireEvent = script.Parent:WaitForChild("Fire")

local FastCast = require(game.ServerStorage:WaitForChild("FastCastRedux"))
local PartCache = require(game.ServerStorage.PartCache)

local origin = Vector3.zero
local direction = Vector3.zero

local bulletsFolder = workspace:FindFirstChild("BulletFolder") or Instance.new("Folder", workspace) 
bulletsFolder.Name = "BulletFolder"

--make base bullet
local bulletTemplate = Instance.new("Part")
bulletTemplate.Anchored = true
bulletTemplate.CanCollide = false
bulletTemplate.Shape = "Ball"
bulletTemplate.Size = Vector3.new(0.2,0.2,0.2)
bulletTemplate.Material = Enum.Material.Neon
bulletTemplate.CastShadow = false
bulletTemplate.Color = Color3.new(1,1,0)
bulletTemplate.Transparency = 1

--make attachments for trail
local leftAttach = Instance.new("Attachment", bulletTemplate)
leftAttach.Position = Vector3.new(-0.15,0,0)
local rightAttach = Instance.new("Attachment", bulletTemplate)
rightAttach.Position = Vector3.new(0.15,0,0)

--trail itself
local trail = Instance.new("Trail", bulletTemplate)
trail.Color = ColorSequence.new{
	ColorSequenceKeypoint.new(0, Color3.new(1,1,1)),
	ColorSequenceKeypoint.new(0.03, Color3.new(1,1,1)),
	ColorSequenceKeypoint.new(0.4, Color3.new(1,1,0.1)),
	ColorSequenceKeypoint.new(0.75, Color3.new(1,0,0)),
	ColorSequenceKeypoint.new(1, Color3.new(0,0,0))
}
trail.FaceCamera = true
trail.LightEmission = 1
trail.LightInfluence = 1
trail.Transparency = NumberSequence.new{
	NumberSequenceKeypoint.new(0, 0),
	NumberSequenceKeypoint.new(1, 1)
}
trail.Archivable = true
trail.Attachment0 = leftAttach
trail.Attachment1 = rightAttach
trail.Enabled = false
trail.Lifetime = 0.2

local caster = FastCast:new()

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
rayParams.FilterDescendantsInstances = {script.Parent, bulletsFolder}

local bulletCache = PartCache.new(bulletTemplate, 100, bulletsFolder)

local behavior = FastCast:newBehavior()
behavior.Acceleration = Vector3.new(0, -workspace.Gravity, 0)
behavior.IgnoreWater = true
behavior.AutoIgnoreContainer = false
behavior.RaycastParams = rayParams
behavior.CosmeticBulletContainer = bulletsFolder
behavior.CosmeticBulletProvider = bulletCache

local function onRayHit(cast, result, velocity, bullet)
	local hit = result.Instance
	
	local character = hit:FindFirstAncestorWhichIsA("Model")
	if character and character:FindFirstChild("Humanoid") then
		if hit.Name == "Head" then
			character.Humanoid:TakeDamage(50)
		elseif hit.Name == "LeftUpperLeg" or hit.Name == "LeftLowerLeg" or hit.Name == "LeftFoot" or hit.Name == "RightUpperLeg" or hit.Name == "RightLowerLeg" or hit.Name == "RightFoot" then
			character.Humanoid:TakeDamage(10)
		else
			character.Humanoid:TakeDamage(20)
		end
	end
	
	delay(2, function()
		bullet.Trail.Enabled = false
		bulletCache:ReturnPart(bullet)
	end)
end

local function onLengthChanged(cast, lastPoint, direction, length, velocity, bullet)
	bullet.Trail.Enabled = true
	if bullet then
		bullet.CFrame = CFrame.new(lastPoint + (direction * length))
		--bullet.Size = Vector3.new(0.2,0.2,math.abs(velocity.Magnitude)/25)
	end
end

fireEvent.OnServerEvent:Connect(function(player, firePoint, fireDirection, ignore)
	origin = firePoint
	direction = (fireDirection - firePoint).Unit
	
	rayParams.FilterDescendantsInstances = {script.Parent, game.Workspace:WaitForChild(ignore), bulletsFolder}
	behavior.RaycastParams = rayParams
	
	caster:Fire(origin, direction, 1000, behavior)
end)

caster.LengthChanged:Connect(onLengthChanged)
caster.RayHit:Connect(onRayHit)
1 Like

did you find a solution? I’m having the same problem

You can do this frame check strat.

1 Like

To anyone still having any issues with this, you can simply add this code into the ActiveCast module on line 168, right before the module fires the LengthChanged signal.

if RunService:IsServer() then
	RunService.Heartbeat:Wait()
else
	RunService.RenderStepped:Wait()
end
2 Likes