It can be a bit easier to place objects using 3ds Max than it would be to place things in UE4, but there’s currently no way to get those positions from 3ds Max to UE4 and try to maintain instancing. So here are a couple Maxscripts to help with that.
The first script is for unique objects–so anything that doesn’t have multiple copies of the object.
https://imagizer.imageshack.us/v2/244x226q90/854/qw2v.jpg
rollout test "Copy to UE4"
(
label packagelabel "Folder Path" style_sunkenedge:false width:180 height:20
edittext packagename "" width:180
label objectlabel "Prefix" style_sunkenedge:false width:180 height:20
edittext prefix "" width:180
button btnCopy "Copy" width:180
fn round_to val =
(
(floor (val + 0.5))
)
on btnCopy pressed do
(
clipboardstring=""
clipboardstring += ("Begin Map")
clipboardstring += ("
"+" Begin Level")
for obj in selection do
(
clipboardstring += ("
"+" Begin Actor Class=StaticMeshActor Name=" + prefix.text + obj.name + " Archetype=StaticMeshActor'/Script/Engine.Default__StaticMeshActor'")
clipboardstring += ("
"+" Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 ObjName=StaticMeshComponent0 Archetype=StaticMeshComponent'/Script/Engine.Default__StaticMeshActor:StaticMeshComponent0'")
clipboardstring += ("
"+" End Object")
clipboardstring += ("
"+" Begin Object Name=StaticMeshComponent0")
clipboardstring += ("
"+" StaticMesh=StaticMesh'" + packagename.text + prefix.text + obj.name + "." + prefix.text + obj.name + "'")
clipboardstring += ("
"+" StaticMeshDerivedDataKey=\"STATICMESH_34081786561B425A9523C94540EA599D_359a029847e84730ba516769d0f19427_08B81D3F4753513B93E720832A7E9708000000000100000001000000000000000000803F0000803F00000000000000000000344203030300000000\"")
clipboardstring += ("
"+" RelativeLocation=(X=" + obj.transform.position.x as string)
clipboardstring += (",Y=" + ((obj.transform.position.y) - (obj.transform.position.y) - (obj.transform.position.y)) as string)
clipboardstring += (",Z=" + obj.transform.position.z as string)
clipboardstring += (")")
clipboardstring += ("
"+" RelativeRotation=(Pitch=" + (round_to (obj.rotation.x_rotation) as integer) as string)
clipboardstring += (",Yaw=" + (round_to ((obj.rotation.z_rotation * -1)) as integer) as string)
clipboardstring += (",Roll=" + (round_to (obj.rotation.y_rotation) as integer) as string)
clipboardstring += (")")
clipboardstring += ("
"+" RelativeScale3D=(X=" + obj.transform.scale.x as string)
clipboardstring += (",Y=" + obj.transform.scale.y as string)
clipboardstring += (",Z=" + obj.transform.scale.z as string)
clipboardstring += (")")
clipboardstring += ("
"+" End Object")
clipboardstring += ("
"+" StaticMeshComponent=StaticMeshComponent0")
clipboardstring += ("
"+" RootComponent=StaticMeshComponent0")
clipboardstring += ("
"+" ActorLabel=\"" + prefix.text + obj.name + "\"")
clipboardstring += ("
"+" End Actor")
)
clipboardstring += ("
"+" End Level")
clipboardstring += ("
"+"Begin Surface")
clipboardstring += ("
"+"End Surface")
clipboardstring += ("
"+"End Map")
SetClipBoardText (clipboardstring as string)
)
)
createDialog test 200 160 fgcolor:Black
Copy the Code and save as UE4-Copy.ms
To use it in 3ds Max you can just drag it into your 3ds Max window and it will run the script.
-Instructions
Under Folder Path, put the path where the file is located in the UDK Content Browser, notice the formatting example.
Under Prefix put in the prefix for the object name. In my case, I had exported the meshes to a file name 787_chairs.fbx so every object ended up with a prefix of 787_chairs_
Make sure that your objects are selected and click Copy
It will copy the object information to the clipboard, just go to UE4 and paste. This currently supports position, rotation, and scale.
Second script is for instanced objects, so you would do this for each object that is used multiple times.
http://imageshack.com/a/img824/4978/2te9.jpg
rollout test "Copy to UE4"
(
label packagelabel "Folder Path" style_sunkenedge:false width:180 height:20
edittext packagename "" width:180
label objectlabel "Object Name" style_sunkenedge:false width:180 height:20
edittext objectname "" width:180
button btnCopy "Copy" width:180
fn round_to val =
(
(floor (val + 0.5))
)
on btnCopy pressed do
(
clipboardstring=""
clipboardstring += ("Begin Map")
clipboardstring += ("
"+" Begin Level")
for obj in selection do
(
clipboardstring += ("
"+" Begin Actor Class=StaticMeshActor Name=" + objectname.text + "_30" + " Archetype=StaticMeshActor'/Script/Engine.Default__StaticMeshActor'")
clipboardstring += ("
"+" Begin Object Class=StaticMeshComponent Name=\"" + "StaticMeshComponent0" + "\"" + " Archetype=StaticMeshComponent'Default__StaticMeshActor:StaticMeshComponent0'")
clipboardstring += ("
"+" End Object")
clipboardstring += ("
"+" Begin Object Name=\"" + "StaticMeshComponent0" + "\"")
clipboardstring += ("
"+" StaticMesh=StaticMesh'" + packagename.text + objectname.text + "." + objectname.text + "'")
clipboardstring += ("
"+" StaticMeshDerivedDataKey=\"STATICMESH_46A8778361B442A9523C54440EA1E9D_2C1BC8F50A7A43818AFE266EB43D9060_D159F6D649D49C94FF855A98AD20AC5F0000000001000000010000000100000000000000000000004000000000000000010000000000803F0000803F0000803F0000803F000000000000803F00000000000000000000344203030300000000\"")
clipboardstring += ("
"+" RelativeLocation=(X=" + obj.transform.position.x as string)
clipboardstring += (",Y=" + ((obj.transform.position.y) - (obj.transform.position.y) - (obj.transform.position.y)) as string)
clipboardstring += (",Z=" + obj.transform.position.z as string)
clipboardstring += (")")
clipboardstring += ("
"+" RelativeRotation=(Pitch=" + (round_to (obj.rotation.x_rotation) as integer) as string)
clipboardstring += (",Yaw=" + (round_to ((obj.rotation.z_rotation * -1)) as integer) as string)
clipboardstring += (",Roll=" + (round_to (obj.rotation.y_rotation) as integer) as string)
clipboardstring += (")")
clipboardstring += ("
"+" RelativeScale3D=(X=" + obj.transform.scale.x as string)
clipboardstring += (",Y=" + obj.transform.scale.y as string)
clipboardstring += (",Z=" + obj.transform.scale.z as string)
clipboardstring += (")")
clipboardstring += ("
"+" End Object")
clipboardstring += ("
"+" StaticMeshComponent=StaticMeshComponent0")
clipboardstring += ("
"+" RootComponent=StaticMeshComponent0")
clipboardstring += ("
"+" ActorLabel=\"" + objectname.text + "\"")
clipboardstring += ("
"+" End Actor")
)
clipboardstring += ("
"+" End Level")
clipboardstring += ("
"+"Begin Surface")
clipboardstring += ("
"+"End Surface")
clipboardstring += ("
"+"End Map")
SetClipBoardText (clipboardstring as string)
)
)
createDialog test 200 160 fgcolor:Black
Copy the Code and save as UE4-Copy Instanced.ms
To use it in 3ds Max you can just drag it into your 3ds Max window and it will run the script.
-Instructions
Folder path is the same as before
Under name, put the actual name of the object as it appears in the Content Browser
Make sure that only the instances of one object are selected, and click Copy
It will copy the information of all the selected objects to the clipboard, go to UE4 and paste.
Workflow for instancing–so for this example I have lots of chairs to place, so in 3ds Max I take one chair and place it at the origin and then export that as FBX to UE4. The object comes up as 787_chair_economy in the content browser. Back in 3ds Max I select all the instances of that type of chair and use the script, and then I can paste it back to UE4 and it will have the same positions. For the objects in 3ds Max they don’t actually have to be instances of the object or even the same object, all it’s doing is copying the transform information of the selections.
NOTE: This will not work with UDK. UDK uses a different formatting when you copy something to the clipboard.
I don’t know that much about scripting, I just learned enough to make these scripts. So if anyone wants to improve on them you are welcome to.