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

I know I did it probably wrong. But this is the code I made using your method. Can you explain to me what’s wrong with it as I’m not quite sure.

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local player = game.Players.LocalPlayer	 	
repeat wait() until player.Character	 	
local Torso = player.Character.Torso
local Moter6D = Instance.new("Motor6D")
Moter6D.Parent = Torso
Torso.Motor6D.C0 = Torso.Motor6D.C0 * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)

I’m just trying to get this part of the script to work. I’m new to scripting if you already couldn’t tell :smile:

Edit, I found a game that has exactly the mechanics I’m trying to create.

2 Likes

Do this on server side if you want the gun to be visible to other players. Whenever the character loads (Can be achieved by player.CharacterAdded), add a Motor6D and set it’s Part0 to Torso/HumanoidRootPart initially. When the tool is being equipped, you have to connect it’s Part1 to the Tool’s Handle on server such that its’ visible to other players. You can also connect it on client and server at the same time such that the visible delay on client is eliminated.

Currently, the Roblox legacy tool uses a weld called Right Grip, where it welds between your Right Arm and the tool’s handle only upon equip. So remember to remove the RightGrip located inside the Right Arm upon equipping the tool.

1 Like

Alright, So I made it into a server script, and It still isn’t working. I’m doing something wrong here.

game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local mouse = player:GetMouse() 	 	
local Torso = character:WaitForChild("HumanoidRootPart")
local Moter6D = Instance.new("Motor6D")
Moter6D.Parent = Torso
Torso.Motor6D.C0 = Torso.Motor6D.C0 * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)print("Hello world!")
	end)
end)

I would put this into the tool, then make C1 to the tool’s handle?

2 Likes

You did it right on creating the Motor6D, however you don’t do the Follow Mouse on server. Now go to your Tool’s script and connect the Motor upon equipping the tool on client. Use a RemoteEvent to connect it on server.

The initial script on your first thread should be located inside a tool’s local script. Server only do the job on creating Motor6D and connecting Motor6D Part1, client should done the job of follow arms.

1 Like

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