How to make good bullet projectiles?

im having problems with the module FastCast: Redux.

(the viewmodel is a viewmodel rig, not the characters arms) when i fire my gun, if im standing still they will go out of the viewmodels barrel, but if im moving they will not come out the center of the viewmodels barrel and will be off a little by a few studs, and it looks really weird, i have tried a bunch of things but none of them work, any reason this is happening or is there ways to fix it? maybe a different module that might work?

i can supply a video of whats happening if anyone wants one.

Are you projecting the bullet on the client end? (I don’t know how FastCast works)
If so, it’s just the server being slow on replicating the bullet to the client and thus making it appear where it should’ve been frames ago.
In that case, try to make the bullet with localscripts and then have the server do bullet physics.

RemoteEvents also do the same things when you trigger something to activate on server and it appears a bit too late, making it look weird.

a problem with that is that you cant see bullet tracers when you make the bullet local, and i want to be able to see bullet tracers from someone elses gun, and from what i remember, making hit registration local gives bad hit registration.

i could try making the bullet local and the hit registration server, but the tracers would be invisible to other players, even then i dont think making a bullet local then making hit reg server is possible, since the bullet is local.

I have little experience in making guns, but here’s what I know about how developers go about doing this.

Player client: Show ADS, first person animationsbullet tracers, hitmarkers, etc

Server: Handle raycasts and hit registration

Other clients: Render third person animations and bullet tracers.

In other words for your situation, you need to fire remote events to the other clients so they can see the tracers on their end

i was scripting the gun in a way that made it so that the bullets were fired from the server, now i know what im doing wrong, i have one question about this, how would i go about making the tracers be seen by other players?

After replicating on client’s end and sending the stuff to the server, the server can replicate the bullet to other clients.
So the bullet is perfectly timed on your screen but for others, it’s slightly delayed which should be fine.

ok, thanks, ill try that out, if it works ill set your comment to solution.

hello i found solution.

you just calc bullet projectile by server, and just display at local

example :

server code :

local cooldowns = {}

local bullets = {}

local BulletID = 0

local gravity = Vector3.new(0, -9.8, 0)

local Bullet_Speed = 500

local Max_Distance = 3000

game.ReplicatedStorage.Network.AddBulet.OnServerEvent:Connect(function(plr, spos, dir)
	if cooldowns[plr] then return end

	cooldowns[plr] = true

	task.delay(1, function()
		cooldowns[plr] = nil
	end)

	table.insert(bullets, {
		['BulletID'] = BulletID,
		['CFrame'] = CFrame.new(spos, spos + dir),
		['Speed'] = 75,
		['Time'] = 0,
		['Velocity'] = dir.Unit * Bullet_Speed,
	})

	BulletID += 1
end)

function DestroyBullet(index)
	game.ReplicatedStorage.Network.BulletDestroyed:FireAllClients(bullets[index].BulletID)
	
	print(bullets[index].BulletID)
	
	table.remove(bullets,index)
end

game["Run Service"].Stepped:Connect(function(_, d)
	for i, v in pairs(bullets) do
		v.Time += d
		
		if v.Time * Bullet_Speed >= Max_Distance then
			DestroyBullet(i)
		end
		
		v.Velocity += gravity * d

		local displacement = v.Velocity * d
		local newPosition = v.CFrame.Position + displacement

		v.CFrame = CFrame.new(newPosition, newPosition + v.Velocity.Unit)

		game.ReplicatedStorage.Network.BulletUpdated:FireAllClients(v)
		
		local raycast = workspace:Raycast(newPosition - v.Velocity.Unit,v.Velocity.Unit * 6)

		if raycast then
			if raycast.Instance.Parent:FindFirstChild('Humanoid') then
				raycast.Instance.Parent:FindFirstChild('Humanoid'):TakeDamage(100)
			end
			
			if raycast.Instance.Parent.Parent:FindFirstChild('Humanoid') then
				raycast.Instance.Parent.Parent:FindFirstChild('Humanoid'):TakeDamage(100)
			end
			
			DestroyBullet(i)
		end
	end
end)

local code :

local VisualBullets = {}

local DestroyedBullets = {}

game.ReplicatedStorage.Network.BulletDestroyed.OnClientEvent:Connect(function(id)
	VisualBullets[id]:Destroy()
	VisualBullets[id] = nil
	
	DestroyedBullets[id] = true
end)

game.ReplicatedStorage.Network.BulletUpdated.OnClientEvent:Connect(function(info)
	if not VisualBullets[info.BulletID] then
		if DestroyedBullets[info.BulletID] then return end
		
		VisualBullets[info.BulletID] = Instance.new('Part', workspace)
		VisualBullets[info.BulletID].Anchored = true
		VisualBullets[info.BulletID].CanCollide = false
		VisualBullets[info.BulletID].Size = Vector3.new(1, 1, 4)
	end

	VisualBullets[info.BulletID].CFrame = info.CFrame
end)

local p = game.Players.LocalPlayer
local m = p:GetMouse()

local isShooting = false

m.Button1Down:Connect(function()
	if p.Character then
		isShooting = true
		
		while isShooting do
			local dir = -(p.Character.HumanoidRootPart.Position - m.Hit.Position).Unit
			game.ReplicatedStorage.Network.AddBulet:FireServer(p.Character.HumanoidRootPart.Position, dir)
			task.wait(1)x
		end
	end
end)

m.Button1Up:Connect(function()
	isShooting = false
end)
1 Like

i forgot to close this post but thank you for responding.

i have already fixed this.
instead of using fastcast, i created my own projectile module that works very differently to fastcast and instead of running projectiles on the server, i run them on both.

the server handles server tracers that are only for visual effect.
the client handles hit registration and client tracers.

theres also a GUI that gives tracers stuff like motion blur and visual curving.
the GUI gives your client tracers and other players server tracers effects but doesnt give your server tracers effects.

i could get into depth about how the tracer effect GUI works but its complicated so i wont do all of it in a reply.

bye