@@ -64,6 +64,9 @@ namespace Editor
64
64
65
65
public class ModelExporter : System . IDisposable
66
66
{
67
+ // To be replaced by checkbox in Fbx Export settings
68
+ bool removeAnimationsFromSkinnedMeshRenderer = true ;
69
+
67
70
const string Title =
68
71
"exports static meshes with materials and textures" ;
69
72
@@ -1267,9 +1270,23 @@ protected bool ExportInstance (GameObject unityGo, FbxNode fbxNode, FbxScene fbx
1267
1270
SharedMeshes [ unityPrefabParent . name ] = fbxNode . GetMesh ( ) ;
1268
1271
return true ;
1269
1272
}
1273
+ return false ;
1270
1274
}
1275
+
1276
+ // We don't export the mesh because we already have it from the parent, but we still need to assign the material
1277
+ var renderer = unityGo . GetComponent < Renderer > ( ) ;
1278
+ var materials = renderer ? renderer . sharedMaterials : null ;
1271
1279
1272
- if ( fbxMesh == null ) return false ;
1280
+ Unity . FbxSdk . FbxSurfaceMaterial newMaterial = null ;
1281
+ if ( materials != null )
1282
+ {
1283
+ foreach ( var mat in materials ) {
1284
+ if ( MaterialMap . TryGetValue ( mat . name , out newMaterial ) ) ;
1285
+ {
1286
+ fbxNode . AddMaterial ( newMaterial ) ;
1287
+ }
1288
+ }
1289
+ }
1273
1290
1274
1291
// set the fbxNode containing the mesh
1275
1292
fbxNode . SetNodeAttribute ( fbxMesh ) ;
@@ -1791,6 +1808,12 @@ protected void ExportAnimationClip (AnimationClip uniAnimClip, GameObject uniRoo
1791
1808
if ( ! uniGO ) {
1792
1809
continue ;
1793
1810
}
1811
+
1812
+ // Do not create the curves if the component is a SkinnedMeshRenderer and if the option in FBX Export settings is toggled on.
1813
+ if ( removeAnimationsFromSkinnedMeshRenderer && ( uniGO . GetComponent < SkinnedMeshRenderer > ( ) != null || uniGO . GetComponentInChildren < SkinnedMeshRenderer > ( ) != null ) )
1814
+ {
1815
+ continue ;
1816
+ }
1794
1817
1795
1818
int index = QuaternionCurve . GetQuaternionIndex ( uniCurveBinding . propertyName ) ;
1796
1819
if ( index >= 0 ) {
@@ -2985,6 +3008,24 @@ static void OnClipContextClick(MenuCommand command)
2985
3008
}
2986
3009
}
2987
3010
3011
+ /// <summary>
3012
+ /// Validate the menu item defined by the function OnClipContextClick.
3013
+ /// </summary>
3014
+ [ MenuItem ( TimelineClipMenuItemName , true , 31 ) ]
3015
+ static bool ValidateOnClipContextClick ( )
3016
+ {
3017
+ Object [ ] selectedObjects = Selection . objects ;
3018
+
3019
+ foreach ( Object editorClipSelected in selectedObjects )
3020
+ {
3021
+ if ( editorClipSelected . GetType ( ) . Name . Contains ( "EditorClip" ) )
3022
+ {
3023
+ return true ;
3024
+ }
3025
+ }
3026
+ return false ;
3027
+ }
3028
+
2988
3029
protected static bool ExportSingleEditorClip ( Object editorClipSelected )
2989
3030
{
2990
3031
if ( editorClipSelected . GetType ( ) . Name . Contains ( "EditorClip" ) )
@@ -3003,19 +3044,25 @@ protected static bool ExportSingleEditorClip(Object editorClipSelected)
3003
3044
return false ;
3004
3045
}
3005
3046
3006
- public static void ExportSingleTimelineClip ( TimelineClip timelineClipSelected , GameObject animationTrackGObject , string filePath = null )
3047
+ public static void ExportSingleTimelineClip ( TimelineClip timelineClipSelected , GameObject animationTrackGObject , string folderPath = null )
3007
3048
{
3008
- UnityEngine . Object [ ] myArray = new UnityEngine . Object [ ] {
3049
+
3050
+ UnityEngine . Object [ ] exportArray = new UnityEngine . Object [ ] {
3009
3051
animationTrackGObject ,
3010
3052
timelineClipSelected . animationClip
3011
3053
} ;
3012
3054
3013
3055
if ( ! string . IsNullOrEmpty ( filePath ) ) {
3014
- ExportObjects ( filePath , myArray , timelineAnim : true ) ;
3056
+ ExportObjects ( filePath , exportArray , timelineAnim : true ) ;
3015
3057
return ;
3016
3058
}
3017
3059
3018
- ExportModelEditorWindow . Init ( myArray , string . Format ( "{0}@{1}" , animationTrackGObject . name , timelineClipSelected . displayName ) , isTimelineAnim : true ) ;
3060
+ string AnimFbxFormat = "{0}@{1}" ;
3061
+ if ( timelineClipSelected . displayName . Contains ( "@" ) )
3062
+ {
3063
+ AnimFbxFormat = "{1}" ;
3064
+ }
3065
+ ExportModelEditorWindow . Init ( myArray , string . Format ( AnimFbxFormat , animationTrackGObject . name , timelineClipSelected . displayName ) , isTimelineAnim : true ) ;
3019
3066
}
3020
3067
3021
3068
/// <summary>
@@ -3075,7 +3122,7 @@ public static void ExportAllTimelineClips(GameObject objectWithPlayableDirector,
3075
3122
}
3076
3123
3077
3124
/// <summary>
3078
- /// Validate the menu item defined by the function above .
3125
+ /// Validate the menu item defined by the function OnPlayableDirectorGameObjectContextClick .
3079
3126
/// </summary>
3080
3127
[ MenuItem ( ClipMenuItemName , true , 31 ) ]
3081
3128
public static bool ValidateClipContextClick ( )
@@ -3090,7 +3137,7 @@ public static bool ValidateClipContextClick()
3090
3137
foreach ( Object obj in selection )
3091
3138
{
3092
3139
GameObject gameObj = obj as GameObject ;
3093
- if ( gameObj != null && gameObj . GetComponent < PlayableDirector > ( ) != null )
3140
+ if ( gameObj != null && gameObj . GetComponent < PlayableDirector > ( ) != null )
3094
3141
{
3095
3142
return true ;
3096
3143
}
@@ -3099,6 +3146,33 @@ public static bool ValidateClipContextClick()
3099
3146
return false ;
3100
3147
}
3101
3148
3149
+ public static void ExportAllTimelineClips ( GameObject objectWithPlayableDirector , string folderPath )
3150
+ {
3151
+ PlayableDirector pd = objectWithPlayableDirector . GetComponent < PlayableDirector > ( ) ;
3152
+ if ( pd != null )
3153
+ {
3154
+ foreach ( PlayableBinding output in pd . playableAsset . outputs )
3155
+ {
3156
+ AnimationTrack animationTrack = output . sourceObject as AnimationTrack ;
3157
+
3158
+ GameObject animationTrackObject = pd . GetGenericBinding ( output . sourceObject ) as GameObject ;
3159
+ // One file by animation clip
3160
+ foreach ( TimelineClip timelineClip in animationTrack . GetClips ( ) )
3161
+ {
3162
+ string AnimFbxFormat = AnimFbxFileFormat ;
3163
+ if ( timelineClip . displayName . Contains ( "@" ) )
3164
+ {
3165
+ AnimFbxFormat = "{0}/{2}.fbx" ;
3166
+ }
3167
+ string filePath = string . Format ( AnimFbxFormat , folderPath , animationTrackObject . name , timelineClip . displayName ) ;
3168
+
3169
+ UnityEngine . Object [ ] exportArray = new UnityEngine . Object [ ] { animationTrackObject , timelineClip . animationClip } ;
3170
+ ExportObjects ( filePath , exportArray , AnimationExportType . timelineAnimationClip ) ;
3171
+ }
3172
+ }
3173
+ }
3174
+ }
3175
+
3102
3176
/// <summary>
3103
3177
/// Add a menu item "Export Model..." to a GameObject's context menu.
3104
3178
/// </summary>
@@ -3114,7 +3188,7 @@ static void OnContextItem (MenuCommand command)
3114
3188
}
3115
3189
3116
3190
/// <summary>
3117
- /// Validate the menu item defined by the function above .
3191
+ /// Validate the menu item defined by the function OnContextItem .
3118
3192
/// </summary>
3119
3193
[ MenuItem ( MenuItemName , true , 30 ) ]
3120
3194
public static bool OnValidateMenuItem ( )
@@ -3123,7 +3197,7 @@ public static bool OnValidateMenuItem ()
3123
3197
}
3124
3198
3125
3199
/// <summary>
3126
- /// Validate the menu item defined by the function above .
3200
+ /// Validate the menu item defined by the function ModelOnlyOnContextItem .
3127
3201
/// </summary>
3128
3202
[ MenuItem ( ModelOnlyMenuItemName , true , 30 ) ]
3129
3203
public static bool ModelOnlyOnValidateMenuItem ( )
@@ -3137,7 +3211,23 @@ public static bool ModelOnlyOnValidateMenuItem ()
3137
3211
[ MenuItem ( AnimOnlyMenuItemName , true , 30 ) ]
3138
3212
public static bool OnValidateAnimOnlyMenuItem ( )
3139
3213
{
3140
- return true ;
3214
+ Object [ ] selection = Selection . objects ;
3215
+
3216
+ if ( selection == null || selection . Length == 0 )
3217
+ {
3218
+ return false ;
3219
+ }
3220
+
3221
+ foreach ( Object obj in selection )
3222
+ {
3223
+ GameObject gameObj = obj as GameObject ;
3224
+ if ( gameObj != null && ( gameObj . GetComponent < Animation > ( ) != null || gameObj . GetComponent < Animator > ( ) != null ) )
3225
+ {
3226
+ return true ;
3227
+ }
3228
+ }
3229
+
3230
+ return false ;
3141
3231
}
3142
3232
3143
3233
public static void DisplayNoSelectionDialog ( )
0 commit comments