I’m trying to export a mesh that is being animated with code to an Alembic file so I can render it in Blender. However, as soon as the Alembic Exporter starts recording (in play mode) the mesh is frozen in it’s initial state (at least it appears that way in the viewport and the resulting Alembic file reflects the same frozen object). If I disable the Alembic Exporter or keep it from recording the mesh animates normally.
I’ve also tried creating a custom Alembic exporter script and use that but the same thing happens no matter what I do. I’ve tested if the Update function is called but even with the Alembic exporter this seem to be the case (it’s called throughout, so it’s not that the main thread is locked up). It’s just that its effects are no longer visible in the viewport or the Alembic file.
I’m pretty new to Unity so there’s probably a simple solution or I’m not understanding something basic about the exporter.
Here is the code for the mesh GameObject:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
public class CustomMesh : MonoBehaviour
{
private Mesh mesh;
private Vector3[] vertices;
private int[] triangles;
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
CreateShape();
UpdateMesh();
}
void CreateShape()
{
// Define vertices (positions of the mesh points)
vertices = new Vector3[]
{
new Vector3(0, 0, 0), // Vertex 0
new Vector3(0, 1, 0), // Vertex 1
new Vector3(1, 1, 0), // Vertex 2
new Vector3(1, 0, 0) // Vertex 3
};
// Define triangles (the order of vertices that make up each triangle face)
triangles = new int[]
{
0, 1, 2, // First triangle
0, 2, 3 // Second triangle
};
}
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals(); // For proper lighting
}
void Update()
{
// Example: Move vertex 0 over time
vertices[0] = new Vector3(Mathf.Sin(Time.time), 0, 0);
//Debug.Log("Update.");
// Apply changes to the mesh
UpdateMesh();
}
}
And here is the code for the Alembic exporter:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Formats.Alembic.Exporter;
public class AlembicCustomExporter : MonoBehaviour
{
public AlembicExporter alembicExporter; // Drag the exporter component here
public float exportDuration = 5f; // How long the animation is
public float frameRate = 30f; // Frames per second for export
private bool isExporting = false;
void Start()
{
// Start capturing the animation in a coroutine
StartCoroutine(CaptureAnimation());
}
IEnumerator CaptureAnimation()
{
isExporting = true;
float timePerFrame = 1f / frameRate; // Calculate time interval for each frame
float startTime = Time.time; // Track the starting time
float currentTime = 0f;
int frameCount = 0;
// Begin recording with Alembic
alembicExporter.BeginRecording();
// Loop for the duration of the export (in seconds)
while (currentTime < exportDuration)
{
// Wait for the next frame
yield return new WaitForEndOfFrame();
// Wait for the next frame time based on the frame rate
yield return new WaitForSeconds(timePerFrame);
// Update the elapsed time and frame count
currentTime = Time.time - startTime;
frameCount++;
Debug.Log($"Frame {frameCount} captured at {Time.time}s");
}
// End the recording after the duration has passed
alembicExporter.EndRecording();
isExporting = false;
Debug.Log("Alembic export completed.");
}
}