I got tired of constantly moving objects to 0 0 0 to export for UDK and remembering to do a few other things like triangulate the model and rename the material, so I wrote this maxscript.
With one button "FBXport" does:- Records the objects current position.
- Moves it to 0 0 0.
- Triangulates the model by adding a turn to poly modifier set to 3 sides.
- Renames the material to match the object name.
- Triggers the FBX export and sends it to a new folder called "Exports" which is in the same place as your max file.
- Moves the object back to its original position.
![](https://us.v-cdn.net/5021068/uploads/editor/rs/1pqe448nozrb.gif)
How To Install:Open max and go Main Menu > Maxscript > Run script > FBXport.ms
It can now be found in Main Menu > Customize > Category: VigTools
From there you can assign it to a keyboard shortcut, toolbar or quad menu.
You can also drag the main body of the script (below) into your tool bar to make a button.
You can then right click that button and change its appearance.
macroScript FBXport
Category:"VigTools"
toolTip:"FBXport"
buttonText:"FBXport"
(
ClearListener()
gc()
Global UnrealDisplayName
Global ForceNameState
Global TriangulateState
Global UnrealPath = (maxFilePath + "\\FBX\\")
Global Roll_FBXport
Try (
cui.unRegisterDialogBar Roll_FBXport
Destroydialog Roll_FBXport
)
catch()
fn WriteINI = (
idxname = ((getdir #userscripts) + "\\FBXport.ini")
idxfile = createfile idxname
format (UnrealPath as string + "\n") to:idxfile
format (ForceNameState as string + "\n") to:idxfile
format (TriangulateState as string + "\n") to:idxfile
format (UnrealDisplayname as string + "\n") to: idxfile
close idxfile
)
fn ReadINI = (
if doesFileExist ((getdir #userscripts) + "\\FBXport.ini") == false then (
print "ReadINI was FALSE"
UnrealPath = "Please Set Path"
ForceNameState = false
TriangulateState = false
UnrealDisplayname = "None"
return false
)
else (
ClearListener()
Print "ReadINI was Success"
idxname = openfile ((getdir #userscripts) + "\\FBXport.ini") mode:"r"
while not eof idxname do (
UnrealPath = readLine idxname as string
ForceNameState = readLine idxname as string
TriangulateState = readLine idxname as string
UnrealDisplayName = readLine idxname as string
)
close idxname
return true
)
)
ReadINI()
fn ERRORSetProjectPath = messagebox "Project path needs to be set first." Title: "INI READ ERROR"
rollout Roll_FBXport "FBXport v1.04" width:280 height:33
(
edittext edt_UnrealPath "" pos:[47,7] width:136 height:16
button btn_UnrealPath "..." pos:[186,7] width:24 height:16
checkbox Chk_Triangulate "Tri?" pos:[6,16] width:41 height:16
checkbox chk_forceName "Mat?" pos:[6,0] width:41 height:16
button btn_export "Export" pos:[215,4] width:56 height:24
fn Refresh = (
ReadINI()
UnrealDisplayName = ((pathConfig.stripPathToLeaf UnrealPath + "\\FBX\\"))
edt_UnrealPath.text = ("...\\" + UnrealDisplayName as string)
if ForceNameState == "true" then (Chk_ForceName.state = true) else (Chk_ForceName.state = false)
if TriangulateState == "true" then (Chk_Triangulate.state = true) else (Chk_Triangulate.state = false)
)
on Roll_FBXport open do (
Refresh()
)
on edt_UnrealPath changed txt do (
UnrealPath = edt_UnrealPath.text
edt_UnrealPath.text = UnrealPath
)
on btn_UnrealPath pressed do (
if UnrealPath == undefined then (
UnrealPath = (getSavePath caption:(("Select UNREAL Project Path:" + "\n\nExample: ...\My Documents\Unreal Projects\My Project") as string) initialDir:(((dotNetClass "System.Environment").GetEnvironmentVariable "UserProfile") + "\\Documents"))
)
else (
UnrealPath = (getSavePath caption:(("Select UNREAL Project Path:" + "\n\nExample: ...\My Documents\Unreal Projects\My Project") as string) initialDir:(UnrealPath))
UnrealDisplayName = ((pathConfig.stripPathToLeaf UnrealPath + "\\FBX\\"))
)
edt_UnrealPath.text = UnrealDisplayName
WriteINI()
Refresh()
)
on btn_UnrealPath rightClick do
(shellLaunch "explorer.exe" (UnrealPath + "\\FBX\\"))
on Chk_Triangulate changed arg do (
if MyProjectPath == "Please Set Path" then (
Refresh()
ERRORSetProjectPath()
)
Else (
TriangulateState = Chk_Triangulate.state
WriteINI()
ReadINI()
if TriangulateState == "true" then (Chk_Triangulate.state = true) else (Chk_Triangulate.state = false)
)
)
on chk_forceName changed arg do (
if MyProjectPath == "Please Set Path" then (
Refresh()
ERRORSetProjectPath()
)
Else (
ForceNameState = chk_forceName.state
WriteINI()
ReadINI()
if ForceNameState == "true" then (Chk_ForceName.state = true) else (Chk_ForceName.state = false)
)
)
on btn_export pressed do (
Cursel = selection as array
For i=1 to cursel.count do (
Select CurSel[i]
curObject = $
curObjectName = $.name
curObjectPos = curObject.position
exportpath = (UnrealPath + "\\FBX\\" + "\\" + curObjectName)
-- Moves the object to the world 0 0 0 node
curObject.pos = [0,0,0]
-- Changes the material name to match the object name
if chk_ForceName.state == true then (
if curObject.material == undefined then (
Print "Created new material"
newmat = StandardMaterial()
newmat.name = CurObject.name
CurObject.material = newmat
)
else (
print "Mat renamed"
curObject.material.name = CurObject.name
)
)
else ()
--Add the "turn to poly" and limit the number of sides to 3
if chk_Triangulate.state == true then (
Print "Triangulated"
modPanel.addModToSelection (Turn_to_Poly ()) ui:on
curObject.modifiers[#Turn_to_Poly].limitPolySize = on
curObject.modifiers[#Turn_to_Poly].maxPolySize = 3
)
else ()
exportFile exportpath selectedOnly:true #noPrompt
-- get rid of turn to poly modifier
if chk_Triangulate.state == true then (
max modify mode
deleteModifier curObject 1
)
else ()
-- moves object back to original position
move curObject curObjectPos
)
)
)
destroydialog Roll_FBXport
createdialog Roll_FBXport
cui.RegisterDialogBar Roll_FBXport style:#(#style_sysmenu,#cui_dock_top,#cui_floatable,#cui_handles,#style_minimizebox)
)
Feel free to change edit, barrow, hack apart and or modify the script however you need. Also if you know of anything better let me know, I was a little surprised I couldn't find script like this already... but maybe I wasn't looking in the right places.
Replies
I salute you.
*Clicks Download*
//hmmm, getting an -- Unknown preperty: "name" in undefined
Just a very quick job so far to fit my use for this. Also hardly tested at all. I'll probably add some more to it tomorrow tough.
Edit: Updated.
Installation and usage is the same as for Marks script.
you'll generally be alright as most systems will go for the "create the shortest edge" option but if you've turned hidden edges manually for whatever reason then the results may well be different.
I haven't had a need to do the retriangulation on any of the meshes with adjusted normals before so not sure if it is possible to do without loosing the normals. Of course going down on sub object level and adding the edges one by one in the script is probably going to work but hoping there is an easier way.
Nice work parkar!
I started working on a UI and then thought, I'm making this more complicated than it needs to be, and went for the one button option. Of course I then ran into cases like you mentioned where you need different options hahaha oh well... time to complicate it a bit, lucky for me you did some of the leg work already
About the triangulation.
I was using the FBX option but noticed would still pop up a message box complaining about turned edges. I too ran into a piece that I needed to edit the normals on and both methods of triangulation where giving me a seam, the only way I could get around it was to let UDK do the triangulation which is did "wrong" but with explicit normals checked on during import they overrode the retrinagulated normals so the seam disappeared.
Things to add:
Display and browse/edit export path, remember path.
Display and edit material name.
Option to create new material with default bitmaps in the commonly used slots.
Option to disable turn to poly triangulation.
I missed a week of work thanks to a bunch of snow and I'm pretty far behind so I don't know when I'll get a chance to work on this next but I'll post a updated version when I do.
Would need some more complicated script and should preferably save the config in the max file. Taking it all the way, some settings could even be stored per object in the custom parmaters I guess. Then add some quick toggle scripts that can be used on selection to set how each model should be handled.
I noticed its in UDK forum... not the best place. Sorry
need more info.
you wanting to export to xnoraml as xn's native sbm format or something else?
are you wanting to export the selections as individual objects, or export everything as 1?
are you wanting to choose the filename, or have the script automatically figure it out based on the object names and the path of the scene file?
I want a script which adds edit mesh modifier to selected mesh, exports to sbm (one script would export with high poly sbm preset and second with low poly), deletes edit mesh mod. One of the solutions i thought of was to solve it like in IOpipeline for modo. Script would export always to the same location. Xnormal would have always those 2 files plugged in (since it remebers what meshes were loaded before). Making bakes would only require to use those 2 scripts on high and low poly. Then you switch to xnormal and just press bake.
don't even really need to replace with variables, since you really got no dynamic things happening in there since all you want to dumping to the same filenames and path every-time.
For example you might do something and listener says: actionMan.executeAction 0 "40015" which is actually max undo which is much easier to work with.
You can use actionMan code but its pretty limiting and often very dependent on the situation you currently have set up, "in sub-object face mode, with faces selected and the paint relax tool active". If you rely on ActionMan you need to do all of that manually which is a waste of time if you want to click an object and have all of that happen automatically.
Also the listener doesn't record everything which can be frustrating so often you have to crack open the maxscript help file and do a bit of searching to find the real useful bits of code.
To get to the maxscript help file go Main Menu > Help > MaxScript Help. Or with the script editor open press F1.
MrOneTwo I'm not sure I understand what you're trying to do? Are you trying to export from max to xNormal or from xNormal to UDK? A single button export max to xNormal would be helpful kind of like GoZ in ZBrush, but you can't control xNormal through maxscript (that I know of) so something else would have to be done to get it out of xNormal and into UDK or back to max.
@ mark seems he just wants a 1 click export that goes to a per-defined location, and filename, useing the xnormal sbm format.