How would I make a player's arm rotate based on their camera CFrame?

  1. What do you want to achieve? Keep it simple and clear!

I want the player’s arms to rotate up and down based on the camera CFrame using Motor6Ds. This is specifically, for a first person flashlight.

  1. What is the issue? Include screenshots / videos if possible!

The issue is that I’m not very experienced in CFrame’s and Motor6D’s. I’m not sure where to start.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I’ve looked on the Developer hub and I’ve found some similar things, but they don’t seem to exactly match up with what I want. I’ve tried to study Motor6D’s and do this, but my solutions were unsuccessful.

Can anybody give me some directions?

7 Likes

I do not recommend using motor6Ds, for rotating parts, you should use CFrame

assuming you have forced first person:

try this - local script in startercharacterscripts

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local cframe = camera.CFrame
local character = player.Character or player.CharacterAdded:Wait()

while task.wait() do
cframe = camera.CFrame
character.RightUpperArm.CFrame = CFrame.fromOrientation(cframe.X, cframe.Y, cframe.Z)
end

i dont have my pc rn so cannot test so might not work as intended

6 Likes

Hi there.
I tested your script so that it might have worked.

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local cframe = camera.CFrame
local character = player.Character or player.CharacterAdded:Wait()

while task.wait() do
cframe = camera.CFrame
character.RightUpperArm.CFrame = CFrame.fromOrientation(cframe.X, cframe.Y, cframe.Z)
end

3rd Person:

1st Person:


Seizure warning:
robloxapp-20230806-2356127.wmv (2.1 MB)]

I don’t know why both modes give ya seizures. I made them spoilers so you don’t get seizures right away

Thanks for understanding.

I forgot they are downloads, don’t download them without checking first

4 Likes

for some reason my device wont allow me to open those files :confused:
could you do it in a drive and send link instead

1 Like

oh those are windows media files ima convert them to mp4 files

edit: here they are:
Conversion 1


Spoiler Warning!

Conversion 2
i guess its waay too big so i cant send it, i might rethink options

3 Likes
local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local cframe = camera.CFrame
local character = player.Character or player.CharacterAdded:Wait()

character.RightUpperArm.CanCollide = false
character.RightLowerArm.CanCollide = false
character.RightHand.CanCollide = false

while character:FindFirstChildOfClass("Tool") do
task.wait()
cframe = camera.CFrame
character.RightUpperArm.CFrame = CFrame.fromOrientation(cframe.X, cframe.Y, cframe.Z)
end
2 Likes

aight if this works you know

-- specimen 1

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local cframe = camera.CFrame
local character = player.Character or player.CharacterAdded:Wait()

while task.wait() do
cframe = camera.CFrame
character.RightUpperArm.CFrame = CFrame.fromOrientation(cframe.X, cframe.Y, cframe.Z)
end

--Specimen 2

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local cframe = camera.CFrame
local character = player.Character or player.CharacterAdded:Wait()

character.RightUpperArm.CanCollide = false
character.RightLowerArm.CanCollide = false
character.RightHand.CanCollide = false

while character:FindFirstChildOfClass("Tool") do
task.wait()
cframe = camera.CFrame
character.RightUpperArm.CFrame = CFrame.fromOrientation(cframe.X, cframe.Y, cframe.Z)
end

Roblox only outputs in WMV format so it might not fit and I’ll need to know what to do

2 Likes

“specimen 2” detects if holding the tool making it fit more to the OP’s post
and also I believe the seizures were from collisions

2 Likes

I put it in StarterPlayer>StarterCharacterScripts

2 Likes

does it work?
also for clarification on client/server, local scripts replicate inside characters

2 Likes
local run = game:GetService'RunService'

local cam = workspace.Camera
local char = script.Parent
local rightShoulder:Motor6D = char:WaitForChild'RightUpperArm':WaitForChild'RightShoulder'

local speed = 5 -- You can adjust how fast the arm moves

local offset = math.pi/2
local current = CFrame.identity
run.Stepped:Connect(function(_,dt)
	local x = cam.CFrame:ToOrientation()
	local target = CFrame.Angles(x+offset,0,0)
	current = current:Lerp(target,math.min(dt*speed,1))
	rightShoulder.Transform = current
end)

This is just a sample code of how to rotate the arm based on their camera cframe. Let me know if you need help implementing it on your own code.

Edit: Here is a recording using the code

sorry for the terrible fps, my pc is very bad

4 Likes

For what you are suggesting and want it to look ‘decent’ in first person (especially for flashlights), I suggest getting a normal viewmodel from toolbox or make you own. I suggest getting a normal dummy, making all parts except for the arms invisible, and deleting the legs and the motors for the legs and use that for a viewmodel.

Something like this:


image

Edit: I realised that I wasn’t following the original question when I posted this. You should use RunService.RenderStepped() and call the viewmodel’s CFrame to the current player’s camera CFrame. Naturally, if you don’t want to do that, use the viewmodel’s RootPart and make it so that it follows the character’s root part instead. (On R6, “RootPart” is the head, while on R15 it’s the HumanoidRootPart.):

Apologies if none of this makes sense, it’s like the first time in forever I’ve decided to reply to a post. If you want me to explain this any further in better detail so it makes more sense, do reply to this message :pray:

4 Likes

Sorry for everyone who made examples and scripts using CFrame. It has to make use of Motor6D’s since I need to have an animation with the arm also playing at the same time. So, I was wondering, is it necessary that I use .Stepped? Or can I used .RenderStepped or :BindToRenderStep()?

So after testing I’ve gotten these strange results:

I have it in a :BindToRenderStep(). If you look in the bottom right corner where my properties window is, you can see the orientation of the “RightShoulder” Motor6D changing when I move my camera up and down, but it doesn’t appear like that. Here’s my code that’s inside the render step:

				local x = v2.cam.CFrame:ToOrientation() --v2 is a module with info like "cam" (which is the camera, as you may assume)
				local target = CFrame.Angles(x+offset,0,0) --offset is defined outside the loop as math.pi/2
				current = current:Lerp(target,math.min(p8*50,1)) --p8 is the deltaTime, current is originally set outisde of the loop as CFrame.identity
				l__RightShoulder__24.Transform = current

All this inside a :BindToRenderStep(). Is there anything wrong with this? If you need more info, just ask.

Edit: I forgot to mention the script doing this is a LocalScript under the StarterGui.

So after a lot of testing and adjusting, I’ve fit this into my code with my preferences. The final and partially glitchy looking outcome that I’m ok with:


For any future viewers, I had to use .Stepped().

Here’s (a piece) of my code:

local x = cam.CFrame:ToOrientation() --cam is workspace.CurrentCamera
local target = CFrame.Angles((x/1.5+offset),0,0) -offset is math.pi/2
current = current:Lerp(target,math.min(dt*10,1)) --dt is the deltaTime
l__RightShoulder__24.Transform = current --l__RightShoulder__24 is the right shoudler joint

Thanks for helping me everyone!

3 Likes

that’s just the doors flashlight…

Yes, it’s the model, but it’s temporary and the animations and sounds are different. I was just using it as a placeholder. :slight_smile:

2 Likes

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