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

I’m trying to make it so when you equip the weapon, your arms and head move up and down with the player’s mouse. I have it so the head moves up and down with your mouse, however I’m not really familiar with wielding, and I’m curious how I could wield the arms to the head.

Here is the script so far that moves the head up and down,

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()


game:GetService("RunService").RenderStepped:Connect(function() 
mouse.TargetFilter = workspace
player.Character.Torso.Neck.C1 = CFrame.new() 
player.Character.Torso.Neck.C0 = CFrame.new(0, 1.5, 0) * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0) 
end)

Thanks for the help! :smile:

25 Likes

To weld the head to the arms you would have to create a Instance.new(“Weld”). Then set C0 to the arm, the C1 to the head, and the Parent to either the head or the arm. Then you will just have to make sure that the arm is anchored and repeat for the second arm. Hope this helps!

This isn’t how welding works at all.

To weld an arm to the head, create a new Weld instance and set Part0 and Part1 of the weld accordingly; I would set Part0 to the head and Part1 to the arm, and parent the weld to the head. If you do this, you’ll notice that the arm is inside of the head. You can mess around with offsets, and set whatever offset you like to C0. One way that I use to find a good offset is to set up a dummy rig, put the arm wherever you would on the rig, then use the command line to print:

rigHead.CFrame:ToObjectSpace(rigArm.CFrame)

That will print what C0 would need to be.

Actually creating the weld would go something like this:

   local offset = CFrame.new()
   local Weld = Instance.new("Weld")
   Weld.Part0 = head
   Weld.Part1 = arm
   Weld.Parent = head
   Weld.C0 = offset

Alternatively, you could just use a WeldConstraint with Part0 and Part1 set as previously described and not have to worry about offsets.

My friend @CleverSource helped someone out with this exact same issue while back, here is a link to his thread with a detailed explanation.

6 Likes

I don’t recommend using Weld to connect between Tool and Character. Instead, use a Motor6D.
I also recommend using Torso or HumanoidRootPart instead of head, your tool will follow the Torso or HumanoidRootPart direction if you do that so.

After you created the Motor6D, bind it’sCFrame times the formula that you used for arms:
Torso.Motor6D.C0 = CFrame.new(0,0,0) * CFrame.Angles(math.asin((mouse.Hit.p - mouse.Origin.p).unit.y), 0, 0)

This is the result for me, even though I used a sightly different method.
https://gyazo.com/02247b996c69f9cb7d0c41bd9afccdcd

If you want a bit more in-depth explanation, check out my thread:

6 Likes

My method which Kensizo provided uses Motor6D’s that are already created by Roblox’s character controller system.

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.
https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/1/2/a/12a0762e27d54b6c02f001cdb190ea1595c73acf.mp4

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.

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

4 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

2 Likes

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

2 Likes

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)
1 Like

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)
1 Like

Alright, I’ve separated the two. Still not doing anything,
https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/2/a/8/2a8b3412eab8c5a49e0158df81fd336d446b9567.mp4
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.

1 Like

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