Camera Cutscene Addon
This addon allows you to export Blender camera keyframes to JSON data, which then can be used to make Roblox cutscenes after decoding to Lua.
Installing Addon to Blender
Step 1
Create a Python script file with the Addon source code.
Source Code:
bl_info = {
"name": "Export Camera Animation to JSON (with CFrame Matrix)",
"author": "ApparentlyJames",
"version": (1, 2),
"blender": (2, 80, 0),
"location": "File > Export > Camera Animation (.json)",
"description": "Export camera animation with baked modifiers using CFrame-compatible matrix format for Roblox.",
"category": "Import-Export",
}
import bpy
import json
from bpy_extras.io_utils import ExportHelper
import mathutils
import bpy_extras
class ExportCameraAnimation(bpy.types.Operator, ExportHelper):
bl_idname = "export_anim.camera_json"
bl_label = "Export Camera Animation"
filename_ext = ".json"
filter_glob: bpy.props.StringProperty(default="*.json", options={'HIDDEN'})
def execute(self, context):
scene = context.scene
cam = scene.camera
if cam is None:
self.report({'ERROR'}, "No active camera in the scene.")
return {'CANCELLED'}
depsgraph = context.evaluated_depsgraph_get()
eval_cam = cam.evaluated_get(depsgraph)
fps = scene.render.fps
start = scene.frame_start
end = scene.frame_end
transform_to_y_up = bpy_extras.io_utils.axis_conversion(
from_forward='-Y', from_up='Z', to_forward='Z', to_up='Y'
).to_4x4()
cframe_frames = {}
fov_frames = {}
for frame in range(start, end + 1):
scene.frame_set(frame)
depsgraph.update()
matrix = eval_cam.matrix_world.copy()
y_up_matrix = transform_to_y_up @ matrix
cframe_components = [
y_up_matrix[0][3], y_up_matrix[1][3], y_up_matrix[2][3],
y_up_matrix[0][0], y_up_matrix[0][1], y_up_matrix[0][2],
y_up_matrix[1][0], y_up_matrix[1][1], y_up_matrix[1][2],
y_up_matrix[2][0], y_up_matrix[2][1], y_up_matrix[2][2],
]
cframe_frames[frame] = cframe_components
fov_frames[frame] = cam.data.angle
output = {
"camera_animation": {
"fps": fps,
"frame_range": [start, end],
"frames": cframe_frames,
"fov_frames": fov_frames
}
}
with open(self.filepath, 'w') as f:
json.dump(output, f, indent=4)
self.report({'INFO'}, f"Camera animation exported to {self.filepath}")
return {'FINISHED'}
def menu_func_export(self, context):
self.layout.operator(ExportCameraAnimation.bl_idname, text="Camera Animation (.json)")
def register():
bpy.utils.register_class(ExportCameraAnimation)
bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
def unregister():
bpy.utils.unregister_class(ExportCameraAnimation)
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
if __name__ == "__main__":
register()
Installing Roblox Plugins
Cutscene Essentials - Creator Store
JSON Importer - Creator Store
Usage Example
Basic Animating
Step 0 (optional):
Enable Auto-Keying by pressing the dot button on the timeline.Step 1:
Set Viewpoint to be the camera by going to View > Viewpoint > Camera, or alternatively pressing the keybind assigned to it (Numpad 0).Step 2:
Go to Fly/Walk Navigation to position the Camera to your needs by going to View > Navigation > Move Navigation, or alternatively pressing the keybind assigned to it (Shift + F).Step 3:
Once you're done with the first keyframe, expand the "Summary" in the timeline and make sure the keyframe is inserted. If not, then press I to insert it manually.Step 4 (optional):
Uncheck "Only Keyframes from Selected Channels", so the timeline keyframes are always visible.This concludes the essential basic animating, for advanced camera manipulation you should research from YouTube or other articles.
How to Use the Camera in Blender (Tutorial) - YouTube
Mastering Camera Control in Blender: A Comprehensive Guide - BlinksAndButtons
Adding scene to Blender
Step 1:
Select the instances you'll want to insert to Blender, then Right-click and press "Export Selection".Step 2:
Create a folder, and export selection into it.Step 3:
On Blender, go to File > Import > Wavefront (.obj), and go to the folder you just created, then select the .obj file.Step 4:
!! DO NOT MOVE OR SCALE THE IMPORTED SCENE !!Use the Walk Navigation to move to the scene and continue your animating process.
Tip: Hold SHIFT to move faster.
Exporting
Before baking and exporting, I recommend saving the .blend file to a folder, incase you'll want to edit something.
Step 1:
Press F3, and type in "bake". The Bake Actions, so if you have any graph modifiers, they should get baked onto the animation timeline.Step 2:
Go to File > Export > Camera Animation (.json). This will save your camera keyframes as a JSON file.Code Example to playing animations in-game
-- Function to turn Array keyframe to a CFrame
local function arrayToCFrame(arr)
return CFrame.new(
arr[1], arr[2], arr[3],
arr[4], arr[5], arr[6],
arr[7], arr[8], arr[9],
arr[10], arr[11], arr[12]
)
end
-- Animation Variables
local AnimationModule = require(pathToModule)
local animation = AnimationModule.camera_animation
local startPoint = animation.frame_range[1]
local endPoint = animation.frame_range[2]
-- Keyframe Loop
for i = startPoint, endPoint do
local keyframeID = tostring(i)
local keyframe = animation.frames[keyframeID]
if not keyframe then
continue
end
TweenService:Create(workspace.Camera, TweenInfo.new(1 / animation.fps, Enum.EasingStyle.Linear), {
CFrame = arrayToCFrame(keyframe),
FieldOfView = math.deg(animation.fov_frames[keyframeID])
}):Play()
task.wait(1 / animation.fps)
end
--[[
Animation Data Format:
{
camera_animation = {
fps = <number>,
frame_range = {
<start_keyframe_number>,
<end_keyframe_number>
},
frames = {
[<keyframe_id_string>] = <cframe_array>,
...
},
fov_frames = {
[<keyframe_id_string>] = <fov_radians>,
...
},
}
}
]]
If you like the plugin, consider donating (through the gamepasses) :]
Made with by ApparentlyJames