How can I make the arms and head follow the camera (if that makes sense)

uhhh, i’m trying to make the head and arms face/point at the direction where the player is looking, so the mouse, but how can I do that?


^^ this is a big nono

2 Likes

Hey, I found a similar topic to this one. Check this out and see if it helps:

1 Like

uhhhh… the left arm rotates but doesn’t seem to move, giving weird results

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Torso = Character:WaitForChild('Torso')
local Neck = Torso:WaitForChild("Neck")
local LeftShoulder = Torso:WaitForChild("Left Shoulder")
local RightShoulder = Torso:WaitForChild("Right Shoulder")
local Humanoid = Character:WaitForChild("Humanoid")
local HMR = Character:WaitForChild("HumanoidRootPart")

local Mouse = Player:GetMouse()
local connection = nil

Character.ChildAdded:Connect(function(child)
	if not child:IsA("Tool") then return end
	Humanoid.AutoRotate = false
	local RC0 = CFrame.new(1, .5, 0, 0, 0, 1, 0, 1, 0, -1, 0, 0)
	local RC1 = CFrame.new(-.5, .5, 0, 0, 0, 1, 0, 1, 0, -1, 0, 0)

	local LC0 = CFrame.new(-1, .5, 0, 0, 0, -1, 0, 1, 0, 1, 0, 0)
	local LC1 = CFrame.new(.5, .5, 0, 0, 0, -1, 0, 1, 0, 1, 0, 0)

	local NeckC0 = Neck.C0
	local NeckC1 = Neck.C1

	connection = game:GetService("RunService").RenderStepped:connect(function()
		local cf = workspace.CurrentCamera.CFrame.LookVector.Y

		local Kek = CFrame.Angles(0, 0, math.asin(Mouse.Origin.LookVector.Y))
		RightShoulder.C1 = RC1 * Kek:inverse()
		LeftShoulder.C1 = LC1 * Kek

		Neck.C0 = NeckC0 * CFrame.Angles(math.asin(Mouse.Origin.lookVector.Y), 0, 0):inverse()
		HMR.CFrame = CFrame.lookAt(HMR.Position, Vector3.new(Mouse.Hit.Position.X, HMR.Position.Y, Mouse.Hit.Position.Z), HMR.CFrame.UpVector)
	end)
end)

Character.ChildRemoved:Connect(function(child)
	if not child:IsA("Tool") then return end
	Humanoid.AutoRotate = true
	connection:Disconnect()
end)

Hmm, I’ve changed RenderStepped to PreSimulation and Transforming the motors instead, so that the animations are processed after.

connection = game:GetService("RunService").PreSimulation:Connect(function()
	local cf = workspace.CurrentCamera.CFrame.LookVector.Y
	local angle = math.asin(Mouse.Origin.LookVector.Y)
	local transformAdjustment = CFrame.Angles(0, 0, angle)

	RightShoulder.Transform *= transformAdjustment
	LeftShoulder.Transform *= transformAdjustment:inverse()

	Neck.Transform *= CFrame.Angles(angle, 0, 0):inverse()
	HMR.CFrame = CFrame.lookAt(HMR.Position, Vector3.new(Mouse.Hit.Position.X, HMR.Position.Y, Mouse.Hit.Position.Z), HMR.CFrame.UpVector)
end)

Let me know if the issue persists

it still persists, sadly (me when funny character limit)

I’ve faced the same issue in one of my previous games. My solution was to reanimate the guns to make them straighter and adjust CFrame values, but I wouldn’t recommend this method as it’s quite impractical.

The root of the problem seems to be that animations and the C0 transformations overlap each other, as animations and the transformations basically happen the same way. Unfortunately, I don’t have a definitive fix for this issue, and I haven’t found a satisfactory solution on the DevForum either. However, I suggest doing some further research- you might find a good solution yourself.

I hope at least a little bit of this information could help.

Maybe try changing C0 instead of C1.

insert building collapsing gif

uh no that just broke it even more :sob:

vid?
I think this might be because you are just dividing by a way to big number try something like 2 or even not dividing at all.

1 Like

hm also sorry i thought i was replying to another post in the previous reply anyway try messing with rotating the cframe a bit until it matches up

that doesn’t really do the trick

ah whatever, i’ll look into this later

I solved this using animations. I made an animation for my character aiming his gun and then I transitioned it from pointing down to up over 1 second. Then using a RenderStepped function you can play a specific time point on the animation depending on how far up or down the mouse is aiming.

Here is a video of what mine ended up looking like (had to make the video super short for maximum file size).

isn’t this like, very painful to do?

In terms of difficulty, not hard. It was tedious though, you have to tweak the animation a bit to make a smooth transition from bottom to top. The math portion is super simple, just make 0 seconds positioned at maximum down angle, 1 second at straight forward, and 2 seconds at maximum up. It was pretty straightforward. Interpolating between those was quite easy.

Edit: I’ll share more detailed info about how I accomplished this.

The first step is to create an animation for the Head and UpperTorso. This animation should contain the full range of movement vertically. Personally, I prefer to use the timestamps 0,1,2; where 0 is the player aiming as far down as possible, 1 is straight ahead, and 2 is as high as possible.


Once this is done, I apply this animation with a priority of Action (to override movement animations) to the character at all times. You will not “play” this animation. Rather, you want to use the TimePosition property of the AnimationTrack to control the angle of the character relative to the angle of their camera. The animation does need to be “playing” in order to show, so you will use AdjustSpeed() to set the speed of the animation to 0.

The code to apply this is minimal; first I make sure that when the animation loads, it is facing forward.

local HeadTrack = Humanoid:LoadAnimation(Animations:WaitForChild'HeadAndTorso')
HeadTrack:Play()
HeadTrack:AdjustSpeed(0)
HeadTrack.TimePosition = 1

Next we set the TimePosition every RenderStepped to smoothly update the angle.

if math.abs(ViewAngles.Y) <= 0.01 then -- facing directly forward
	HeadTrack.TimePosition = 1
elseif ViewAngles.Y > 0 then -- facing down
	if ViewAngles.Y > 1.06 then
		HeadTrack.TimePosition = 0
	else
		HeadTrack.TimePosition = 1 - (ViewAngles.Y/1.08)
	end
else -- facing up
	if 1 + -ViewAngles.Y >= 2.3 then
		HeadTrack.TimePosition = 1.99
	else
		HeadTrack.TimePosition = 1 + -(ViewAngles.Y/1.36)
	end
end

You won’t be able to copy and paste this code since ViewAngles is a Vector2 that we implemented for tracking the angle of the player’s camera with custom limits on the max up and down angles of the camera. The numbers seen represent the minimum and maximum angles, with some forgiveness for each. All you need to understand here is that the Y angle represents the vertical angle of the player’s camera and that you should be setting the TimePosition relative to that angle. It is also important that your maximum angle can never reach the full TimePosition of 2, since that “ends” the animation if you reach the end of the Length.

If you have a decent understanding of Lua, you should be able to accomplish results like this or better fairly quickly. Personally, I did not spend much time polishing this animation or writing this code; this part took an hour or less.


The next step is to repeat the first step once for a hip fire animation, and again for ADS. The key difference for these animations is that they will exclusively control the left and right arms (and hands). Additionally, this animation will only play while the gun is equipped.



Now we just implement similar code as above, and toggle between animations when the character is using ADS. Be willing to do some repetitive tweaking on the animations to get the angles just right.


Final result:

2 Likes

had the same problem before, ended up just making a viewmodel and replicating all the m6d Transforms from the character to the viewmodel.

An example post:

So pretty much its as simple as this:

-- also add something to clone the tool and put it in the viewmodel

game:GetService("RunService").RenderStepped:Connect(function()
    viewmodel.PrimaryPart.CFrame = camera.CFrame

    -- obviously change the joints
    viewmodelLeftShoulder.Transform = characterLeftShoulder.Transform
    viewmodelRightShoulder.Transform = characterRightShoulder.Transform
   -- also add any other joints for stuff like guns in here or Grip motor6ds.
   -- here is my implementation
   for _, v in pairs(tool:GetDescendants()) do 
	  if v:IsA("BasePart") then v.LocalTransparencyModifier = 1 end -- make sure u cant see the real one
	  if v:IsA("Motor6D") then
	       viewmodelTool:FindFirstChild(v.Parent.Name, true):FindFirstChild(v.Name).Transform = v.Transform
	  end
   end

   -- whatever else
end)

Pretty sure games like Criminality use this technique.
You can probably find a better tutorial for this on the devforum BTW.

can you help me to that please ?