How to add a parts cframe position + rotation to the cameras cframe

for example;
part1.cframe = 2,2,2
camera.cframe 1,1,1
camera.cframe = part1.Cframe + camera.cframe
camera.cframe = 3,3,3

how could you achieve this?
im trying to get the camera to play animations and am trying to do through animating a part and adding its cframes on to the camera

Camera.CFrame = CameraPart.CFrame.Rotation + Camera.CFrame.Position 

(script used in video)
^ this is the script i have now but it locks your camera in the part1’s direction (doesnt add them together, just makes camera copy part1’s cframe)

3 Likes

You mean
Camera.CFrame = CameraPart.CFrame
?

Not exactly

video linked has a timestamp;
if you look close you can see when he equips or inspects, his camera is also animated (
Am trying to achieve this if that makes sense

Roblox implemented AnimationController as a way to animate other objects. Hope this helped.

EDIT: If anything, there’s an article about cutscene cameras.

3 Likes

Thank you but i think this is different for what am going for
am explainging it bad
the character still needs to have full control over the camera and keep its original postion however the animation is being played ontop of it so its offsetting the camera i guess

Like how in the youtube video above, its not locking his camera into any position etc, It’s just slightly rotating the camera around (playing the animation)

1 Like

Try using the * operator when combining two CFrames

Here’s a link to the math operations of CFrame

4 Likes

I tried this code

local x, y, z = camPart.CFrame:ToOrientation()
cam.CFrame = cam.CFrame * CFrame.Angles(x,y,z)

its exgarretting it alot and moving the original camera.cframe; It should go back to where the camera orignally was at the end of the animation

the actual animation is rly Subtle. its multiplying it every frame
im running the code on a render stepped, would checking if its already multipled by an angle fix this?

1 Like

Maybe make a new variable that saves the original camera cframe before applying the changes? Then once the camera animation is done, set the cframe back to that.

As for the exaggeration, multiply the CFrame.Angles by a fraction like 0.5 before multiplying it by the cam.CFrame?

2 Likes

i tried this

local OldCamCF = CFrame.Angles(0,0,0)

					local x, y, z = CameraPart.CFrame:ToOrientation()
					if OldCamCF ~= CFrame.Angles(x,y,z) then
						print("RAN")
						OldCamCF = CFrame.Angles(x,y,z)
					Caera.CFrame = Camera.CFrame * CFrame.Angles(x,y,z)

its still weird, i dont think multiplying it like this works but idk
the fraction idea might not work because itll change the animation speed depending on ur frames since its on renderstepped

1 Like

Now that I’m on my laptop and not at work I can see the video better. I’ve experimented a lot with adding/subtracting 3D rotations. I’ve not found a single one that works correctly.
However your problem is much simpler. All you need to do is take the current cframe and rotate it by CFrame.Angles() Then tell tweenservice to move to that cframe and then tell it to move to the original cframe. Or you could even use the reverses boolean so it reverses to the original cframe.

TweenInfo:

Also,

local OrigCFrame = workspace.CurrentCamera.CFrame
local NewCFrame = OrigCFrame*CFrame.new(0,1,0)*CFrame.Angles(0.1,0.1,0)
-- By multiplying by CFrame.new(0,1,0) instead of adding a vector3, it will localize the position relative to OrigCFrame
1 Like

Second thought, that won’t let you rotate your camera during animation.
Instead maybe do something like this:

local OrigRot = CFrame.Angles(0,0,0)
local NewRot = CFrame.Angles(0.1,0.1,0.1)
local PrevRot = OrigRot

local time = 0
local time_to = 0.1
local con
con = game:GetService("RunService").RenderStepped:Connect(function(dt)
  time += dt
  local lv = time/time_to
  if lv > 1 then lv = 1 end
  local new_rot = OrigRot:Lerp(NewRot, lv)
  workspace.CurrentCamera.CFrame *= PrevRot:Inverse()*new_rot
  PrevRot = new_rot
  if lv==1 then con:Disconnect() end
end)
1 Like

Thank you for putting time into this ive been stuck on this for while
i dont rly understand it though, would this work for copying the cameraParts cframes onto the camera and how would it look

local anims = {}

game:GetService("RunService"):BindToRenderStep("CameraMovement", Enum.RenderPriority.Camera.Value-1, function(dt)
	local cam_cf = workspace.CurrentCamera.CFrame
	for i,vars in pairs(anims) do
		vars.time += dt
		local lv = vars.time/vars.time_to
		if lv >= 1 then
			lv = 1
		end
		local new_cf = vars.FromCFrame:Lerp(vars.ToCFrame, lv)
		cam_cf *= vars.PrevCFrame:Inverse()*new_cf
		vars.PrevCFrame = new_cf
		if lv==1 then
			if vars.Reverse==false then
				vars.Reverse = true
				vars.time = 0
				local tocf = vars.ToCFrame
				vars.ToCFrame = vars.FromCFrame
				vars.FromCFrame = tocf
			else
				table.remove(anims,i)
			end
		end
	end
	workspace.CurrentCamera.CFrame = cam_cf
end)

local function doit()
	table.insert(anims, {
		FromCFrame = CFrame.Angles(0,0,0),
		ToCFrame = CFrame.Angles(0,0.1,0),
		PrevCFrame = CFrame.Angles(0,0,0), -- always same as FromCFrame
		Reverse = false,
		time = 0,
		time_to = 0.2,
	})
end

for i=1,100 do
	doit()
	wait(.5)
end

Here I wrote and tested this code. I was having a problem where I wanted the camera to run after the rotation code so it wouldn’t offset where the camera was looking. I didn’t want to change the camera’s CameraType to Scriptable because then it wouldn’t follow the character during animation. Like if you rotated your camera around your character, it wouldn’t allow that. So I decided to use BindToRenderStep to assign it the correct render priority.

1 Like

this loosk really complicated thank you for this
this might be little different, i might be reading it wrong but am guessing the anim Table is to put your animations in it for it to play
Basically the animations are handled through a rig, its just the normal r6 rig but with a extra part used to control camera animations; so am not sure if a table would work with this as its just animations being played onto the character, and the camerapart is being animated within that. unless am missing something but idk
let me know if needs more explaining, im explaining bad i think

Are you saying the extra part is welded to the character in some way? Like a Motor6D. And then you animate the part in an animation editor?

  • if so
local Rig = script.Parent
local CPart = Rig:WaitForChild("CameraAnimationPart") -- whatever you named it/placed it

local smooth

function ToPart(part, timeToArrive, timeToStay, timeToLeave)
	smooth = {
		time_to_arrive = timeToArrive,
		time_to_stay = timeToArrive + timeToStay,
		time_to_leave = timeToArrive + timeToStay + timeToLeave,
		time = 0,
		part_to_follow = part,
		relative_origin_cframe = Rig.HumanoidRootPart.CFrame:ToObjectSpace(workspace.CurrentCamera.CFrame) -- get camera cframe relative to humanoidRootPart
	}
end

game:GetService("RunService"):BindToRenderStep("CameraExtraMotion", Enum.RenderPriority.Camera.Value+1, function(dt)
	if smooth then
		smooth.time += dt
		if smooth.time < smooth.time_to_arrive then
			local lv = smooth.time/smooth.time_to_arrive
			local from = Rig.HumanoidRootPart.CFrame:ToWorldSpace(smooth.relative_origin_cframe)
			local to = smooth.part_to_follow.CFrame
			workspace.CurrentCamera.CFrame = from:Lerp(to,lv)
		elseif smooth.time < smooth.time_to_stay then
			workspace.CurrentCamera.CFrame = smooth.part_to_follow.CFrame
		elseif smooth.time < smooth.time_to_leave then
			local lv = (smooth.time - smooth.time_to_stay)/(smooth.time_to_leave - smooth.time_to_stay)
			local from = smooth.part_to_follow.CFrame
			local to = Rig.HumanoidRootPart.CFrame:ToWorldSpace(smooth.relative_origin_cframe)
			workspace.CurrentCamera.CFrame = from:Lerp(to,lv)
		else
			workspace.CurrentCamera.CFrame = Rig.HumanoidRootPart.CFrame:ToWorldSpace(smooth.relative_origin_cframe)
			smooth = nil
		end
	end
end)

for i=1,100 do
	ToPart(CPart, 1, 2, 1)
	wait(smooth.time_to_leave)
	wait(3) -- wait time between animations
end
1 Like

hello sorry late response, thanks for this again
this seems different i think am explaining it bad
this seems to tween the players camera to the camera part but i may be using it wrong not sure

animations are being played on the camera part, the animations are only rotating the part so the position isnt moving; only the orientation

cameraParts orientation default is 0,0,0; animations will roate the cameapart, for example in an animation it’ll be 0,90,0 (or anything else, just whatever the orientation is in the animation)

if players camera orientation is e.g: 0,50,30 and the cameraPart is 0,90,0, the players camera rotation should change to 0,140,30 (adding them together) this causes the effect of an animated camera, player should still be in full control etc

the animation automatically goes back to 0,0,0 so dont have to worry about tweening it when it ends or anything

video has timestamp^
same way the camera shakes when he equips or inspects, this is what this is trying to do

Lmk if this makes sense, its hard to explain
Thank you for all effort so far

local anims = {}

game:GetService("RunService"):BindToRenderStep("CameraMovement", Enum.RenderPriority.Camera.Value+1, function(dt)
	local cam_cf = workspace.CurrentCamera.CFrame
	for i,vars in pairs(anims) do
		vars.time += dt
		local lv = vars.time/vars.time_to
		if lv >= 1 then
			lv = 1
		end
		local new_cf = vars.FromCFrame:Lerp(vars.ToCFrame, lv)
		cam_cf *= vars.PrevCFrame:Inverse()*new_cf
		vars.PrevCFrame = new_cf
		if lv==1 then
			if vars.Reverse==false then
				vars.Reverse = true
				vars.time = 0
				local tocf = vars.ToCFrame
				vars.ToCFrame = vars.FromCFrame
				vars.FromCFrame = tocf
			else
				table.remove(anims,i)
			end
		end
	end
	workspace.CurrentCamera.CFrame = cam_cf
end)

local function doit()
	local CPart = script.Parent.CPart
	table.insert(anims, {
		FromCFrame = CFrame.Angles(0,0,0),
		ToCFrame = CPart.CFrame.Rotation,
		PrevCFrame = CFrame.Angles(0,0,0), -- always same as FromCFrame
		Reverse = true,
		time = 0,
		time_to = 0.2,
	})
end

-- call doit when you want to add CPart's rotation to Camera

--[=[
for i=1,100 do
	doit()
	wait(.5)
end
--]=]
1 Like

thank you this is really close
theres only 1 issue, i think its overshooting it a bit (and exgarretting the animation, the actual animations subtle)


am not sure why its doing this, i cant read the script good
but it should be going back to where it was at the end of the animation, it starts at 0,0,0 and ends at 0,0,0
would you know why its doing this? Thank you alot for all help so far

am running doit() on a renderstepped, not if sure thatys right
guessing its causing this

first is roblox client then studio client