Shoot a bullet in the direction of the mouse with linear trajectory

Hello guys, thats my first topic. So, how can i shoot bullet along an linear trajectory from first position to the mouse click position

Look at the code and the last comment to make it clearer to you



function create_bullet()
	local bullet = Instance.new("Part")
	bullet.Name = "bullet"

	bullet.Position = tool.ShootPartStart.Position
	bullet.CanCollide = false

	return bullet
end

function send(finish_Pos) -- finish_pos is position on mouse click
	local bullet = create_bullet()
	
	bullet.Parent = game.Workspace.BulletTrash
	
    local start_Pos = tool.ShootPartStart.Position
    
	-- moving bullet along a straight trajectory from start_Pos to finish_Pos
end
4 Likes

So you just want the guns beam to go to the mouse? Like wdym

I want the bullet to fly at the mouse click position

1 Like

so that you don’t get distracted, I was removed the excess from the code

1 Like

Ohh so you want a bullet to fly out instead of a beam

1 Like

I’m sorry for confusing you. Forget about beam. I just want the bullet to fly from the starting position to the position where I clicked the mouse. I probably need to do something with the velocity of the bullet, but unfortunately I don’t understand it well

2 Likes

Ohh ok unfortunately im on my phone so i will tell u as soon as i can

2 Likes

do you need it to be linear trajectory

1 Like

i dont have studio open rn so i cant write code for it, but you could make it so when u click the mouse first it gets your CFrame and then the mouse.Hit and then u can do CFrame:LookAt(mouse.Hit) and then u can use tween, or vector force, or whatever, but that should work

1 Like

When you create a bullet, instead of setting JUST the bullet’s position, set it’s CFrame to CFrame.new(tool.ShootPartStart.Position, finish_pos)

The second argument of CFrame.new() is the direction it is facing, so now you have a bullet facing it’s end position.

Now, you can just run bullet.CFrame *= CFrame.new(0, 0, -speed) every heartbeat. Finally, you should probably check if the bullet is too far from the gun’s barrel (using magnitude), at which point you would call :Destroy() on it.

If my writing is difficult to understand, apologies, you can reply to me and I’ll fix it :slight_smile:

1 Like

I GOT IT it took me like 15 min but here it is

so first I had to make my own scripts and stuff

heres the local

local gun = script.Parent
local re = script.Parent:WaitForChild("RemoteEvent")
local player = nil
local mouse = nil
local connection = nil

local debounce = false

local function onActivated()
	if debounce == false then
		debounce = true
		re:FireServer(mouse.Hit.Position)
		wait(0.5)
		debounce = false
	end
end

gun.Equipped:Connect(function()
	player = game.Players.LocalPlayer
	mouse = player:GetMouse()
	connection = gun.Activated:Connect(onActivated)
end)

gun.Unequipped:Connect(function()
	player = nil
	mouse = nil
	connection:Disconnect()
end)

heres the server

local tool = script.Parent
local re = script.Parent:WaitForChild("RemoteEvent")
local player = nil
local mouse = nil
local connection = nil

local TweenService = game:GetService("TweenService")

local debounce = false



function create_bullet()
	local bullet = Instance.new("Part")
	bullet.Name = "bullet"

	bullet.Position = tool.ShootPartStart.Position
	bullet.CanCollide = false

	return bullet
end

local function send(player,finish_Pos) -- finish_pos is position on mouse click
	local bullet = create_bullet()

	bullet.Parent = game.Workspace.BulletTrash
	bullet.CFrame = CFrame.lookAt(bullet.Position, finish_Pos)

	local start_Pos = tool.ShootPartStart.Position
	
	local Attachment = Instance.new("Attachment",bullet)
	Attachment.Name = "Attachment"

	local Tween = 	TweenService:Create(
		
		bullet,TweenInfo.new(0.2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false),
		
		{Position = finish_Pos} 
	)
	

	Tween:Play()
	-- moving bullet along a straight trajectory from start_Pos to finish_Pos
end

re.OnServerEvent:Connect(send)

and heres my explorer
image
heres the result


and thats it!

2 Likes

Wait, but if the tweenTime is the same regardless of distance, wouldn’t that cause a few problems?

1 Like

image

Don’t use tween it will travel faster if the distance is larger or slower if the distance is short. Instead, you can use Final Position = StartingPos + velocity*Time

1 Like

yes it would I forgot to mention I turned up the velocity to really fast

1 Like

what about it? the name???

1 Like

Your time is constant and that will result in weird-looking bullets

Example:
1 second to travel 1 meter = fine
1 second to travel 1km = not fine
1 second to travel 1 light year = :skull:

1 Like

uhhh sorry I still don’t understand what ur saying

1 Like

If you threw a ball and it traveled 10 meters in 1 second that would look natural but if the same ball traveled 100000 meters in 1 second it would zoom past. My point is that the time staying still will result in the object moving at different speeds

1 Like

yes it will your right because im not very good at the guns sorry

1 Like

figured it out

in a local script (parented to the gun tool):

local cas = game:GetService("ContextActionService")
local players = game:GetService("Players")
local fireRE = game:GetService("ReplicatedStorage"):WaitForChild("Fire")

local localPlayer = players.LocalPlayer
local mouse = localPlayer:GetMouse()

local gun = script.Parent

local function fire(action, inputState, inputObject)
	if action == "Fire" then
		if inputState == Enum.UserInputState.Begin then
			if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
				fireRE:FireServer(mouse.Hit.Position, gun)
			end
		end
	end
end

gun.Equipped:Connect(function()
	cas:BindAction("Fire", fire, false, Enum.UserInputType.MouseButton1)
end)
gun.Unequipped:Connect(function()
	cas:UnbindAction("Fire")
end)

in a server script:

local fireRE = game:GetService("ReplicatedStorage"):WaitForChild("Fire")

local bulletSpeed = 600
-- you can change this

local fireFunction

local function cast(mouseHitPos: Vector3, playerTool: Tool)
	local bullet = Instance.new("Part")
	bullet.Name = "bullet"
	bullet.CFrame = CFrame.new(playerTool.ShootPartStart.Position, mouseHitPos)
	bullet.CanCollide = false
	bullet.Anchored = true
	bullet.Parent = workspace
	
	fireFunction = game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
		bullet.CFrame *= CFrame.new(0, 0, -bulletSpeed * deltaTime)
		if (playerTool.ShootPartStart.Position - bullet.Position).Magnitude > 500 then
			bullet:Destroy()
		end
	end)
end

fireRE.OnServerEvent:Connect(function(player, mouseHitPos, playerTool)
	cast(mouseHitPos, playerTool)
end)

no idea about the performance honestly, but it works fine on my computer (which, mind you, is not very powerful)

there MUST be a remoteEvent named “Fire” in game.ReplicatedStorage

3 Likes