How can I calculate the rotation for this?

Gah, I would love to get my teeth into this. There’s a simpler solution to this, I know there is, but I just don’t have the free time these days to tinker with code like I used to :sad:

1 Like

I don’t think this would work. And if I do use this, where do I put it and what do I remove? Did you look my code? because this was instant.

You haven´t tried it out yet. Just send me your code, I’ll fix it.

It’s in the file. WAKKAWAKKAWignore

Please explain where I would put the line of code and what to remove from my original script. The local script is located in starterplayerscripts.

wtf, no solution yet?

You might want to try this

local Part = Instance.new("Part")
Part.Anchored = true
Part.Parent = workspace

local Camera = workspace.CurrentCamera

local RelativeCF = Camera.CFrame:ToObjectSpace(Part.CFrame)

while true do
	task.wait()
	Part.CFrame = Camera.CFrame * RelativeCF
end

1 Like

Would this work for 3rd person?

Sure but you would have to make it relative to character’s root part instead of camera

Do I do the same thing with the players head?

Not head, Character.HumanoidRootPart, because the head animates by default so the part would follow your characters head animation movements. The root doesnt change position when animating

Oh ok I forgot animations do that

How can I get the head position from the rootpart?

Head.Position - RootPart.Position

That gives a vector from the last one pointed to the first one, keeping the magnitude between them also.
But what do you want it for? If you want the whole CFrame of one relative to another, it would be

Root.CFrame:ToObjectSpace(Head.CFrame)

I want it so it uses the head position so both first person and 3rd person would look good. if it rotate around the humanoid root part, it would seem a little offset.

Ah ok, so you can get the distance between root and head at first and add it above the root

local Part = Instance.new("Part")
Part.Anchored = true
Part.Parent = workspace

local Camera = workspace.CurrentCamera

local RelativeCF = Camera.CFrame:ToObjectSpace(Part.CFrame)
local Offset = Head.Position - HumanoidRootPart.Position -- get these from whatever your context is

while true do
	task.wait()
	Part.CFrame = (Camera.CFrame * RelativeCF) + Offset
end

Note that im adding a constant offset direction here, its assuming your character will aways be grabbing something while in a straight position, so if your character is rotated like upside down, like its falling down or ragdolled or animated to a bruscally different pose, the grabbed part wont follow that rotation. If you want it to follow that, it you should use " * Offset" instead of " + Offset"

How do I implement this into my code?

Important changes:

  • At the begining of runtime, save the offset between rootpart and head:
local Offset = character.Head.Position - character.HumanoidRootPart.Position
  • By the time you first grab the object, save the relative object’s CFrame from the root + offset:
RelativeCF = CFrame.lookAlong(character.HumanoidRootPart.Position + Offset, Camera.CFrame.LookVector):ToObjectSpace(grabbedPart.CFrame)
  • Inside the grabbing loop, get the cam to mouse vector, build a cframe positioned at the root + offset and oriented to the “cam to mouse vector”; then multiply this cframe to your relative cframe taken from the grabbed part at the beginning, this multiplying operation act like a sum operation but for cframes, and same as CFrame:ToWorldSpace(CFrame):
local CamToMouseVector = (Mouse.Hit.Position - Camera.CFrame.Position)
mousePosPart.CFrame = CFrame.lookAlong(character.HumanoidRootPart.Position + Offset, CamToMouseVector) * RelativeCF

TestPlace.rbxl (63,0,KB)

Code

local userInputService = game:GetService("UserInputService")
local _workspace = game:GetService("Workspace")

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()

local camera = _workspace.CurrentCamera

local Offset = character.Head.Position - character.HumanoidRootPart.Position
local relativeCF

local grabbedPart

local dragMaxRange = 8
local dragMinRange = 4

local dragFeetRange = 2

local mousePosPart = script.MousePos

--Grabbed
userInputService.InputBegan:Connect(function(input, processed)
	if(not processed) then
		if(input.UserInputType == Enum.UserInputType.MouseButton1) then
			local mousePart = player:GetMouse().Target
			local mouseHit = player:GetMouse().Hit
			if(mousePart) then
				if(mousePart:FindFirstChild("GrabId")) then
					if((mouseHit.Position - character.Head.Position).Magnitude < dragMaxRange) then
						if(mousePart.GrabId.Value == 0) then
							grabbedPart = mousePart
							mousePosPart.Rotation = grabbedPart.Rotation
							relativeCF = CFrame.lookAlong(character.HumanoidRootPart.Position + Offset, camera.CFrame.LookVector):ToObjectSpace(grabbedPart.CFrame)
							game.ReplicatedStorage.RemoteEvents.Grab:FireServer(mousePart.GrabId, false)
							local newAttachment = Instance.new("Attachment")
							newAttachment.Name = "DragClickPoint"
							newAttachment.Parent = grabbedPart
							newAttachment.WorldPosition = mouseHit.Position
						end
					end
				end
			end
		end
	end
end)

--Stopped grab
local function Drop()
	game.ReplicatedStorage.RemoteEvents.Grab:FireServer(grabbedPart.GrabId ,0)
	if(grabbedPart:FindFirstChild("DragClickPoint")) then
		grabbedPart.DragClickPoint:Destroy()
	end
	mousePosPart.Parent = script
	player:GetMouse().TargetFilter = nil
	local alignPosition = mousePosPart.AlignPosition
	local alignOrientation = mousePosPart.AlignOrientation
	alignPosition.Attachment0 = nil
	alignOrientation.Attachment0 = nil
	alignPosition.Attachment1 = nil
	alignOrientation.Attachment1 = nil
	grabbedPart = nil
end

userInputService.InputEnded:Connect(function(input, processed)
	if(not processed) then
		if(input.UserInputType == Enum.UserInputType.MouseButton1) then
			if(grabbedPart) then
				if(grabbedPart.GrabId.Value ~= 0) then
					Drop()
				end
			end
		end
	end
end)

--Grabbing
while task.wait() do
	if(grabbedPart) then
		if(grabbedPart.GrabId.Value ~= 0) then
			player:GetMouse().TargetFilter = grabbedPart
			local newMousePos = player:GetMouse().Hit
			local direction = (newMousePos.Position - character.HumanoidRootPart.Position).unit
			if((newMousePos.Position - character.HumanoidRootPart.Position).Magnitude <= dragMaxRange) then
				mousePosPart.Position = newMousePos.Position
			else
				mousePosPart.Position = character.HumanoidRootPart.Position + direction * Vector3.new(dragMaxRange,dragMaxRange,dragMaxRange)
			end
			mousePosPart.Parent = workspace
			local camToMouseVector = (newMousePos.Position - camera.CFrame.Position)
			mousePosPart.CFrame = CFrame.lookAlong(character.HumanoidRootPart.Position + Offset, camToMouseVector) * relativeCF
			local alignPosition = mousePosPart.AlignPosition
			local alignOrientation = mousePosPart.AlignOrientation
			alignPosition.Attachment0 = grabbedPart:WaitForChild("DragClickPoint")
			alignOrientation.Attachment0 = grabbedPart.DragClickPoint
			alignPosition.Attachment1 = mousePosPart.Attachment
			alignOrientation.Attachment1 = mousePosPart.Attachment
			if((grabbedPart.DragClickPoint.WorldPosition - character.Head.Position).Magnitude > dragMaxRange + 3) then
				Drop()
			end
			if(grabbedPart) then
				local flyglitch = grabbedPart.Touched:Connect(function(foot)
					if(grabbedPart) then
						if(foot.Name == "RightFoot" or foot.Name == "LeftFoot" or foot.Name == "RightLeg" or foot.Name == "LeftLeg" or foot.Name == "LeftUpperLeg" or foot.Name == "RightUpperLeg") then
							Drop()
						end
					end
				end)
			end
		end
	end
end

Problem


It offsets on grab.

So you basically want it to behave one way on first person and another on third person view. Ure gonna have to add events to know that change and start to recalculate propperly. Feels like ure asking too much though. You just need to understand better how CFrame works so you will be able to accomplish it. We wont be coding your whole grabbing system for you

I thought itd be more simpler :confused: