Hold and shoot projectile

I’ve been trying to learn how to create projectiles recently, but I seem to have some major flaws.
I want to be able to hold a projectile in-front of the player until they let go of the m1 button. Something very similar to the games World Of Magic, and Elemental awakening.

https://gyazo.com/69c8a4f7e960544c2389ca32f2682dd9

The way I tried making this was by creating the projectile when they hold down m1 and firing an event, then shooting it towards the mouse’s direction when another event is fired after they let go of m1, but after spamming the projectiles, previously shot bullets are destroyed. I need them to despawn after a few seconds, but it’s destroying newly shot bullets, and bullets that haven’t reached the despawn time aswell.

I am also curious on if there are any ways to make the bullet smoother when firing.

Also, after destroying many bullets after some time, shooting just one projectile freezes the game for about 1/4 of a second. I don’t know if this has to do with clearing the projectile after a bit but it gets really laggy after shooting for a bit.

https://gyazo.com/f5e93a77e79228232e05da989af05849
https://gyazo.com/c528a48c30ba9d204eaaad58ef493bdb

I’ve tried adding a cooldown to the projectile, but then reconsidered because I want the player able to shoot multiple projectiles, and also because my attempt at making a cooldown for it failed. I do not know any other kinds of methods to fix it.

What I have right now:

cf4fa81fbbb170da15eaf93eebb9f7c0

Localscript code inside of the tool:

local MakeBullet = script:WaitForChild("MakeBullet")
local ShootBullet = script:WaitForChild("ShootBullet")

local player = game:GetService("Players").LocalPlayer
local mouse = player:GetMouse()

script.Parent.Equipped:Connect(function(mouse)
		mouse.Button1Down:Connect(function()
			MakeBullet:FireServer()
		mouse.Button1Up:Connect(function()
			ShootBullet:FireServer(mouse.Hit.p)
		end)
	end)
end)

Script inside of Localscript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Make = script.Parent.MakeBullet
local Shoot = script.Parent.ShootBullet

Make.OnServerEvent:Connect(function(player) 
	local character = player.Character
	local rp = character.HumanoidRootPart
	bullet = ReplicatedStorage.StarBolt:Clone() 

	bullet.Parent = workspace
	bullet.CFrame = rp.CFrame * CFrame.new(0,0,-3)

	weld = Instance.new("WeldConstraint",bullet)
	weld.Part0 = bullet
	weld.Part1 = character.HumanoidRootPart
end)

Shoot.OnServerEvent:Connect(function(player, mousePos)
	local Speed = Instance.new("BodyVelocity")
	Speed.Parent = bullet
	Speed.MaxForce = Vector3.new(1e6,1e6,1e6) 
	Speed.Velocity = CFrame.new(bullet.Position, mousePos).LookVector * 35 

	weld:Destroy()

	game.Debris:AddItem(bullet, 4)
end)
3 Likes

U should make ur own projectile system instead of using velocity. here’s some things u can do:

Getting the direction:

local hitPos = mouse.Hit.p
local direction = (handle.Position - hitPos).unit

Calculating the new position ( every heartbeat or so )

local speed = 3.5
bullet.CFrame = bullet.CFrame:lerp(CFrame.new(bullet.Position + direction * speed, hitPos)

I’d recommend using CFrame.lookAt, games like arsenal use lookAt

Hello, I think I’ve overcome your problem.
Server script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Make = ReplicatedStorage:FindFirstChild("MakeBullet") or ReplicatedStorage:WaitForChild("MakeBullet")
local Shoot = ReplicatedStorage:FindFirstChild("ShootBullet") or ReplicatedStorage:WaitForChild("ShootBullet")

Make.OnServerEvent:Connect(function(player) 
	print("a")
	local character = player.Character or player.CharacterAdded:Wait()
	local rp = character.HumanoidRootPart
	bullet = ReplicatedStorage.Part:Clone() 
	bullet.Name = "Bullet"
	bullet.Parent = workspace
	bullet.CFrame = rp.CFrame * CFrame.new(0,0,-3)

	weld = Instance.new("WeldConstraint",bullet)
	weld.Part0 = bullet
	weld.Part1 = character.HumanoidRootPart
end)

Shoot.OnServerEvent:Connect(function(player, mousePos)
	local Speed = Instance.new("BodyVelocity")
	Speed.Parent = bullet
	Speed.MaxForce = Vector3.new(1e6,1e6,1e6) 
	Speed.Velocity = CFrame.new(bullet.Position, mousePos).LookVector * 35 

	weld:Destroy()

	game.Debris:AddItem(bullet, 4)
	bullet = nil -- here's what solved the problem, I think
end)

Local script:

local MakeBullet = game.ReplicatedStorage:FindFirstChild("MakeBullet") or game.ReplicatedStorage:WaitForChild("MakeBullet")
local ShootBullet = game.ReplicatedStorage:FindFirstChild("ShootBullet") or game.ReplicatedStorage:WaitForChild("ShootBullet")

local player = game:GetService("Players").LocalPlayer
local mouse = player:GetMouse()

script.Parent.Equipped:Connect(function()
	Function1 = mouse.Button1Down:Connect(function()
		MakeBullet:FireServer()
		Function2 = mouse.Button1Up:Connect(function()
			ShootBullet:FireServer(mouse.Hit.p)
			Function2:Disconnect()
		end)
	end)
end)
script.Parent.Unequipped:Connect(function()
	Function1:Disconnect()
end)
1 Like