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.
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.
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.
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
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
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
-- 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
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.
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.
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
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