在unity中导入fbx是个跟简单的事,只需要把fbx放到unity的项目文件夹下,它就能自动识别并读取了,但是在unity运行的过程中输出fbx却相当麻烦。因为工作项目的需求,需要把场景中的物体在运行时导出成fbx,所以对这个功能进行了研究,在unity商店也有一些导出的插件,但是基本都是只限于基本的几何体导出,要不就是不支持skinned mesh,要不就是不支持blendshape。因为这个项目的需求是需要把动作捕捉和面部捕捉的数据,写入到模型中并导出到fbx,所以也基本都不能满足需求,那就只能自己从头开始研究了。

要写fbx文件,就需要对fbx文件进行研究,简单来说fbx文件是类似于json结构的一种文件,首先是该fbx文件的基本信息,包括fbx版本,作者,标题、单位信息以及坐标系统信息。

 fbxExpter.SetFileExportVersion("FBX201400");fbxExpter.SetProgressCallback(fbxProgressCallback);FbxScene fbxScene = FbxScene.Create(fbxMgr, "Scene");FbxDocumentInfo fbxDocInfo = FbxDocumentInfo.Create(fbxMgr, "SceneInfo");fbxDocInfo.mTitle = "exports static meshes with materials and textures";fbxDocInfo.mSubject = "";fbxDocInfo.mAuthor = "bytework";fbxDocInfo.mRevision = "1.0";fbxDocInfo.mKeywords = "export mesh materials textures uvs";fbxDocInfo.mComment = "";fbxDocInfo.Original_ApplicationName.Set(string.Format("Unity {0}", "FBX Exporter"));fbxDocInfo.LastSaved_ApplicationName.Set(fbxDocInfo.Original_ApplicationName.Get());//fbxDocInfo.Original_ApplicationVersion.Set("1.0");fbxDocInfo.LastSaved_ApplicationVersion.Set(fbxDocInfo.Original_ApplicationVersion.Get());
fbxScene.SetSceneInfo(fbxDocInfo);
FbxGlobalSettings globalSettings = fbxScene.GetGlobalSettings();
globalSettings.SetSystemUnit(FbxSystemUnit.cm);
globalSettings.SetAxisSystem(FbxAxisSystem.MayaYUp);

然后是一个list类似的树状结构,每个根节点记录了该物体的名称,然后是子节点,一个物体包括多个子节点,包括mesh renderer,transform等节点信息,节点信息里有属性等细节信息。

要写fbx文件,首先就是fbx sdk的封装,Autodesk官网提供了fbx的核心sdk,但是是c++版本的,需要对它进行一次C#封装,封装完之后就是unity端,c#导出脚本的编写了,我们要把unity的物体导出为fbx就需要把unity物体的每个组件都转换为fbx格式的组件,然后再写入fbx文件。这就需要我们手动对每个组件进行一次转换。例如unity中的Vector3,对应fbx中的就是FbxDouble3,unity中物体的旋转就是一个四元数,对应fbx的FbxQuaternion 。unity中的AnimationCurve 对应fbx中的FbxAnimCurve等。

sdk封装和转换脚本写完后就可以进行实际的导出了,流程就是首先获取unity场景中的一个物体,然后获取该物体的所有子物体,对这些物体按找层级关系,写入一个fbxnode,节点名字就是物体名字,然后输出每个物体的Tranform组件,将其写入fbx中,因为每个物体都必定会有这个节点。

public static FbxVector4 ConvertQuaternionToXYZEuler(FbxQuaternion quat)
    {
        FbxAMatrix val = new FbxAMatrix();
        val.SetQ(quat);
        FbxVector4 r = val.GetR();
        return new FbxVector4(r.X, 0.0 - r.Y, 0.0 - r.Z, r.W);
    }

protected bool ExportTransform(Transform unityTransform, FbxNode fbxNode, Vector3 newCenter, TransformExportType exportType){fbxNode.SetRotationOrder((FbxNode.EPivotSet)0, (FbxEuler.EOrder)0);Vector3 leftHandedVector;FbxDouble3 val = default(FbxDouble3);Vector3 val2;switch (exportType){case TransformExportType.Reset:leftHandedVector = Vector3.zero;val = new FbxDouble3(0.0);val2 = Vector3.one;break;case TransformExportType.Global:leftHandedVector = GetRecenteredTranslation(unityTransform, newCenter);val = ConvertQuaternionToXYZEuler(unityTransform.rotation);val2 = unityTransform.lossyScale;break;default:leftHandedVector = unityTransform.localPosition;val = ConvertQuaternionToXYZEuler(unityTransform.localRotation);val2 = unityTransform.localScale;break;}FbxVector4 val3 = ConvertToRightHanded(leftHandedVector, 100f);FbxDouble3 val4 = default(FbxDouble3);val4 = new FbxDouble3(val2.x, val2.y, val2.z);fbxNode.LclTranslation.Set(new FbxDouble3(val3.X, val3.Y, val3.Z));fbxNode.LclRotation.Set(val);fbxNode.LclScaling.Set(val4);return true;}

如果这个物体是空物体,那么这个物体就导出成功了。接着再次循环物体,得到每个物体独有的组件,将其写入对应fbx节点。

例如下面的代码就是导出材质球的颜色的方法

public FbxDouble3 GetMaterialColor(Material unityMaterial, string unityPropName, float defaultValue = 1f)
    {
        if (!unityMaterial)
        {
            return new FbxDouble3(defaultValue);
        }
        if (!unityMaterial.HasProperty(unityPropName))
        {
            return new FbxDouble3(defaultValue);
        }
        Color color = unityMaterial.GetColor(unityPropName);
        return new FbxDouble3(color.r, color.g, color.b);
    }

通过上述的循环完成后,一个完整的fbx文件也就导出来了。有什么问题欢迎大家交流,如果有类似需求的也可以交流合作。q2609087666

Unity运行时输出场景物体及角色为fbx文件相关推荐

  1. #汇编语言字符串的输出(dosbox运行时输出乱码问题解决)

    #汇编语言字符串的输出 dosbox运行时输出乱码,经过检查发现在定义字符串时忘记在后面加上$字符 代码一· ;This is the structure of a main module using ...

  2. 编写一个C程序,运行时输出以下图形:

    编写一个C程序,运行时输出以下图形: **** **** ​ **** ​ **** 代码示例: #include <stdio.h>int main() {for (int i = 0; ...

  3. 【Lua运行时热重载功能实现①】检测Lua文件发生变化

    这几天由于项目组需要一直在琢磨一个功能,就是如何在unity编辑器下不需要重启游戏就能让lua文件改动后立刻生效.如果能够实现这个功能,那会大幅提高开发效率.查了一圈,网上的结果都不太满意,要么只有理 ...

  4. 【Unity3D插件】RuntimeTransformGizmos插件分享《Unity运行时控制模型插件》

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 一.前文   Runtime Transform Gizmos看名字顾名思义 ...

  5. Unity运行时检测Altas使用情况

    UI贴图在游戏中内存大小中占的分量非常非常大,尤其对于前期对UI没有规划的项目,无论是包量还是内存大小都是需要花费很多时间去优化.如果涉及到战斗场景和逻辑场景的情况下,常用的做法就是把两个场景使用的a ...

  6. 把Hybris安装时输出的日志重定向到一个本地文件中

    我在本地安装Hybris时遇到一些错误,我想把输出的信息保存到一个本地文件里: [java] de.hybris.platform.core.UninstantiableCoreApplication ...

  7. C专家编程 第6章 运动的诗章:运行时数据结构 6.3 操作系统在a.out文件里干了些什么

    操作系统在a.out文件里干了些什么      为什么a.out要以段的形式组织.段可以方便地映射到链接器在运行时可以直接载入的对象中!载入器只是取文件中的每个段的映像,并直接将它们放入到内存中.从本 ...

  8. Unity与3ds Max的单位关系(使用FBX文件)

      游戏引擎通常并不具备专业的建模功能,所以通常情况下模型都是在专业的三维软件中进行设计,然后再通过特定格式的文件导入到游戏引擎中进行游戏开发.Unity支持多种外部导入的模型格式,如FBX.3ds. ...

  9. unity 运行时的工具栏作用

    这个干啥用的? 第一个 是摄像机里用的 第二个 分辨率 你做ugui的时候 背景也会显示一个和这个大小一样的框 VSync 是垂直同步 防止画面撕裂 录视频的时候可以开启 这个是运行的时候 自动ide ...

  10. unity运行过程中销毁物体导致引用缺失

    MissingReferenceException: The object of type 'MonsterFish' has been destroyed but you are still try ...

最新文章

  1. java为什么实现_为什么在java中这样实现了这样的实现?
  2. 删除指定文件夹下的小于 4K的所用文件...
  3. python字符串写入excel-python-xlwt写入excel详解
  4. 官网拉取fuchsia代码
  5. cache目录没有权限
  6. Spring MVC DispatcherServlet介绍(2)
  7. 【解题报告】Leecode 500. 键盘行——Leecode每日一题系列
  8. windows 2008 server NTP Server
  9. ajax长链接--拉实现
  10. Netapp日志出现auth.dc.trace.DCConnection.errorMsg:error报错
  11. MySQL高级-MySQL应用优化
  12. 集团公司(嵌入ETL工具)财务报表系统解决方案
  13. 浅谈UWB室内定位(一)_vortex_新浪博客
  14. 如何在20130513image上,备份NAND到SD卡,然后把这个SD卡做成可以自启动的SD卡
  15. Control Flow - Containers
  16. python写透视挂_python – OpenCV透视变换给出了意想不到的结果
  17. 大数据入门介绍和学习路线
  18. php ziparchive类,PHP Zip ZipArchive 类_编程学问网
  19. Linux安装GO语言环境
  20. POI 导出 Excel:字体颜色、行列自适应、锁住、合并单元格、一文搞定……

热门文章

  1. hill密码 java_希尔密码(Hill Cipher)的实现
  2. xmind8 下载安装与破解激活
  3. uploader.php,使用uploader上传拍摄的图片php后端代码出错~求助~
  4. GAN网络笔记 MATLAB实现
  5. 必看 | 机器视觉基础入门
  6. 搜罗到一个简洁、支持免费听和下载全网音乐的网站
  7. 阿里云搭建WordPress系统
  8. 关于CMOS摄像头的DVP接口的工作方式与一般使用方法
  9. 用于检测未知恶意软件的深度学习方法
  10. Unity粒子特效系列-毒液喷射预制体做好了,unitypackage包直接用 -下