How could I make your arms and head follow your mouse up and down?

Alright, I just got no errors in the output, So I will connect Part 1 to the tools handle on the client or on the server?
This is what I ended up doing in the Client, its not working currently.

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local tool = script.Parent
local Character = player.Character or player.CharacterAdded:Wait()
local Torso = Character:WaitForChild("HumanoidRootPart")
tool.Equipped:Connect(function()
	game.ReplicatedStorage.MoveArms:FireServer()
	Torso.Motor6D.C0 = Torso.Motor6D.C0 * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)
	Torso.Motor6D.C1 = tool.Handle.C1 * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)
end)
1 Like

Use a local script

local RunService = game:GetService("RunService")

local Player = game.Players.LocalPlayer
local PlayerMouse = Player:GetMouse()

local Camera = workspace.CurrentCamera

local Character = Player.Character or Player.CharacterAdded:Wait()
local Head = Character:WaitForChild("Head")
local Neck = Head:WaitForChild("Neck")

local Torso = Character:WaitForChild("UpperTorso")
local Waist = Torso:WaitForChild("Waist")

local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")

local NeckOriginC0 = Neck.C0
local WaistOriginC0 = Waist.C0

Neck.MaxVelocity = 1/3

RunService.RenderStepped:Connect(function() 
	local CameraCFrame = Camera.CoordinateFrame
	
	if Character:FindFirstChild("UpperTorso") and Character:FindFirstChild("Head") then
		local TorsoLookVector = Torso.CFrame.lookVector
		local HeadPosition = Head.CFrame.p
		
		if Neck and Waist then
			if Camera.CameraSubject:IsDescendantOf(Character) or Camera.CameraSubject:IsDescendantOf(Player) then
				local Point = PlayerMouse.Hit.p
				
				local Distance = (Head.CFrame.p - Point).magnitude
				local Difference = Head.CFrame.Y - Point.Y
				
				Neck.C0 = Neck.C0:lerp(NeckOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 0.5), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 1, 0), 0.5 / 2)
				Waist.C0 = Waist.C0:lerp(WaistOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 0.5), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 0.5, 0), 0.5 / 2)
			end
		end
	end	
end)

Visit this post please,

and the link to the rbxl file
https://devforum.roblox.com/uploads/short-url/kzyFMHM8KlY3f64upU6t4bnE6Wf.rbxl
You can set when script.enabled=false or when tool is not activated

5 Likes

I don’t know the answer, but this might help: if your arm moves too much, maybe add a max arm up and down

You should put character.Torso.Motor6D as an argument such that the server side code can reference it and connect Part1 to the tool. Also, you don’t have to modify C1.

I’ve tried a script like this before. But the game is R6. I might mess around and see if I can make it work with R6, but I’m not sure

1 Like

I found the solution a while back here, but how would you make it appear on all clients and not just yours?

1 Like

Alright, So I made it a variable, and in the server I have this script.

game.Players.PlayerAdded:Connect(function(player)
	local Character = player.Character or player.CharacterAdded:Wait()
	local Torso = Character:WaitForChild("HumanoidRootPart")
	local tool = script.Parent
game.ReplicatedStorage.MoveArms.OnServerEvent:Connect(function(plr, Motor)
	local Motor6D = Instance.new("Motor6D")
	Motor6D.Parent = Torso
	Motor.Part1 = tool.Handle
	end)
end)

along with the client

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local tool = script.Parent
local Character = player.Character or player.CharacterAdded:Wait()
local Torso = Character:WaitForChild("HumanoidRootPart")
local Motor = Torso:WaitForChild("Motor6D")
tool.Equipped:Connect(function()
	game.ReplicatedStorage.MoveArms:FireServer(Motor)
	Torso.Motor6D.C0 = Torso.Motor6D.C0 * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)
end)

Seperate these 2 functions. It’s the best to initiailze the Motor6D when the character loads, instead of upon equip.
Also, use CharacterAdded with player.

   game.Players.PlayerAdded:Connect(function(player)
    player.CharacterAdded:Connect(functoin(character)
    	local Torso = Character:WaitForChild("HumanoidRootPart")
    	local tool = script.Parent

    	local Motor6D = Instance.new("Motor6D", Torso)
    	Motor6D.Part0 = Torso
    end)
    end)

    game.ReplicatedStorage.MoveArms.OnServerEvent:Connect(function(plr, Motor, ToolHandle)
          Motor.Part1 = ToolHandle
    end)



tool.Equipped:Connect(function()
	game.ReplicatedStorage.MoveArms:FireServer(Motor, Tool.Handle)
	Torso.Motor6D.C0 = Torso.Motor6D.C0 * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)
-- Also with your arms code
end)

Alright, I’ve separated the two. Still not doing anything,


Client:

local player = game.Players.LocalPlayer
player.CharacterAdded:Connect(function(Character)
local mouse = player:GetMouse()
local tool = script.Parent
local Torso = Character:WaitForChild("HumanoidRootPart")
local Motor = Torso.Motor6D
tool.Equipped:Connect(function()
	game.ReplicatedStorage.MoveArms:FireServer(Motor, tool.Handle)
	Torso.Motor6D.C0 = Torso.Motor6D.C0 * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)
end)
end)

Server:

 game.Players.PlayerAdded:Connect(function(player)
 player.CharacterAdded:Connect(function(Character)
  local Torso = Character:WaitForChild("HumanoidRootPart")
  local tool = script.Parent
  local Motor6D = Instance.new("Motor6D", Torso)
    	Motor6D.Part0 = Torso
    end)
    end)
  game.ReplicatedStorage.MoveArms.OnServerEvent:Connect(function(plr, Motor, ToolHandle)
          Motor.Part1 = ToolHandle
  end)

Sorry for asking so much. I just seem I can’t get this to work.

You did not bind RunService.RenderStepped to the Moving Arms function.

1 Like

How you be holding with 2 hands

4 Likes

Hello im making something similar and i modified the Headstackk formula to make it work for the tool Handle.
I move arms only locally, so heres the “Move arms” piece of my local script:

run.RenderStepped:Connect(function()
	if equipped then
		Torso.Motor6D.C0 = CFrame.new(0, 0, 0) * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)
	end
end)

For “Torso.Motor6D” i mean the motor6D of the tool handle, you can create it in server just typing:

local motor = Instance.new("Motor6D")
motor.Part0 = character.Torso
motor.Part1 = tool.Handle
motor.Parent = character.Torso

This formula works for my tool’s motor6D, but it needs to be modified to make it work for shoulders, and unluckily i dont know how to do that. So, can someone try to modify it? It will be very helpful!
Thanks in advance. :grinning:

1 Like

This is the video of the formula:

Im also following the Headstackk guide to animate with tools:

Thats very helpful, so thanks @Headstackk.

1 Like

Hello again guys, i finaly found a good way to close this topic!
I modified the formula, and now it works nicely for arms, but it doesnt for the tool, so i decided to modify the motor6D of the toolHandle, so that the Part0 is now the RightArm.
Now, with this new motor6D, your tool will be attached at your arm, that follows the mouse, so, arms, and tool follow the mouse now!
This is a pretty easy way to animate too! You will not find yourself in difficulty with animating, trust me!

So, how did i modify the formula?
I saw that with the normal formula, the arm turned for itself, and it was because, the formula added in loop the angle that was needed for the arm to turn towards the mouse:

Torso["Right Shoulder"].C0 = Torso["Right Shoulder"].C0 * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)

therefore it can be understood that by always adding the same angle, the arm turns on itself. So I had an idea, first of all i got the angles of “Torso[“Right Shoulder”].C0” just by doing “local rightX, rightY, rightZ = self.char.Torso[“Right Shoulder”].C0:ToEulerAnglesYXZ()”, then i took this: “Torso[“Right Shoulder”].C0” and i substracted the negative Z angle that i took from the :ToEulerAnglesYXZ() function.
Then i put this micro formula in brackets, and i added the new angles of the mouse.
Sorry, im not very good for explaining, specialy in english, so i will give you the finished formula:

run.RenderStepped:Connect(function()
	if equipped then
		local rightX, rightY, rightZ = self.char.Torso["Right Shoulder"].C0:ToEulerAnglesYXZ()
		self.char.Torso["Right Shoulder"].C0 = (self.char.Torso["Right Shoulder"].C0 * CFrame.Angles(0, 0, -rightZ)) * CFrame.Angles(0, 0, math.asin((self.mouse.Hit.p - self.mouse.Origin.p).unit.y))
		
		local leftX, leftY, leftZ = self.char.Torso["Left Shoulder"].C0:ToEulerAnglesYXZ()
		self.char.Torso["Left Shoulder"].C0 = (self.char.Torso["Left Shoulder"].C0 * CFrame.Angles(0, 0, -leftZ)) * CFrame.Angles(0, 0, math.asin((-self.mouse.Hit.p - -self.mouse.Origin.p).unit.y))
	end
end)

Here’s a video of how it should work:

I hope this was helpful for you guys! :grinning:

EDIT:
After 3 years, i wanted to thank you all for supporting this reply so much! I wrote this when i didn’t have much experience, and once i found the working formula, i just posted it here. So before just taking for granted, check out the problem yourself and try to find a better way to do it, just take this as a start.
Unfortunately, i won’t be answering anything anymore since i stopped being an active developer on roblox. Thanks again!

75 Likes

Sorry to bother everyone I don’t mean to revive this thread how ever I have done everything exactly as you have in the tutorial and I used your formula for arms and used render stepped and binded the Motor6D to the torso however I get this…

https://gyazo.com/9cfc52e8076efcaaa043068f8c86315b

The only way I can fix this is by binding the motor6D to the right arm and deleting the formula for the gun up/down however I now can’t animate the right arm independent of the gun which is what I wanted :confused:

Sorry, I think the formula up there is wrong, it should be:
Torso.Motor6D.C0 = CFrame.new(0,0,0) * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)

1 Like

Ah yes it does indeed work however the gun moves forward/backwards along the arms when pointing up and down as you can see below.

https://gyazo.com/cef885a35e855f8c0a9d2dae1e0216c9

I am not sure how I would make it stay static and not move forwards/backwards along the players arms while moving up/down. Ill think I might just have to stick to welding it to the right arm as it looks more realistic.

My bad again, it should be Right Shoulder c0 * CFangles (0, math.pi/2) * offset, try to get the offset by yourself atm, I’m on mobile and I can’t get the code here right now. If this doesn’t work I’ll copy the code from my PC to here soon.

2 Likes
local rightX, rightY, rightZ = player.Character.Torso["Right Shoulder"].C0:ToEulerAnglesYXZ()
player.Character.Torso.ToolGrip.C0 = player.Character.Torso["Right Shoulder"].c0 * CFrame.Angles(0, 0, rightZ) * CFrame.Angles(0, 0, math.asin((-mouse.Hit.p - -mouse.Origin.p).unit.y))

https://gyazo.com/42eeb128b511f4e8997f00204cc96748

I tried this not sure if exactly the right way you said to do it but it works!!! Except it’s offset the gun towards the left arm and rotated it upside down so I had to rotate the handle in the model to get it to be right way up.

Here’s mine:
char.Torso.ToolGrip.C0 = char.Torso["Right Shoulder"].C0 * CFrame.fromEulerAnglesXYZ(0, math.pi/-2,0) * CFrame.new(-1,-0.5,0)
Alternatively:
char.Torso.ToolGrip.C0 = CFnew(ViewModel.Torso["Right Shoulder"].C0.Position) * CFnew(-1,-0.5,0)

13 Likes