How to make a Parts rotation add onto the Camera? been stuck on this for 2years

Im trying to make a gun system; i cant find any dev forum posts or youtube tutorials about how to make what im trying to do

I have a viewmodel that has an animated CamPart; i’d like the campart rotations to play on the camera

this is what I have right now
(really messy code)

local GoalCFrame
-- renderstep loop below
		local CamPart = Character.CamPart
		
		local cameraX, cameraY, cameraZ = Camera.CFrame:ToOrientation()
		
		local LastCFrame
		local NEWCFRAME
		
		local cp = Character.CamPart


		local x,y,z = cp.CFrame:ToOrientation()
		
		local hrpX,hrpY,hrpZ = Character.HumanoidRootPart.CFrame:ToOrientation()
		
		x -= hrpX ; y -= hrpY ; z -= hrpZ
		
		if LastCFrame then
			x -= LastCFrame.X ; y -= LastCFrame.Y ; z -= LastCFrame.Z
		end
		
		if not GoalCFrame then
			GoalCFrame = Vector3.new(x,y,z)
		end
		
		--LastCFrame = CFrame.Angles(math.rad(Vector3.new(Camera.CFrame:ToEulerAnglesXYZ()).X + CamPart.CFrame.Rotation.X), math.rad(Vector3.new(Camera.CFrame:ToEulerAnglesXYZ()).Y + CamPart.Rotation.Y), math.rad(Vector3.new(Camera.CFrame:ToEulerAnglesXYZ()).Z + CamPart.Rotation.Z))
		
		--local GoalCFrame = Vector3.new(cameraX + x, cameraY + y, cameraZ + z)
		
		--Camera.CFrame = Camera.CFrame * CFrame.Angles(math.rad(Vector3.new(Camera.CFrame:ToEulerAnglesXYZ()).X + CameraPart.CFrame.Rotation.X), math.rad(Vector3.new(Camera.CFrame:ToEulerAnglesXYZ()).Y + CameraPart.Rotation.Y), math.rad(Vector3.new(Camera.CFrame:ToEulerAnglesXYZ()).Z + CameraPart.Rotation.Z))
		Camera.CFrame = Camera.CFrame * CFrame.Angles( math.rad(GoalCFrame.X ), math.rad(GoalCFrame.Y ), math.rad(GoalCFrame.Z) )
		
		GoalCFrame = Vector3.new(x,y,z) - Vector3.new(Camera.CFrame:ToOrientation()) 
		LastCFrame = Vector3.new(x,y,z)
		
		print(x,y,z, GoalCFrame)

it half works, the inspect animation moves the camera according to the CamParts rotation - but it locks the camera into one direction

Let me know if this needs more explaining or if somethings confusing

for example what im trying to achieve: the campart is moved by an animation played on the character, i want the rotation on the campart played from the animation copied to the players camera

so if the players camera cframe was 0,0,0 and the CamPart’s rotation was 0,50,0 then i’d want the camera Cframe to be 0,50,0; same thing for if the players camera cframe was 10,90,50 and campart was 40,40,40 then i’d want the camera’s cframe to be 50,140,90

I cant find a way for the camera to not overadd the cameraparts cframe, it always ends up adding the same calcuation over and over or doubling it

any help appreciated

You should:

  • add the part CFrame to the camera
  • calculate the inverse of the part CFrame
  • Wait for next RenderStepped
  • add the INVERSE that you just calculated (this essentially undos the added part CFrame
  • Repeat from step 1

It is important that you do this with BindToRenderStepped, since it allows you to prioritize this function to always execute AFTER the default camera controller.

I have a post in another thread where somebody had a very similar problem to yours and the solution is basically identical to what I just described. You can take a look here:

1 Like

hi THanks for responding

i struggle with cframes alot, especially with adding them together and rotations

local inverseP
--loop below
		local x,y,z = CamPart.CFrame:ToOrientation()
		local hrpX,hrpY,hrpZ = Character.HumanoidRootPart.CFrame:ToOrientation()
		
		x -= hrpX ; y -= hrpY ; z -= hrpZ
		
		if inverseP then
			
			Camera.CFrame *= inverseP
			
		end
		
		
		

		Camera.CFrame = Camera.CFrame * CFrame.Angles(x,y,z)
		inverseP = CamPart.CFrame:Inverse()

i tried to follow what you said but I dont understand cframes well; i couldnt get it to work
is there anything I can change?
thanks for the response

Two issues.

Angles are discontinuous, so you can’t just subtract them like that. You’ll get much different numbers than expected.

Also, the angles you’re getting are already in radians. You’re converting them from degrees to radians each frame which is why your camera keeps easing towards the identity rotation.

You want your camera to take on the rotation of CamPart right?

To do that you just need to extract the rotation components from CamPart and add the position components from Camera.

local camPartRotation = Character.CamPart.CFrame.Rotation
Camera.CFrame = camPartRotation + Camera.CFrame.Position
1 Like

hi thanks for responding

Im trying to add the rotation of CamPart onto the players camera - as an offset sorta

You can offset the existing camera CFrame with a multiplication.

Camera.CFrame *= Character.CamPart.CFrame.Rotation

But if you just do this then each frame’s offset will accumulate because the Roblox camera has no way of knowing that you’re doing this as a layer on top of the default camera behavior. You need to apply this after the Roblox camera runs and then remove it before it runs on the next frame.

You need to use BindToRenderStep. The Roblox camera runs at the Camera priority. So you can apply the rotation offset at Camera.Value+1. You should remember what the Roblox camera wants the camera to be set to. Then you can set the camera back to that at Camera.Value-1. And the Roblox camera will be unaware of the offset you’re applying.

Also if your CamPart is rotating with your character then you need to extract the rotation relative to your character. Like:

relativeRotation = rootPart.CFrame.Rotation:ToObjectSpace(camPart.CFrame.Rotation)
Camera.CFrame *= relativeRotation
1 Like

i tried this again, its really close but its acting weird

local LastCFrame = nil
-loop below
		local CamPart = Character.CamPart
		
		local cameraX, cameraY, cameraZ = Camera.CFrame:ToOrientation()
		
		local x,y,z
		
		
		x,y,z = CamPart.CFrame:ToOrientation()
		local hrpX,hrpY,hrpZ = Character.HumanoidRootPart.CFrame:ToOrientation()
		
		x -= hrpX ; y -= hrpY ; z -= hrpZ
		
		if LastCFrame then
			
			Camera.CFrame *= LastCFrame:Inverse()
			
		end
		
		
		

		
		Camera.CFrame *= LastCFrame

it seems to be slightly off - when the inspect finishes, the camera ends up in a different location, idk what’s causing this

i just realised since the cameras moving, the viewmodel will too.. so the camera looking down wont be looking at the viewmodel since it’s moving with the camera.. idk how im meant to fix that

for reference this is what im trying to achieve:

  • Weaponry

is there some sort of camera offset option? it looks like there is because the viewmodel and crosshairs position is not affected by the camera moving

i’ve been looking how to do for this for 2 years, ive tried looking through open source gun systems, all of dev forum and youtube vids; i cant find a single post related to this mechanic

any help appreciated, im really stuck on this

i looked through open source gun systems and found a solution

heres the solution if anyone else needs it

local OldCamCF
---below bindtorenderstepped, 201 priority
		local NewCamCF = Character.HumanoidRootPart.CamPart.Transform
		if OldCamCF then
			local _, _, Z = NewCamCF:ToOrientation()
			local X, Y, _ = NewCamCF:ToObjectSpace(OldCamCF):ToEulerAnglesXYZ()
			Camera.CFrame = Camera.CFrame * CFrame.Angles(X, Y, -Z):Inverse() -- try without inverse if acts weird
		end
		OldCamCF = NewCamCF

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