@@ -86,7 +86,7 @@ public class ModelExporter : System.IDisposable
86
86
const string ClipMenuItemName = "GameObject/Export All Timeline Clips..." ;
87
87
const string TimelineClipMenuItemName = "GameObject/Export Selected Timeline Clip..." ;
88
88
89
- const string AnimOnlyMenuItemName = "GameObject/Export Animation Only" ;
89
+ const string AnimOnlyMenuItemName = "GameObject/Export Animation Only... " ;
90
90
91
91
const string FileBaseName = "Untitled" ;
92
92
@@ -189,6 +189,11 @@ public enum FbxNodeRelationType
189
189
/// </summary>
190
190
const string UniqueNameFormat = "{0}_{1}" ;
191
191
192
+ /// <summary>
193
+ /// The animation fbx file format.
194
+ /// </summary>
195
+ const string AnimFbxFileFormat = "{0}/{1}@{2}.fbx" ;
196
+
192
197
/// <summary>
193
198
/// Gets the export settings.
194
199
/// </summary>
@@ -1238,7 +1243,8 @@ protected bool ExportInstance (GameObject unityGo, FbxNode fbxNode, FbxScene fbx
1238
1243
{
1239
1244
PrefabType unityPrefabType = PrefabUtility . GetPrefabType ( unityGo ) ;
1240
1245
1241
- if ( unityPrefabType != PrefabType . PrefabInstance ) return false ;
1246
+ if ( unityPrefabType != PrefabType . PrefabInstance &&
1247
+ unityPrefabType != PrefabType . ModelPrefabInstance ) return false ;
1242
1248
1243
1249
Object unityPrefabParent = PrefabUtility . GetPrefabParent ( unityGo ) ;
1244
1250
@@ -1530,8 +1536,8 @@ protected void ExportAnimationCurve (UnityEngine.Object uniObj,
1530
1536
Debug . Log ( "Exporting animation for " + uniObj . ToString ( ) + " (" + uniPropertyName + ")" ) ;
1531
1537
}
1532
1538
1533
- FbxPropertyChannelPair fbxPropertyChannelPair ;
1534
- if ( ! FbxPropertyChannelPair . TryGetValue ( uniPropertyName , out fbxPropertyChannelPair ) ) {
1539
+ FbxPropertyChannelPair [ ] fbxPropertyChannelPairs ;
1540
+ if ( ! FbxPropertyChannelPair . TryGetValue ( uniPropertyName , out fbxPropertyChannelPairs ) ) {
1535
1541
Debug . LogWarning ( string . Format ( "no mapping from Unity '{0}' to fbx property" , uniPropertyName ) ) ;
1536
1542
return ;
1537
1543
}
@@ -1549,39 +1555,35 @@ protected void ExportAnimationCurve (UnityEngine.Object uniObj,
1549
1555
return ;
1550
1556
}
1551
1557
1552
- // map unity property name to fbx property
1553
- var fbxProperty = fbxNode . FindProperty ( fbxPropertyChannelPair . Property , false ) ;
1554
- if ( ! fbxProperty . IsValid ( ) )
1555
- {
1556
- var fbxNodeAttribute = fbxNode . GetNodeAttribute ( ) ;
1557
- if ( fbxNodeAttribute != null )
1558
- {
1559
- fbxProperty = fbxNodeAttribute . FindProperty ( fbxPropertyChannelPair . Property , false ) ;
1558
+ foreach ( var fbxPropertyChannelPair in fbxPropertyChannelPairs ) {
1559
+ // map unity property name to fbx property
1560
+ var fbxProperty = fbxNode . FindProperty ( fbxPropertyChannelPair . Property , false ) ;
1561
+ if ( ! fbxProperty . IsValid ( ) ) {
1562
+ var fbxNodeAttribute = fbxNode . GetNodeAttribute ( ) ;
1563
+ if ( fbxNodeAttribute != null ) {
1564
+ fbxProperty = fbxNodeAttribute . FindProperty ( fbxPropertyChannelPair . Property , false ) ;
1565
+ }
1566
+ }
1567
+ if ( ! fbxProperty . IsValid ( ) ) {
1568
+ Debug . LogError ( string . Format ( "no fbx property {0} found on {1} node or nodeAttribute " , fbxPropertyChannelPair . Property , fbxNode . GetName ( ) ) ) ;
1569
+ return ;
1560
1570
}
1561
- }
1562
- if ( ! fbxProperty . IsValid ( ) )
1563
- {
1564
- Debug . LogError ( string . Format ( "no fbx property {0} found on {1} node or nodeAttribute " , fbxPropertyChannelPair . Property , fbxNode . GetName ( ) ) ) ;
1565
- return ;
1566
- }
1567
1571
1568
- // Create the AnimCurve on the channel
1569
- FbxAnimCurve fbxAnimCurve = fbxProperty . GetCurve ( fbxAnimLayer , fbxPropertyChannelPair . Channel , true ) ;
1572
+ // Create the AnimCurve on the channel
1573
+ FbxAnimCurve fbxAnimCurve = fbxProperty . GetCurve ( fbxAnimLayer , fbxPropertyChannelPair . Channel , true ) ;
1570
1574
1571
- // create a convert scene helper so that we can convert from Unity to Maya
1572
- // AxisSystem (LeftHanded to RightHanded) and FBX's default units
1573
- // (Meters to Centimetres)
1574
- var convertSceneHelper = new UnityToMayaConvertSceneHelper ( uniPropertyName ) ;
1575
+ // create a convert scene helper so that we can convert from Unity to Maya
1576
+ // AxisSystem (LeftHanded to RightHanded) and FBX's default units
1577
+ // (Meters to Centimetres)
1578
+ var convertSceneHelper = new UnityToMayaConvertSceneHelper ( uniPropertyName ) ;
1575
1579
1576
- // TODO: we'll resample the curve so we don't have to
1577
- // configure tangents
1578
- if ( ModelExporter . ExportSettings . BakeAnimation )
1579
- {
1580
- ExportAnimationSamples ( uniAnimCurve , fbxAnimCurve , frameRate , convertSceneHelper ) ;
1581
- }
1582
- else
1583
- {
1584
- ExportAnimationKeys ( uniAnimCurve , fbxAnimCurve , convertSceneHelper ) ;
1580
+ // TODO: we'll resample the curve so we don't have to
1581
+ // configure tangents
1582
+ if ( ModelExporter . ExportSettings . BakeAnimation ) {
1583
+ ExportAnimationSamples ( uniAnimCurve , fbxAnimCurve , frameRate , convertSceneHelper ) ;
1584
+ } else {
1585
+ ExportAnimationKeys ( uniAnimCurve , fbxAnimCurve , convertSceneHelper ) ;
1586
+ }
1585
1587
}
1586
1588
}
1587
1589
@@ -1636,75 +1638,78 @@ public FbxPropertyChannelPair(string p, string c):this() {
1636
1638
/// Map a Unity property name to the corresponding FBX property and
1637
1639
/// channel names.
1638
1640
/// </summary>
1639
- public static bool TryGetValue ( string uniPropertyName , out FbxPropertyChannelPair prop )
1641
+ public static bool TryGetValue ( string uniPropertyName , out FbxPropertyChannelPair [ ] prop )
1640
1642
{
1641
1643
System . StringComparison ct = System . StringComparison . CurrentCulture ;
1642
1644
1643
1645
// Transform Scaling
1644
1646
if ( uniPropertyName . StartsWith ( "m_LocalScale.x" , ct ) || uniPropertyName . EndsWith ( "S.x" , ct ) ) {
1645
- prop = new FbxPropertyChannelPair ( "Lcl Scaling" , Globals . FBXSDK_CURVENODE_COMPONENT_X ) ;
1647
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Lcl Scaling" , Globals . FBXSDK_CURVENODE_COMPONENT_X ) } ;
1646
1648
return true ;
1647
1649
}
1648
1650
if ( uniPropertyName . StartsWith ( "m_LocalScale.y" , ct ) || uniPropertyName . EndsWith ( "S.y" , ct ) ) {
1649
- prop = new FbxPropertyChannelPair ( "Lcl Scaling" , Globals . FBXSDK_CURVENODE_COMPONENT_Y ) ;
1651
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Lcl Scaling" , Globals . FBXSDK_CURVENODE_COMPONENT_Y ) } ;
1650
1652
return true ;
1651
1653
}
1652
1654
if ( uniPropertyName . StartsWith ( "m_LocalScale.z" , ct ) || uniPropertyName . EndsWith ( "S.z" , ct ) ) {
1653
- prop = new FbxPropertyChannelPair ( "Lcl Scaling" , Globals . FBXSDK_CURVENODE_COMPONENT_Z ) ;
1655
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Lcl Scaling" , Globals . FBXSDK_CURVENODE_COMPONENT_Z ) } ;
1654
1656
return true ;
1655
1657
}
1656
1658
1657
1659
// Transform Translation
1658
1660
if ( uniPropertyName . StartsWith ( "m_LocalPosition.x" , ct ) || uniPropertyName . EndsWith ( "T.x" , ct ) ) {
1659
- prop = new FbxPropertyChannelPair ( "Lcl Translation" , Globals . FBXSDK_CURVENODE_COMPONENT_X ) ;
1661
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Lcl Translation" , Globals . FBXSDK_CURVENODE_COMPONENT_X ) } ;
1660
1662
return true ;
1661
1663
}
1662
1664
if ( uniPropertyName . StartsWith ( "m_LocalPosition.y" , ct ) || uniPropertyName . EndsWith ( "T.y" , ct ) ) {
1663
- prop = new FbxPropertyChannelPair ( "Lcl Translation" , Globals . FBXSDK_CURVENODE_COMPONENT_Y ) ;
1665
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Lcl Translation" , Globals . FBXSDK_CURVENODE_COMPONENT_Y ) } ;
1664
1666
return true ;
1665
1667
}
1666
1668
if ( uniPropertyName . StartsWith ( "m_LocalPosition.z" , ct ) || uniPropertyName . EndsWith ( "T.z" , ct ) ) {
1667
- prop = new FbxPropertyChannelPair ( "Lcl Translation" , Globals . FBXSDK_CURVENODE_COMPONENT_Z ) ;
1669
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Lcl Translation" , Globals . FBXSDK_CURVENODE_COMPONENT_Z ) } ;
1668
1670
return true ;
1669
1671
}
1670
1672
1671
1673
if ( uniPropertyName . StartsWith ( "m_Intensity" , ct ) )
1672
1674
{
1673
- prop = new FbxPropertyChannelPair ( "Intensity" , null ) ;
1675
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Intensity" , null ) } ;
1674
1676
return true ;
1675
1677
}
1676
1678
1677
1679
if ( uniPropertyName . StartsWith ( "m_SpotAngle" , ct ) )
1678
1680
{
1679
- prop = new FbxPropertyChannelPair ( "OuterAngle" , null ) ;
1681
+ prop = new FbxPropertyChannelPair [ ] {
1682
+ new FbxPropertyChannelPair ( "OuterAngle" , null ) ,
1683
+ new FbxPropertyChannelPair ( "InnerAngle" , null )
1684
+ } ;
1680
1685
return true ;
1681
1686
}
1682
1687
1683
1688
if ( uniPropertyName . StartsWith ( "m_Color.r" , ct ) )
1684
1689
{
1685
- prop = new FbxPropertyChannelPair ( "Color" , Globals . FBXSDK_CURVENODE_COLOR_RED ) ;
1690
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Color" , Globals . FBXSDK_CURVENODE_COLOR_RED ) } ;
1686
1691
return true ;
1687
1692
}
1688
1693
1689
1694
if ( uniPropertyName . StartsWith ( "m_Color.g" , ct ) )
1690
1695
{
1691
- prop = new FbxPropertyChannelPair ( "Color" , Globals . FBXSDK_CURVENODE_COLOR_GREEN ) ;
1696
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Color" , Globals . FBXSDK_CURVENODE_COLOR_GREEN ) } ;
1692
1697
return true ;
1693
1698
}
1694
1699
1695
1700
if ( uniPropertyName . StartsWith ( "m_Color.b" , ct ) )
1696
1701
{
1697
- prop = new FbxPropertyChannelPair ( "Color" , Globals . FBXSDK_CURVENODE_COLOR_BLUE ) ;
1702
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "Color" , Globals . FBXSDK_CURVENODE_COLOR_BLUE ) } ;
1698
1703
return true ;
1699
1704
}
1700
1705
1701
1706
if ( uniPropertyName . StartsWith ( "field of view" , ct ) )
1702
1707
{
1703
- prop = new FbxPropertyChannelPair ( "FieldOfView" , null ) ;
1708
+ prop = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( "FieldOfView" , null ) } ;
1704
1709
return true ;
1705
1710
}
1706
1711
1707
- prop = new FbxPropertyChannelPair ( ) ;
1712
+ prop = new FbxPropertyChannelPair [ ] { } ;
1708
1713
return false ;
1709
1714
}
1710
1715
}
@@ -2813,7 +2818,7 @@ public int ExportAll (
2813
2818
2814
2819
Vector3 center = Vector3 . zero ;
2815
2820
if ( exportType == TransformExportType . Global ) {
2816
- center = ExportSettings . centerObjects ? FindCenter ( revisedExportSet ) : Vector3 . zero ;
2821
+ center = ( ExportSettings . centerObjects && revisedExportSet . Count > 1 ) ? FindCenter ( revisedExportSet ) : Vector3 . zero ;
2817
2822
}
2818
2823
2819
2824
foreach ( var unityGo in revisedExportSet ) {
@@ -2950,12 +2955,10 @@ static void OnClipContextClick(MenuCommand command)
2950
2955
{
2951
2956
if ( obj . GetType ( ) . Name . Contains ( "EditorClip" ) )
2952
2957
{
2953
- var selClip = obj . GetType ( ) . GetProperty ( "clip" ) . GetValue ( obj , null ) ;
2954
- UnityEngine . Timeline . TimelineClip timeLineClip = selClip as UnityEngine . Timeline . TimelineClip ;
2958
+ var timeLineClip = GetPropertyFromObject < TimelineClip > ( obj , "clip" ) ;
2955
2959
2956
- var selClipItem = obj . GetType ( ) . GetProperty ( "item" ) . GetValue ( obj , null ) ;
2957
- var selClipItemParentTrack = selClipItem . GetType ( ) . GetProperty ( "parentTrack" ) . GetValue ( selClipItem , null ) ;
2958
- AnimationTrack editorClipAnimationTrack = selClipItemParentTrack as AnimationTrack ;
2960
+ var selClipItem = GetPropertyFromObject < object > ( obj , "item" ) ;
2961
+ var editorClipAnimationTrack = GetPropertyFromObject < AnimationTrack > ( selClipItem , "parentTrack" ) ;
2959
2962
2960
2963
GameObject animationTrackGObject = UnityEditor . Timeline . TimelineEditor . playableDirector . GetGenericBinding ( editorClipAnimationTrack ) as GameObject ;
2961
2964
@@ -2972,6 +2975,10 @@ static void OnClipContextClick(MenuCommand command)
2972
2975
}
2973
2976
}
2974
2977
2978
+ private static T GetPropertyFromObject < T > ( object obj , string propertyName ) where T : class {
2979
+ return obj . GetType ( ) . GetProperty ( propertyName ) . GetValue ( obj , null ) as T ;
2980
+ }
2981
+
2975
2982
/// <summary>
2976
2983
/// Add an option "Export all Timeline clips" in the contextual GameObject menu.
2977
2984
/// </summary>
@@ -3020,7 +3027,7 @@ static void OnGameObjectWithTimelineContextClick(MenuCommand command)
3020
3027
GameObject atObject = pd . GetGenericBinding ( output . sourceObject ) as GameObject ;
3021
3028
// One file by animation clip
3022
3029
foreach ( TimelineClip timeLineClip in at . GetClips ( ) ) {
3023
- string filePath = folderPath + "/" + atObject . name + "@" + timeLineClip . animationClip . name + ".fbx" ;
3030
+ string filePath = string . Format ( AnimFbxFileFormat , folderPath , atObject . name , timeLineClip . animationClip . name ) ;
3024
3031
UnityEngine . Object [ ] myArray = new UnityEngine . Object [ ] { atObject , timeLineClip . animationClip } ;
3025
3032
ExportObjects ( filePath , myArray , AnimationExportType . timelineAnimationClip ) ;
3026
3033
@@ -3484,6 +3491,13 @@ bool ExportMesh (GameObject gameObject, FbxNode fbxNode)
3484
3491
3485
3492
// If we're here, custom handling didn't work.
3486
3493
// Revert to default handling.
3494
+
3495
+ // if user doesn't want to export mesh colliders, and this gameobject doesn't have a renderer
3496
+ // then don't export it.
3497
+ if ( ! ExportSettings . instance . exportMeshNoRenderer && ! gameObject . GetComponent < Renderer > ( ) ) {
3498
+ return false ;
3499
+ }
3500
+
3487
3501
var meshFilter = defaultComponent as MeshFilter ;
3488
3502
if ( meshFilter ) {
3489
3503
var renderer = gameObject . GetComponent < Renderer > ( ) ;
0 commit comments