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
(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)
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
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)
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?
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?
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
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.
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
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)
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.
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
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
--]=]
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