效果:
前言:
最近有一个需求,需要将Unity中VR玩家的摄像头运动轨迹与UI以及Blender中的场景合并,渲染成视频用于投标。
我当时在Unity中构建了一个布满追踪点的房间,在VR操作后使用Recorder渲染出一个视频,接着将这个视频导入Blender中反推摄像机的轨迹。这个过程非常耗时,也不够优雅,而且效果不佳。
源码:
将此脚本挂在摄像机上运行游戏
-
它在摄像机运动时记录每一帧的位置和旋转。
- 在对象销毁时,它将这些数据导出到一个名为 “CameraMotionData.csv” 的 CSV 文件中。
- 这段代码实现了摄像机运动数据的记录和导出功能。
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class CameraMotionRecorder : MonoBehaviour
{
private List<Vector3> cameraPositions = new List<Vector3>();
private List<Vector3> cameraRotations = new List<Vector3>();
private void Start() {
Application.targetFrameRate = 60;
}
private void Update()
{
// 记录每一帧的摄像机位置和旋转
cameraPositions.Add(transform.position);
cameraRotations.Add(transform.eulerAngles);
}
private void OnDestroy()
{
// 在对象销毁时导出轨迹数据
ExportCameraMotionData();
}
private void ExportCameraMotionData()
{
string filePath = "CameraMotionData.csv";
using (StreamWriter writer = new StreamWriter(filePath))
{
for (int i = 0; i < cameraPositions.Count; i++)
{
// 将每一帧的位置和旋转写入 CSV 文件
writer.WriteLine($"{cameraPositions[i].x},{cameraPositions[i].y},{cameraPositions[i].z}," +
$"{cameraRotations[i].x},{cameraRotations[i].y},{cameraRotations[i].z}");
}
}
Debug.Log($"摄像机运动数据已导出至 {filePath}");
}
}
Blender这边就只要每帧读取这些数据并写入到时间轴上,注意的是俩软件轴向不一样,需要调换个顺序.Blender相机默认是朝下的,unity是朝前的.需要调整一下
核心代码:
import pandas as pd
import bpy
import math
from addons.hello_world.config import __addon_name__
# path=bpy.context.preferences.addons[__addon_name__].preferences
# path = r'D:/unity project/My project/CameraMotionData.csv'
def readcsv(path):
return pd.read_csv(path)
def Motion(obj,Data):
end_frame = Data.shape[0]
for frame in range(end_frame):
bpy.context.scene.frame_set(frame)
obj.location[0] = Data.iloc[frame,0]
obj.location[1] = Data.iloc[frame,2]
obj.location[2] = Data.iloc[frame,1]
obj.rotation_euler[0] = math.radians(Data.iloc[frame,3]+90)
obj.rotation_euler[1] = math.radians(Data.iloc[frame,4])
obj.rotation_euler[2] = math.radians(Data.iloc[frame,5])
bpy.ops.anim.keyframe_insert_by_name(type="BUILTIN_KSI_LocRot")
写上路径载入相机数据