Help with 3rd person shooter

Hello, I am making an game which will be a third person shooter game, unlike any other 3rd person shooter game mine will be different. There will be 5 types of bullets to choose from and each of them will have different abilities. Lets say one of them will shoot out even more bullets from itself and one of them will freeze players on hit. I have experience on programming as well, here are somethings i want to know

  1. How should i do the bullets flying? i know i can use fast cast BUT some of my bullets needs to follow wherever my character is pointing at and fast cast does not have that feature and i tried making one myself but its laggy and glichy
  2. How should i set up the bullets? like an module script for each which has functions like onHit() onFire() ?

heres my script which is the flying script

function module.newCast(Gravity, Param, Wind, DespawnTime, Control, mousePosVar, Visualize, SlugName)
	local newProjectile = {}

	newProjectile.Gravity = Gravity
	newProjectile.Wind = Wind
	newProjectile.DespawnTime = DespawnTime
	newProjectile.Visualize = Visualize
	newProjectile.Control = Control
	newProjectile.MousePosVar = mousePosVar

	newProjectile.Params = Param

	function newProjectile:Cast(start, dest, force)
		local conversion = 196.2 / 9.8
		local vForce = (dest - start).Unit * force * conversion
		local maxSpeed = vForce.Magnitude

		local gravityForce = Vector3.new(0, -self.Gravity * 9.8, 0) * conversion
		local windForce = Vector3.new(self.Wind.X, self.Wind.Y, self.Wind.Z) * conversion

		local currentCFrame = CFrame.new(start, start + vForce)
		local t = 0
		local tick_ = tick()
		local found = false

		local connection
		connection = runService.Heartbeat:Connect(function(dt)
			if found then return end

			t += dt

			local a = windForce
			if self.Control == 0 then
				a = a + gravityForce
			end

			local velocity = currentCFrame.LookVector * maxSpeed
			velocity = velocity + a * dt

			if self.Control ~= 0 and self.MousePosVar then
				local currentMousePos = self.MousePosVar.Value
				local homingDir = (currentMousePos - currentCFrame.Position).Unit
				local lerpFactor = math.clamp(self.Control * dt, 0, 1) -- Clamp lerpFactor to avoid instability
				local newDir = velocity:Lerp(homingDir * maxSpeed, lerpFactor).Unit
				currentCFrame = CFrame.new(currentCFrame.Position, currentCFrame.Position + newDir)
			end

			currentCFrame = currentCFrame * CFrame.new(0, 0, -velocity.Magnitude * dt)

			shooterRemotes.updateSlugPos:FireAllClients(tick_, currentCFrame, SlugName)

			local rayResult = workspace:Raycast(currentCFrame.Position, velocity * dt, self.Params)

			if rayResult or t > self.DespawnTime then
				found = true

				shooterRemotes.removeSlug:FireAllClients(tick_)

				onHit()
				connection:Disconnect()
			end
		end)
	end

	return newProjectile
end

I know OOP as well so yea

1 Like