Using fake (viewmodel) arms to point to the mouse

I’m trying to make a system where upon equipping a tool, such as a gun or melee, the character’s real arms are hidden and a pair of fake, viewmodel arms is CFramed to the character. This is so the arms can point up and down with the mouse/camera.

local cam = workspace.CurrentCamera
local viewmodel = cam.Viewmodel
local vmHum = viewmodel.Humanoid
local vmPart = viewmodel.PrimaryPart

game:GetService("RunService").RenderStepped:Connect(function(dt)
	local mousePos = mouse.Hit.Position
	
	local X = -(math.asin((char.HumanoidRootPart.Position - mousePos).unit.y))
	vmPart.CFrame = char.Head.CFrame * CFrame.Angles(X,0,0)
end)

Note:
The viewmodel is basically an R6 character with all the parts invisible except the arms. The PrimaryPart in this case is the head.

Result:


Fake arms - viewmodel being rotated

As you can see in the above video, it works but the arms sort of move away from the shoulder as they’re rotating; I want to negate this offset so that it stays in position like the real arms, similar to the video below:


Real arms - Motor6Ds being rotated

You may be wondering, why don’t I just rotate the Motor6Ds of the real arms to achieve this?
Well, I tried this in my previous gun systems, and it works, but with a catch: tools have to be welded to the Right or Left Arm, otherwise they don’t rotate with the arms properly.
This means the arm that the tool is welded to can’t be animated, as it’s in a fixed position relative to the tool - for example, a bolt action rifle welded to the Right Arm can’t have any animations of the right arm pulling the bolt back, making for some pretty scuffed animations.

Using fake arms allows me to weld tools to the Torso or HumanoidRootPart of the viewmodel, while maintaining the smooth up and down movement with the mouse, as the whole viewmodel can be rotated instead of having to edit motor6Ds. This gives me much more freedom in animating.

1 Like

Here is an idea of what you can do to get this offset.

The issue is the pivot center is the head CFrame which the arms are welded at a constant position C0 away from as you mentioned.

You can get the world position relative to 0,0,0 origin of the arm joints using the Motor6D formula

(Part0.CFrame * C0).Position

This is the target constraint relative to the torso.

So it’s just about adjusting the viewmodel welds which starts relative to the head to go to that position.

local motor = script.Parent
local target = workspace.Target

local function worldCFrameRotationToC0ObjectSpace(motor6DJoint,worldCFrame)
	local part1CF = motor6DJoint.Part1.CFrame
	local part0 = motor6DJoint.Part0
	local c1Store = motor6DJoint.C1
	local c0Store = motor6DJoint.C0
	local relativeToPart0 = part0.CFrame:inverse() * worldCFrame * c1Store
	
	local goalC0CFrame = relativeToPart0
		
	return goalC0CFrame
end

while true do
	task.wait()
	motor.C0 = worldCFrameRotationToC0ObjectSpace(motor, target.CFrame)
end
2 Likes

That wouldn’t work though as I’d have to weld tools to the arms so they would follow the rotation of the arm joint properly. The whole point I’m using fake arms for this is so I can rotate the arms without editing the shoulder joints; this lets me weld a tool to the Torso of the viewmodel and it will follow the rotation of the arms, as the whole viewmodel assembly including the tool is rotated.

My problem now is just making the viewmodel pivot from the shoulders instead of the head (the head is the PrimaryPart):


Red is the viewmodel, blue is the real character

Would something like ToObjectSpace work for this? Or would I just manually offset it by a factor of X, for example:

vmPart.CFrame = char.Head.CFrame * CFrame.Angles(X,0,0) -- * CFrame.new(0, X*0.5, X*0.3) ?

Never mind, figured out another way to do this.

howd you work this out? How do you think i could do this for r6 arms?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.