Stabilize a character in the Physics state and subtly rotate towards a target part

I have a script for a grappling hook which works fine for the most part. However, the character goes crazy as soon as they begin being dragged by the Spring (which acts as the rope between the gun and the hook) as they are in a Physics state. It would be nice if this didn’t happen. As for the second half of the title, I speculate this could be done with AlignOrientation, but I would like some guidance on how to implement this as I’m not too good with the forces in Roblox.

The main script for the grappling hook (a ModuleScript called by a LocalScript and server Script):

local runserv = game:GetService("RunService")
local players = game:GetService("Players")
local tweenserv = game:GetService("TweenService")

local tool = script.Parent
local base = tool:WaitForChild("base")
local spring = base.spring
local hook = tool:WaitForChild("hook")
local hookweld = hook.hookweld
local hookref = tool:WaitForChild("hookref")
local msg = script:WaitForChild("msg")
local active = script:WaitForChild("gamingrn")

--client only vars
local player = nil
local mouse = nil
local curtween = nil

local grapplegun = {}

local function togglegrapplestate(active)
	local humanoid = player.Character and player.Character:FindFirstChild("Humanoid")
	
	if humanoid then
		wait()
		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()
	--prevent player from hitting themself
	mouse.TargetFilter = player.Character
	
	tool.Activated:Connect(function()
		if not grapplegun.IsActivated() and mouse.Target then
			msg:FireServer(true, mouse.Hit.Position)
			togglegrapplestate(true)
		end
	end)
	tool.Deactivated:Connect(function()
		msg:FireServer(false)
		togglegrapplestate(false)
	end)
	tool.Unequipped:Connect(function()
		msg:FireServer(false)
		togglegrapplestate(false)
	end)
end

local function serverinit()
	msg.OnServerEvent:Connect(function(player, _activated, targetpos)
		active.Value = _activated
		
		if grapplegun.IsActivated() then
			grapplegun:Fire(targetpos)
		else
			grapplegun:Reset()
		end
	end)
end

local function init()
	if runserv:IsClient() then
		print("client")
		clientinit()
	elseif runserv:IsServer() then
		print("server")
		serverinit()
	end
end

function grapplegun.IsActivated()
	return active.Value
end

function grapplegun:Fire(targetpos)
	local initpos = hookref.Position
	--distance from gun 2 mouse
	local distance = (targetpos - initpos).Magnitude
	hookweld.Enabled = false
	hook.Anchored = true
	wait()
	local hookInfo = TweenInfo.new(distance/500, Enum.EasingStyle.Linear)
	local hookTween = tweenserv:Create(hook, hookInfo, {Position = targetpos})
	--hook.Position = targetpos
	hookTween:Play()
	curtween = hookTween
	hookTween.Completed:Connect(function()
		spring.FreeLength = distance
		
		local info = TweenInfo.new(distance/100, Enum.EasingStyle.Linear)
		local tween = tweenserv:Create(spring, info, {FreeLength = 1})
		tween:Play()
		curtween = tween
	end)
end

function grapplegun:Reset()
	if curtween then
		curtween:Cancel()
	end
	hook.CFrame = hookref.CFrame
	hookweld.Enabled = true
	hook.Anchored = false
	spring.FreeLength = 1
end

init()
return grapplegun
1 Like

Help would be appreciated.­­­­­­­­­­­

Here’s what I mean by “going crazy” if it helps anyone:

https://i.imgur.com/jAidflF.gif

guess i’m on my own, i’ll post my solution here if i ever figure it out

tool.Activated:Connect(function()
		if not grapplegun.IsActivated() and mouse.Target then
			msg:FireServer(true, mouse.Hit.Position)
			togglegrapplestate(true)
			--handle rotation
  			local root = humanoid.Parent.HumanoidRootPart
			local rotator = hook.AlignOrientation
			local humattach = root.RootAttachment
			local hookattach = hook.Attachment1
			rotator.Attachment0 = humattach
			rotator.Attachment1 = hookattach
		end
	end)
1 Like