How to make arm follow mouse

After I heard your cries of help, I will try to show you my mediocre script.

RS.Heartbeat:Connect(function()
	if Character and Character:FindFirstChild(Tool.Name) and Character:FindFirstChild("Torso") then
		local RightShoulder,= Character.Torso:WaitForChild("Right Shoulder")
		local X = -(math.asin((Mouse.Origin.p - Mouse.Hit.p).unit.y))
		local _, Y, Z = RightShoulder.C0:ToEulerAnglesXYZ()
		RightShoulder.C0 = CFrame.new(RightShoulder.C0.Position) * CFrame.Angles(X, Y, Z)
	end
end)

RS = RunService, Character = the players character and Mouse is the Player:GetMouse()

Also this only works up and down, in R6 only. I belive you must find another Joint rather than “Right Shoulder”

4 Likes

Hello,
I tested out your script and it does not work.
The arm disappears

Are you sure you are using R6 and an Tool? I forgot that the Tool variable should be the Tool the players needs to be equiped so the arm will follow the mouse. Deleting and Character:FindFirstChild(Tool.Name) will make it so no Tool is needed.

1 Like

Hello,
I don’t want to use a tool for it yet, I just want it to work whenever for now before I empliment any activationl ogic. One thing to keep out on is that I want it to be togglable so when it turns off the arm returns back to normal and doesn’t break or stay in the same place

RS.Heartbeat:Connect(function()
	if Character and Character:FindFirstChild("Torso") and Activated then
		local RightShoulder,= Character.Torso:WaitForChild("Right Shoulder")
		local X = -(math.asin((Mouse.Origin.p - Mouse.Hit.p).unit.y))
		local _, Y, Z = RightShoulder.C0:ToEulerAnglesXYZ()
		RightShoulder.C0 = CFrame.new(RightShoulder.C0.Position) * CFrame.Angles(X, Y, Z)
	end
end)

And when you deactivate it should be something like this:

--Some event or anything 
local RightShoulder = Character.Torso:WaitForChild("Right Shoulder")
RightShoulder.C0 = CFrame.new(1, 0.5, 0, 0, 0, 1, 0, 1, -0, -1, 0, 0)

This is how it looks like in a gun (When the gun goes up and down, I’m unable to do the other 2 Axis):

robloxapp-20210124-2318367.wmv (3.2 MB)

2 Likes

Hello,
I tested your script and it does not work.

wait(2)
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local plr = Players.LocalPlayer
local char = plr.Character
local mouse = plr:GetMouse()
mouse.TargetFilter = workspace
local armOffset = char.Torso.CFrame:Inverse() * char["Right Arm"].CFrame

local armWeld = Instance.new("Weld")
armWeld.Part0 = char.Torso
armWeld.Part1 = char["Right Arm"]
armWeld.Parent = char
local lastmou
game:GetService("RunService").Heartbeat:Connect(function()
	if char and char:FindFirstChild("Torso") then
		local RightShoulder = char.Torso:WaitForChild("Right Shoulder")
		local X = -(math.asin((mouse.Origin.p - mouse.Hit.p).unit.y))
		local _, Y, Z = RightShoulder.C0:ToEulerAnglesXYZ()
		RightShoulder.C0 = CFrame.new(RightShoulder.C0.Position) * CFrame.Angles(X, Y, Z)
	end
end)


My arm goes inside my torso.

1 Like

dude, hold yourself together man…
Anyways…
With regards to your script, your nearly there. Personally I take the approach of using angles instead of using pure cframes, this is because in your CFrame.new(point1, point2) solution you will very quickly run into issues when aiming directly up or down.

Anyways as for a solution I won’t give you any code but rather I will give you a few tips to how to get there.

A weld on an arm is offset, therefore you need to make sure to replicate that with this equation, I recommend using ToObjectSpace and ToWorldSpace.

For easier math you will want to localize the target based on the torsos CFrame.

As for the yaw and pitch of the arm, heres a great equation for that:

local yaw = math.atan2(-localizedTarget.X, -localizedTarget.Z)
local pitch = math.atan2(localizedTarget.Y, math.sqrt((localizedTarget.X ^ 2) + (localizedTarget.Z ^ 2)))

Now go learn some math!

As a side note, please don’t beg, your not going to get anywhere with that.

1 Like

Hello,
Can you specify what you mean by ‘math’? Also, what is yaw and pitch, what does ToObjectSpace and ToWorldSpace do

Read up on this stuff.
When I refer to math I’m refering to the equations which are involved with CFrame operations, terms such as Radians, Rotational Matrix and Vector should be familiar to you.

Hello,
Is this what you are talking about when arm pointing upwards have issue?

wait(2)
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local plr = Players.LocalPlayer
local char = plr.Character
local mouse = plr:GetMouse()
mouse.TargetFilter = workspace
local armOffset = char.Torso.CFrame:Inverse() * char["Right Arm"].CFrame

local armWeld = Instance.new("Weld")
armWeld.Part0 = char.Torso
armWeld.Part1 = char["Right Arm"]
armWeld.Parent = char
local lastmou
RunService.RenderStepped:Connect(function()
	
	lastmou = mouse.Hit.p
	local e = Instance.new("Part",workspace)
	e.CFrame = CFrame.new(char.Torso.Position, mouse.Hit.Position)
	e.Anchored = true
	e.CanCollide = false
	e.Size = Vector3.new(1,1,1)
	game:GetService("Debris"):AddItem(e,.05)
	local cframe = CFrame.new(char.Torso.Position, mouse.Hit.Position) * CFrame.Angles(math.pi/2, 0, 0)
	armWeld.C0 = armOffset * char.Torso.CFrame:toObjectSpace(cframe)
end)

I have no idea how to fix it and if you could please help me that would be fine :smiley:

Hello,
Also I would like it to so that the arm points inversely if your mouse is in the back of your character because human arms can’t move like that :stuck_out_tongue_winking_eye:

Hello,
I did some math and it seems like I got it with UpVector and RightVector but for some reason setting the c0 of the armweld would make my arm float and it’s very weird because when I rotate my character and make it fall the arm just moves back and it stays there

wait(2)
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local plr = Players.LocalPlayer
local char = plr.Character
local mouse = plr:GetMouse()
mouse.TargetFilter = workspace
local armOffset = char.Torso.CFrame:Inverse() * char["Right Arm"].CFrame

local armWeld = Instance.new("Weld")
armWeld.Part0 = char.Torso
armWeld.Part1 = char["Right Arm"]
armWeld.Parent = char
local lastmou
RunService.RenderStepped:Connect(function()
	
	lastmou = mouse.Hit.p
	local e = Instance.new("Part",workspace)
	e.CFrame = CFrame.new(char.Torso.Position+char.Torso.CFrame.RightVector+char.Torso.CFrame.UpVector, mouse.Hit.Position)
	e.Anchored = true
	e.CanCollide = false
	e.Size = Vector3.new(1,1,1)
	game:GetService("Debris"):AddItem(e,.05)
	local cframe = CFrame.new(char.Torso.Position+char.Torso.CFrame.RightVector+char.Torso.CFrame.UpVector, mouse.Hit.Position)
	armWeld.C0 = cframe * CFrame.Angles(math.pi/2, 0, 0)
end)


Very weird indeed :thinking:

Hello,
Is anyone going to help me? It’s been 44 days and I’m still unfortunately stuck on this very issue.

2 Likes

Hello,
No one is going to help me? I’m sorry if you think this is spamming/bumping but if I leave this post for another month I’m not going to receive a single droplet of help, let alone any useful ones

His velocity thing I got a better idea I used to help my friend when dealing with tweening on the rs. Basically we use whats called “parametric rays” basically we can define a point on a ray by

p=o+(d*t)

Where the point is described as our origin of our ray (the hip socket) and d describes our ray (hipSocket - endMouseHit) multiplied by how far along the ray we wanna go. So what we could do is like calculate how long this ray is then plug it for t. From there it’s just interpolation

Hello,
It’s been another month and I was right, @CoderHusk can you explain more

(my grammar is horrible btw)
Hello :D!,
iSyriux

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local char = player.Character
local mouse = player:GetMouse()

--Weld for the cframing plus motor6ds are out of my league and animations will still work like nothing happen to it

local armWeld = Instance.new("Weld")
armWeld.Part0 = char.Torso
armWeld.Part1 = char:WaitForChild("Right Arm")
armWeld.Parent = char

--pi/2 is also known as 90 deg.(just wanted to point this out lol)

local piDiv2 = -math.pi/2

RunService.Heartbeat:Connect(function()
	local CFraming = CFrame.new((char.Torso.CFrame * CFrame.new(1.5, 0.5, 0)).Position, mouse.Hit.Position) * CFrame.new(0, 0, -0.5) * CFrame.Angles(piDiv2, 0, 0)
	armWeld.C0 = char.Torso.CFrame:ToObjectSpace(CFraming)
end)

Ok so i found a post where someone made a R15’s player arm to face the mouse direction, so i converted it to R6 and changed some stuff about it. Now we get this.

anyways, we first get the position of where the rotation is occurring and then we give it the mouse position,

then we’ll add another -0.5 offset when it has its LookVector that way it isn’t centered,

after we’ll turn it from world space to object space.

Now I’ll point out that there’s way more efficient ways of doing this, but this is just a demo so it shouldn’t be too bad.

If you don’t want the player’s arm to go into the player’s character you can use the dot product and inverse it or something

Vectors can be formed from 2 points. If you know where your mouse will hit in world space and you know the length of the arm the end position is the solution to this problem

endPosition = hipSocket + (mouseHit - hipSocket).Unit * lengthOfArm

So calculate the end position from that then you can align it by using the cframe method

The cframe of this part is equal to this ^

1 Like

I’m sorry about bumping this topic, but no one pointed out that the person said that the script is specifically meant for r6, yet you used r15, so it didnt work

Sorry for the late response, but there still isn’t a solution for this yet.

local position = char.Torso:WaitForChild('Right Shoulder').C0.Position+Vector3.new(0,.5,0)

game:GetService("RunService").RenderStepped:Connect(function()
    if equipped == true then
        local RightShoulder = char.Torso:WaitForChild("Right Shoulder")
        local X = -(math.asin((mouse.Origin.p - mouse.Hit.p).unit.y))
        local _, Y, Z = RightShoulder.C0:ToEulerAnglesXYZ()
        RightShoulder.C0 = CFrame.new(RightShoulder.C0.Position) * CFrame.Angles(X+math.pi/4, Y, Z+math.pi/4)
    end
end)
4 Likes