Make spear tween to mouse position?

I am attempting to make a spear tween to the mouse position, like this:
https://gyazo.com/15b9ddb5a42da407627aede959fe8546

But I am not sure how I am able to do this with Ray and TweenService with Mouse.

Here is what happens to me:

ServerScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")

local spearEvent = ReplicatedStorage:WaitForChild('SpearEvent')
local mouseMoveEvent = ReplicatedStorage:WaitForChild('MouseMoveEvent')
local iceSpear = ReplicatedStorage:WaitForChild('IceSpear')

local maxDistance = 50
local goal = {}
local tweenInfo = TweenInfo.new(0.25)

local damage = 50

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local spearFolder = Instance.new("Folder", character)
		spearFolder.Name = 'SpearFolder'
	end)
end)

local function repeatSpears(player, mouseP)
	for i = 1, 4, 1 do
		local character = player.Character
		local cloned = iceSpear:Clone()
		local based = cloned.Inv
		cloned.Parent = player.Character.SpearFolder
		cloned.Name = "IceSpear"..i
		cloned:SetPrimaryPartCFrame(CFrame.new(character.Head.Position + Vector3.new(math.random(-2, 2), math.random(1, 4), math.random(-2, 2)), mouseP) 
		* CFrame.Angles(math.rad(0), math.rad(-90), 0))
	end
	wait(1)
end

local function spearCreate(player, mouseP, distance, origin, mouseHit)
	repeatSpears(player, mouseP)
	
	local spearRay = Ray.new(origin, (mouseP - origin).Unit * maxDistance)
	local hit, position = game.Workspace:FindPartOnRayWithIgnoreList(spearRay, {player.Character})
	local distance = (origin - mouseP).magnitude
	
	for i, v in pairs(player.Character.SpearFolder:GetChildren()) do
		if distance < maxDistance and hit and hit.Parent:FindFirstChild('Humanoid') then
			hit.Parent.Humanoid:TakeDamage(15)
		end
		
		goal.CFrame = v.Inv.CFrame * CFrame.new(-mouseHit.Position)
		local tween1 = TweenService:Create(v.Inv, tweenInfo, goal)
		tween1:Play()
		tween1.Completed:Wait()
		Debris:AddItem(v, 2.5)
		
	end
end

spearEvent.OnServerEvent:Connect(function(player, origin, mousePos, mouseHit)
	local spearRay = Ray.new(origin, (mousePos - origin).Unit * maxDistance)
	local hit, position = game.Workspace:FindPartOnRayWithIgnoreList(spearRay, {player.Character})
	local distance = (origin - mousePos).magnitude
	
	if distance < maxDistance and hit then
		spearCreate(player, mousePos, distance, origin, mouseHit)
	end 
end)
LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local spearEvent = ReplicatedStorage:WaitForChild('SpearEvent')
local mouseMoveEvent = ReplicatedStorage:WaitForChild('MouseMoveEvent') 
local tool = script.Parent
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:wait()
local mouse = player:GetMouse()
local used = false
local cooldown = 2.5 -- time between each shot

tool.Activated:Connect(function()
	if not used then
		used = true
		local origin = character:WaitForChild('Head').Position
		spearEvent:FireServer(origin, mouse.Hit.Position, mouse.Hit)
		wait(cooldown)
		used = false
	end
end)
1 Like

If you’re ok with the spear going super fast (essentially making it unblockable/undodgeable)
you could do something like

OffsetCFrame = CFrame.Angles(0,math.rad(180),0) -- Play around with this
-- set the CFrame to the mousePos, make it face the original spear position, then rotate it 180 degrees
spear.CFrame = CFrame.new(mousePos,spear.Position)*OffsetCFrame

Making ranged weapons with proper projectiles can get a little tricky.
There are modules for this

If you wanna have a go at doing it yourself, I wouldn’t recommend using tweens. It’ll be more accurate if you just teleported the bullet each step of the way.

You’re basically taking the original raycast
image

and splitting it into sections
image
The bullet checks what’s immediatly infront of it
image

If there’s nothing there, it teleports (not tweens) to however far the raycast is and repeats the step
image

If something jumps in the way, or is in the way
image

The bullet teleports to where the ray intersected
image

If you tweened it then bullets might appear to go through things, depending on how slow the tween is.

I made my own module called Easy Bullet that’s a little easier to use than FastCast, but I haven’t released it to the public yet.
I could give it to you if you want.

2 Likes

Interesting, how would I split the sections?

And would it look smooth if I split it into sections?

I just saw your edit, so I should just spawn it in, and use CFrame to move it, but use ray to detect damage?

Well, I guess you’re not actually splitting it as much as you’re taking it a step at a time.
Yea, that’s basically what you do.

I forgot to mention another layer of complexity: Collisions
If the raycast hits something with CanCollide set to false then you have to repeat that same raycast but add the thing to an ignore list. Otherwise, there’ll be a bug where the bullet goes through nonsolid objects and then through solid objects.