You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中使用Alembic Exporter导出时动态网格冻结问题求助

Unity代码驱动Mesh导出Alembic冻结问题解决方案

问题根源

Unity Alembic Exporter默认仅捕获静态Mesh数据或通过Animator/AnimationClip驱动的动画。直接在Update中修改Mesh顶点时,若未正确标记Mesh为动态、未更新Mesh边界,或导出器设置为仅抓取初始状态,导出器会无法追踪后续的Mesh修改,导致录制时网格冻结在初始帧。


解决方案

1. 修改CustomMesh脚本,确保Mesh动态更新被追踪

在Start中标记Mesh为动态,同时优化UpdateMesh方法,避免重置整个Mesh,确保导出器能感知顶点变化:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CustomMesh : MonoBehaviour
{
    private Mesh mesh;
    private Vector3[] vertices;
    private int[] triangles;

    void Start()
    {
        mesh = new Mesh();
        GetComponent<MeshFilter>().mesh = mesh;
        mesh.MarkDynamic(); // 关键:标记Mesh为动态,告知Unity会频繁更新
        
        CreateShape();
        UpdateMesh();
    }

    void CreateShape()
    {
        vertices = new Vector3[]
        {
            new Vector3(0, 0, 0),
            new Vector3(0, 1, 0),
            new Vector3(1, 1, 0),
            new Vector3(1, 0, 0)
        };

        triangles = new int[]
        {
            0, 1, 2,
            0, 2, 3
        };
        // 只在初始化时赋值三角形,后续拓扑不变无需重复设置
        mesh.triangles = triangles;
    }

    void UpdateMesh()
    {
        // 无需Clear,直接更新顶点
        mesh.SetVertices(vertices); // 比直接赋值更高效,适合动态更新
        mesh.RecalculateNormals();
        mesh.RecalculateBounds(); // 必须更新边界,确保导出器捕捉到变化
    }

    void Update()
    {
        vertices[0] = new Vector3(Mathf.Sin(Time.time), 0, 0);
        UpdateMesh();
    }
}

2. 调整Alembic Exporter组件设置

在Inspector面板中修改AlembicExporter的参数:

  • Capture Type:选择GameObject(单个对象)或Hierarchy(多个对象)
  • Capture Mesh:设置为Every Frame(默认是Once,仅抓取初始状态)
  • Dynamic Objects:勾选该选项,确保动态修改的对象被正确录制
  • Topology:保持Static(你的动画仅顶点移动,拓扑未变化)

3. 修正自定义导出脚本的帧同步逻辑

原脚本的等待逻辑会导致帧不同步,改用Time.captureFramerate强制Unity以目标帧率运行,确保导出帧与Mesh更新完全同步:

using System.Collections;
using UnityEngine;
using UnityEngine.Formats.Alembic.Exporter;

public class AlembicCustomExporter : MonoBehaviour
{
    public AlembicExporter alembicExporter;
    public float exportDuration = 5f;
    public float frameRate = 30f;

    private bool isExporting = false;
    
    void Start()
    {
        StartCoroutine(CaptureAnimation());
    }

    IEnumerator CaptureAnimation()
    {
        isExporting = true;
        // 保存原帧率,导出后恢复
        int originalCaptureFramerate = Time.captureFramerate;
        Time.captureFramerate = (int)frameRate; // 强制Unity以目标帧率运行

        float startTime = Time.realtimeSinceStartup;
        alembicExporter.BeginRecording();

        // 按实际运行时间控制导出时长
        while (Time.realtimeSinceStartup - startTime < exportDuration)
        {
            yield return new WaitForEndOfFrame();
            Debug.Log($"已捕获帧:{Time.frameCount},时间:{Time.time}s");
        }

        alembicExporter.EndRecording();
        Time.captureFramerate = originalCaptureFramerate;
        isExporting = false;
        Debug.Log("Alembic导出完成");
    }
}

内容的提问来源于stack exchange,提问作者Rolf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:23:10