Camera Animations for cutscenes and gameplay!

To be honest, there are barely any games that use camera animations. Even though a good camera can make an attack feel much more powerful or give an awesome shot of a landscape during a cutscene. So I will be teaching how you can make camera animations, and use them in-game.

Note: This is my first ever tutorial on here, please roast me.

To start off, you’re going to need Moon Animator.

I will start by explaining how to make simple cutscenes that always appear in the same position, I recommend reading that first, since the gameplay portion will build off of that.

Simple Cutscene

Once you’ve made a new project, add a camera to it.
image

Select the CFrame track
image

And move your camera anywhere you’d like (Tip, you can use control + h to toggle the UI)
Once you’ve found a nice position press the + key to make a new keyframe
Slide the position marker forward a bit and make the next keyframe, keep doing this until you’re finished.

(Extra tip! You can add a character with an animation to your project, and animate them at the same time! This is great for syncing the camera with character animation)

Once you have finished your animation, it’s time to export.
image

It should export a folder that contains the CFrame for every frame (Based on the animation FPS, 60 by default) Place this folder in a place the client can access
image

Now that you’ve made your animation, we need to actually script it so we can run it in-game

local RunService = game:GetService("RunService")

local Character = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
local Camera = workspace.Camera

function Cinematic()
	local CinematicsFolder = nil -- Path to your folder! 

	local CurrentCameraCFrame = workspace.CurrentCamera.CFrame

	Camera.CameraType = Enum.CameraType.Scriptable
	local FrameTime = 0
	local Connection

	Connection = RunService.RenderStepped:Connect(function(DT)
		local NewDT = DT * 60
		FrameTime += NewDT
		local NeededFrame = CinematicsFolder.Frames:FindFirstChild(tonumber(math.ceil(FrameTime)))
		if NeededFrame then
			Character.Humanoid.AutoRotate = false
			Camera.CFrame = NeededFrame.Value
		else
			Connection:Disconnect()
			Character.Humanoid.AutoRotate = true
			Camera.CameraType = Enum.CameraType.Custom
			Camera.CFrame = CurrentCameraCFrame	
		end
	end)
end

Calling this “Cinematic” function, and having your folder pathed should run your cutscene!

Gameplay Cutscenes

This is essentially the same as normal cutscenes, but we will be making use of the “Reference Part” in Moon.
This is the part the camera will offset from.
image
99% of the time, when I’m making attack cutscenes, I just set this to the character’s HumanoidRootPart

Animate your camera like normal and export it, no extra steps there.

In your script, instead of setting the camera cframe like this:

Camera.CFrame = NeededFrame.Value

We multiply it by our reference part’s CFrame
(Say the character’s HumanoidRootPart)

Camera.CFrame = Character.HumanoidRootPart.CFrame * NeededFrame.Value

That’s it! just make sure you pass the correct reference part in your code depending on the cutscene.

Here’s an example in my own game!

79 Likes

gonna need this for later, thank you for tutorial!

3 Likes

Gameplay Cutscenes

More details are needed

Amazing tutorial, thanks for sharing!

1 Like

where do i place the script if im done making the camera?

4 Likes

Can you put more comments in your code? Its really hard for me to understand, especially because I dont know anything about run service.

1 Like

What happens if i fire this on 2 clients, Will the camera play on a single player’s reference part, Or both have their own referenced humanoidrootpart?

If so, How do i make it the camera uses the dominant player’s reference part?

EDIT: Nevermind, I can just change

Camera.CFrame = Character.HumanoidRootPart.CFrame * NeededFrame.Value

to

Camera.CFrame = PlayerToPlayFrom.HumanoidRootPart.CFrame * NeededFrame.Value
1 Like

yo where do i put the script because im lazy

Thanks for this, I thought it would be more difficult than!

StarterPlayerScripts is where i put it

1 Like