Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Character and arms following player's mouse?

local tool = script.Parent.Parent
local service = game:GetService("RunService") --get  run time servise

local success = false

local player = game:GetService("Players").LocalPlayer --get the current player
local character = player.Character or player.CharacterAdded:wait() --get character
local humanoid = character:WaitForChild("Humanoid") --get humanoid

local camera = game.Workspace.CurrentCamera --player camera
local mouse = player:GetMouse() --player mouse

local offset, magnitude, vector3, cFrame, direcction = nil --varibles to make calculations
local shoulder, arm, torso, body, neck = nil --variables to hold body parts
local defaultNeckCO, defaultShoulderCO = nil --variables to hold the defauld posicion of the body parts
local animate = nil --variable to hold the function of the animation

local shoulderPositionC0, shoulderCFramePositionC1 = nil --variables to extrack some data from the body parts
local turnAngle = CFrame.fromEulerAnglesXYZ(math.pi/2, 0, 0) --constant, used later on to make calculations
local rightangle = CFrame.fromEulerAnglesXYZ(0, 0, math.pi) --constant, used later on to make calculations

local unequipListener --listener to disconect the unequip function

--get offset
function updateOffset()
	offset = (body.Position.y - mouse.Hit.p.y) / 100
	magnitude = (body.Position - mouse.Hit.p).magnitude / 80
	return offset/magnitude
end

--get vector3 of direccion
function updateBodyRotation()
	
	if (camera.Focus.p - camera.CoordinateFrame.p).magnitude > 1 then
		--stop the defauld rotation
		humanoid.AutoRotate = false
		
		--get the rotation vector3
		vector3 = Vector3.new(mouse.Hit.p.x, body.Position.y, mouse.Hit.p.z)
		
		--create the cframe with the same posicion of the body and the new rotation
		cFrame = CFrame.new(body.Position, vector3)
		
		--updating the body rotation
		body.CFrame = cFrame
	else
		--get the defauld rotation
		humanoid.AutoRotate = true
	end
	
end

--function to animate the humanoid R15
function animateR15()
	--update neck
	offset = updateOffset()
	neck.C0 = defaultNeckCO * CFrame.fromEulerAnglesXYZ(-offset, 0, 0)
	
	--update arm
	vector3 = (torso.CFrame * CFrame.new(shoulderPositionC0)).p + Vector3.new(0, -0.25,0) --offset position
	direcction = (vector3 - mouse.Hit.p).unit 
	arm.CFrame = CFrame.new(vector3, vector3 + direcction) * turnAngle * shoulderCFramePositionC1 * rightangle 
	
	--NOTE: the following changes update the arm in a lesser accurate way, but it's faster,
	--to change the faster way, must comments the previous update arm (previus 3 code lines),
	--and add the following code line in the "getBodyParts()" in the R15 side
	--defaultShoulderCO  = CFrame.new(1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)
	--then uncomment the following code line
	--shoulder.C0 = defaultShoulderCO * CFrame.fromEulerAnglesXYZ(-offset, 0, 0)
	--at last, the shoulder.C0 take some changes in the animation,
	--the defauld posicion have to by reset in defauld on "stopAllFunctions()", with the following code line:
	--shoulder.C0 = defaultShoulderCO
end

--function to animate the humanoid R6
function animateR6()
	--getting the offset
	offset = updateOffset()
	
	--update neck and arm, NOTE: this is almost the only variation between R6 nd R15,
	--and basically it's where is going to be the offset
	neck.C0 = defaultNeckCO * CFrame.fromEulerAnglesXYZ(offset, 0, 0)
	shoulder.C0 = defaultShoulderCO * CFrame.fromEulerAnglesXYZ(0, 0, -offset)
end

--function to get parts of the body depending on the humanoid
function getBodyParts()
	
	--same body in both humanoids types
	body = character.HumanoidRootPart
	
	--bifurcate between diferents humanoids to get part of the body
	if humanoid.RigType == Enum.HumanoidRigType.R15 then
		--R15
		
		--getting body parts
		shoulder = character.RightUpperArm.RightShoulder
		arm = character.RightUpperArm
		neck = character.Head.Neck
		torso = character.UpperTorso
		
		--deatach the arm
		arm.Anchored = true
		shoulder.Part1 = nil
		
		--setting animation
		animate = animateR15
		
		--Note: those CFrame are the defauld position of each motor6d
		defaultNeckCO = CFrame.new(0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)
		shoulderCFramePositionC1 = CFrame.new(shoulder.C1.p)
		shoulderPositionC0 = shoulder.C0.p
	else
		--R6
		
		--getting body parts
		shoulder = character.Torso["Right Shoulder"]
		arm = character["Right Arm"] 
		neck = character.Torso.Neck
		
		--setting animation
		animate = animateR6
		
		--Note: those CFrame are the defauld position of each motor6d
		defaultNeckCO = CFrame.new(0, 1, 0, -1, -0, -0, 0, 0, 1, 0, 1, 0)
		defaultShoulderCO = CFrame.new(1, 0.5, 0, 0, 0, 1, 0, 1, 0, -1, -0, -0)
	end

end


--this function try to stop all function of this script and set defauld values
function stopAllFunctions()
	
	pcall(function()
		--disconect the unequip tool listener
		unequipListener:Disconnect()
	end)
	
	pcall(function()
		--stop the rendering of the animation
		service:UnbindFromRenderStep(script.Name)
	end)
		
	pcall(function()
		--reset defauld position of the neck 
		neck.C0 = defaultNeckCO
	end)
		
	pcall(function()
		--reset the defauld rotation of the body
		humanoid.AutoRotate = true
	end)
	
	pcall(function ()
		if humanoid.RigType == Enum.HumanoidRigType.R15 then
			--R15 
			--atach the arm
			shoulder.Part1 = arm
			arm.Anchored = false
		else
			--R6
			--reset defauld position of the arm 
			shoulder.C0 = defaultShoulderCO
		end
	end)

end

--function to animate the character
function characterFollowTool()

	--try to render the animation
	success = pcall(function()
		--update the Bogy rotation and offset
		updateBodyRotation()
		
		--execute the animation, this function it's diferent depending of the humanoid type
		animate()
	end)
	
	--if the rendering went wrong, 
	if not success then
		stopAllFunctions()
	end
	
end

function onEquip()
	--add listener to the tool to stop all functions when the tool is unequipped  
	unequipListener = tool.Unequipped:connect(stopAllFunctions)

	--getting the parts of the current character
	success = pcall(getBodyParts)
	if not success then
		stopAllFunctions()
	end
	
	--adding the animation in the rendering of the screen
	service:BindToRenderStep(script.Name, Enum.RenderPriority.Input.Value - 1, characterFollowTool)
end

tool.Equipped:connect(onEquip)

There a script i found in toolbox. I dont know how to make the same movement but with left arm. This script only moves head, torso and right arm.

1 answer

✓ Accepted answer

you don't need to move body parts one by one, that is wrong. Instead, all you need to do is pointing your HumanoidRootPart CFrame to your mouse direction

Character.PrimaryPart.CFrame = CFrame.new(Character.PrimaryPart.Position, mouse.Hit.P)

This discussion is preserved as it was. New answers, comments, and votes are closed.