Rotating arms, weapon, and head relative to first-person camera movement

Hello! As an element of a survival game I’m making, I’ve created a rough weapon system, one that does not use a view model, as it’s a lot more convenient and I’ve had issues with view models previously, and using guns that are Motor6D’d to the character’s HumanoidRootPart, as I need the two arms available to make convincing reload animations.

My issue is that I have no clue how I’d move the arms, gun, and head up and down in first and third-person (first-person being more important) as the camera moves, also without butchering the animations I’ve already done.

I’m striving for a look much like CoderQwerty’s guns, albeit mine is using actual animations (his guns use a script to change CFrame)
His system:

My rifle currently looks like this:

I did extensive searching for solutions yesterday, finding a few posts that looked promising but either didn’t work in my case or were too confusing to follow, particularly this one.

If I can do something that looks like this in a live game, except it stays with the torso and also doesn’t tear off the arms, I’d be ecstatic.

This bit of scripting is new to me. What can I do to create such a thing for my guns? Thanks in advance!

8 Likes
local modelCFrame = CFrame.new(head.Position) -- Position
    * CFrame.lookAt(Vector3.new(), cam.CFrame.LookVector) -- Rotation
    * CFrame.new(0,0,-2) -- Offset

or

local modelCFrame = cam.CFrame -- Position &  Rotation
    * CFrame.new(0,0,-2) -- Offset

I don’t know if this can help, but you can move the arms using this method but it will rotate from the camera, and not the center of the model.

2 Likes

How can I use this? What I just tried gave me some unexpected results, I’m definitely not doing it the right way.

If you’re looking to do the aiming using Roblox animations there is one method that I know, although it’s a bit hacky. The official Roblox gun kits, such as their Auto Rifle, make use of it.

They have a single aiming animation which is one second long (because it makes the maths easier). Over this second the animation goes from aiming straight down to straight up.

Aim Animation

Animation Aiming

To make use of this animation they bind a function to the render step, set the animation’s speed to 0, and adjust the TimePosition of the animation so that it corresponds to the angle the player is aiming at. In the gun kit, this is done on line 906 of the BulletWeapon module script. A simplified extract from my own version is:

Code Extract
function getLookAngle()
	local baseCFrame = Character.HumanoidRootPart.CFrame + Character.HumanoidRootPart.CFrame.UpVector * (Character.HumanoidRootPart.Size.Y / 2)
	local objectSpacePosition = baseCFrame:pointToObjectSpace(Mouse.Hit.Position)

	--local horizontalAngle = -(math.atan2(-objectSpacePosition.x, -objectSpacePosition.z))
	local verticalAngle = (math.atan2(objectSpacePosition.y, math.sqrt(objectSpacePosition.x^2 + objectSpacePosition.z^2)))

	return verticalAngle
end

function updateAim()
	-- Some code to get the aimTrack, set it up, play it, handle aiming/aiming down sights, etc.

	local lookAngle = getLookAngle()
	-- A few magic numbers are required to convert from radians to a 0-1 interval.
	local aimTimePos = (lookAngle + math.pi/2) * (aimTrack.Length / math.pi)

	aimTrack.TimePosition = aimTimePos
end
19 Likes

You’re awesome for the response, thank you!

I’ve built your code into the gun and the movement is looking super smooth from player’s perspective. The only unsatisfying thing is the shooting animation, which I had to turn into another aiming animation with the gun pushed back slightly to simulate recoil, though I could still probably improve it.

I’ve only run into one actual issue with this. Is there any way I could improve the slow replication of the aiming animation on the server?

3 Likes

I think that lag might just be caused by Roblox reducing the frame rate for inactive windows. When I test in Studio I have the same issue, but it doesn’t appear in live games. Would you be able to test this?

1 Like

Tested this with my alt account in a live server. I found it’s still unfortunately laggy, almost as if the server updates are delayed, as I’ve seen the shooting animation continuing to play much longer than it should’ve.

I’ve only edited a minimal amount of the updateAim() function you gave me, so I have no clue as to what’s causing this.

Edited Code
function updateAim()
	aimTrack:AdjustSpeed(0)
	-- Some code to get the aimTrack, set it up, play it, handle aiming/aiming down sights, etc.

	local lookAngle = getLookAngle()
	-- A few magic numbers are required to convert from radians to a 0-1 interval.
	local aimTimePos = (lookAngle + math.pi/2) * (aimTrack.Length / math.pi)
	local shootTimePos = (lookAngle + math.pi/2) * (shootTrack.Length / math.pi)

	aimTrack.TimePosition = aimTimePos
	shootTrack.TimePosition = aimTimePos
end

RunService.RenderStepped:Connect(function()
	updateAim()
end)

How are you switching between the aimTrack and shootTrack, are you playing/stopping them or adjusting their weight? I’ve not seen this issue in my system, which adjusts the weight of each track and only plays them when required.

I’ve actually moved on to a different method which I think will work better in the long run but I’ve nevertheless marked your post as the solution. I appreciated your help a bunch!

5 Likes

how did you make the firing animation follow the idle rotation as well?

adding on to this, how did you do that?