R15 Arm following mouse?

I’ve seen multiple systems done with R6 which isn’t hard due to it being only 1 limb but how would I go about R15? I can’t seem to find any sources or where to start on how to get the “RightUpperArm”, “RightLowerArm”, and “RightHand” to follow the mouse. I was thinking about inverse kinematics though I don’t know if that’s the solution. If anyone knows themselves or can provide sources that would be highly appreciated.

1 Like

Your right, inverse kinematics would be the best solution. I’m sure there are other solutions out there, but IK is the most natural.

2 Likes

Thanks for providing some sources I could use but after some further looking I managed to find this solution that was originally made to work with R6 but I changed it up a little and now its works. Even works without inverse kinematics

If anyone is wondering here is the code:

Fire the server the mouse position

Remotes.ShoulderCFrameUpdate:FireServer(Mouse.Hit.p)

Calculate on the server
(Dont mind the “RemotePlayer” parameter name. It’s like that for reasons.)

Remotes.ShoulderCFrameUpdate.OnServerEvent:Connect(function(RemotePlayer, MouseHitPosition)
	if RemotePlayer == Player then
		local ShoulderPosition = Character.ArmWeld.Part0.CFrame:toWorldSpace(CFrame.new(0.9,0.25,0.25))
		local ShoulderCFrame = CFrame.new(ShoulderPosition.p, MouseHitPosition) * CFrame.Angles(math.pi/2, 0, 0) * CFrame.new(0, -1, 0)

		Character.ArmWeld.C0 = Character.ArmWeld.Part0.CFrame:toObjectSpace(ShoulderCFrame)
	end
end)

Oh here is the ArmWeld btw

local ArmWeld = Instance.new("Weld")
ArmWeld.Name = "ArmWeld"
ArmWeld.Parent = Character
ArmWeld.Part0 = Character.UpperTorso
ArmWeld.Part1 = Character.RightUpperArm
6 Likes

Revised Version (YES I KNOW IM LATE)

Local-Script : StarterPack, StarterGui or StarterPlayerScripts

--// StarterGui : Local-Script
local player = game:GetService('Players').LocalPlayer
local mouse = player:GetMouse()

local runService = game:GetService('RunService')
local event = game:GetService('ReplicatedStorage'):WaitForChild('ArmsEvent')

runService.RenderStepped:Connect(function()
	event:FireServer(player, mouse.Hit.p)
end)

An alternative to RenderStepped is,

while true do
	delta = game:GetService('RunService').Stepped:Wait()
	-- Sum Code...
end

Script : ServerScriptService

--// ServerScriptService : Script
local replicatedStorage = game:GetService('ReplicatedStorage')
local playersService = game:GetService('Players')

function createArmWelds(character)
	local ArmWeld = Instance.new("Weld")
	ArmWeld.Name = "ArmWeld_Right"
	ArmWeld.Parent = character
	ArmWeld.Part0 = character.UpperTorso
	ArmWeld.Part1 = character.RightUpperArm
	
	local ArmWeld2 = Instance.new("Weld")
	ArmWeld2.Name = "ArmWeld_Left"
	ArmWeld2.Parent = character
	ArmWeld2.Part0 = character.UpperTorso
	ArmWeld2.Part1 = character.LeftUpperArm
end

playersService.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(model)
		
		createArmWelds(model)
		
	end)
end)

replicatedStorage:WaitForChild('ArmsEvent').OnServerEvent:Connect(function(RemotePlayer, CallPlayer, MouseHitPosition)
	if RemotePlayer ~= CallPlayer then return end
	
	local Character = RemotePlayer.Character
	
	for _, armWeld in pairs(Character:GetChildren()) do
		
		if armWeld:IsA('Weld') and string.split(armWeld.Name, '_')[1] == 'ArmWeld' then
			
			local armType =  string.lower(string.sub(armWeld.Name, 9,9))
			local inverse = 1
			
			if armType == 'l' then
				inverse = -1
			end

			local ShoulderPosition = armWeld.Part0.CFrame:toWorldSpace(CFrame.new(0.9*inverse,0.25,0.25))
			local ShoulderCFrame = CFrame.new(ShoulderPosition.p, MouseHitPosition) * CFrame.Angles(math.pi/2, 0, 0) * CFrame.new(0, -1, 0)

			armWeld.C0 = armWeld.Part0.CFrame:toObjectSpace(ShoulderCFrame)
			
		end
		
	end
end)

This is not completed efficient as if the player’s mouse is not moving Data would still get sent, an simple way to reduce Data use it to check the last mouse position and if its same it should close by using return.

You could make more complex by adding a threshold which is just rounding the vectors and checkinf if their the same.