Help with grappling gun

So I’ve made this grapple gun on roblox, and im trying to make this grapple gun have a “smoother” pull on the player. Right now, the grapple gun just flings the player around while they’re in the air. Is there a way to make the player not get flinged.

This is how the gun currently looks:

This is how I want the gun to look:

This is my current script:

local RunService = game:GetService("RunService")
local players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local UIService = game:GetService("UserInputService")

local tool = script.Parent
local base = tool:WaitForChild("Base")
local spring = base.Spring
local hook = tool:WaitForChild("Hook")
local hWeld = hook.HookWeld
local ref = tool:WaitForChild("HookRef")
local messageEvent = script:WaitForChild("MessageEvent")
local activated = script:WaitForChild("Activated")

--client
local player = nil
local mouse = nil
local currentTween = nil

local Grapplegun = {}

local function toggleHumanoidGrappleState(active)
	local humanoid = player.Character and player.Character:FindFirstChild("Humanoid")
	
	if humanoid then
		
		if active then
			humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, false)
			humanoid:ChangeState(Enum.HumanoidStateType.Physics)
		else
			humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, true)
			humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
		end
		
	end
end

local function clientInit()
	player = players.LocalPlayer
	mouse = player:GetMouse()
	
	mouse.TargetFilter = player.Character
	
	tool.Activated:Connect(function()
		if not Grapplegun.IsActivated() and mouse.Target then
			messageEvent:FireServer(true, mouse.Hit.Position)
			toggleHumanoidGrappleState(true)
		end
	end)

	
	tool.Deactivated:Connect(function()
		messageEvent:FireServer(false)
		toggleHumanoidGrappleState(false)
	end)
	
	tool.Unequipped:Connect(function()
		messageEvent:FireServer(false)
		toggleHumanoidGrappleState(false)
	end)
	
	
end

local function serverInit()
	
	messageEvent.OnServerEvent:Connect(function(player, _activated, targetPosition)
		activated.Value = _activated
		
		if Grapplegun.IsActivated() then
			Grapplegun.Fire(targetPosition)
		else
			Grapplegun.Reset()
		end
		
	end)
	
end

local function init()
	if RunService:IsClient() then
		clientInit()
	elseif RunService:IsServer() then
		serverInit()
	end
end

function Grapplegun.IsActivated()
	return activated.Value
end

function Grapplegun.Fire(targetPosition)
	local initalPos = ref.Position
	
	local distance = (targetPosition - initalPos).Magnitude
	
	hWeld.Enabled = false
	hook.Anchored = true
	
	wait()
	
	hook.Position = targetPosition
	spring.FreeLength = distance
	
	local info = TweenInfo.new(distance/100, Enum.EasingStyle.Linear)
	local tween = TweenService:Create(spring, info, {FreeLength = 1})
	
	tween:Play()
	
	currentTween = tween
end

function Grapplegun.Reset()
	if currentTween then
		currentTween:Cancel()
	end
	
	hook.CFrame = ref.CFrame
	hWeld.Enabled= true
	hook.Anchored = false
	
	spring.FreeLength = 1
	
end

init()
return Grapplegun

Spring:
Screenshot 2024-03-10 215826

1 Like