3DMax坐标系转换为Unity坐标系

3DMax坐标系转换为Unity坐标系

3DMax是右坐标系,并且Z轴向上
3DMax坐标系转换为Unity坐标系_第1张图片
Unity 是左手坐标系,并且Y轴向上
3DMax坐标系转换为Unity坐标系_第2张图片
在导出FBX文件的时候3DMax是可以指定Y,Z轴向上的3DMax坐标系转换为Unity坐标系_第3张图片
问题是unity里面X轴会旋转-90度,而这个结果是我们不想要的。而这个问题就出在

  1. Max是Z轴向上的
  2. 导出Y轴向上设置Max直接把X旋转了90度,而这个时候物体也一起旋转了90度
  3. 为了不让物体旋转,在FBX导入的时候X轴旋转-90来把物体扶正

解决方案

仅旋转物体的pivot 轴向(X会旋转-90 那么X轴提前旋转90 这样在Unity里面抵消为0),经过实验这样是可行的。
3DMax坐标系转换为Unity坐标系_第4张图片

完整脚本

try(cui.unRegisterDialogBar ToolTest)catch()

try(DestroyDialog ToolTest)catch()


fn RotatePivot obj x y z absolute:false =
(
	-- store the object's position for later
	p = obj.pos
	
	if absolute do
	(
		-- store the object's rotation as an offset from the
		-- identity matrix (aka zero world transform)
		offsetrot = inverse (obj.rotation * inverse (matrix3 1))
		
		-- use the stored offset to zero the pivot rotation
		-- in world coords. after this step, the supplied x y z 
		-- will be an absolute offset from world coords:)
		obj.rotation *= offsetrot
		obj.objectoffsetrot *= offsetrot
	)
	
	-- get the supplied x y z degrees as a quaternion offset.
	-- the inversion changes the rotation from a right-handed 
	-- coordinate system to the expected left-handed system.
	-- Rotation in Maxscript sure is tricky!
	rot = inverse ((eulerangles x y z) as quat)
	
	-- finally, apply the final offset to the object's pivot.
	-- Basically, we're transforming the whole object, and then
	-- using .objectoffsetrot to backtransform just the object's 
	-- geometry.  Pretty neat, huh?
	obj.rotation *= rot
	obj.objectoffsetrot *= rot
	
	-- set the object to it's original position
	obj.pos = p
	
	return ok
)

fn getRoot node = if isvalidnode node do (while node.parent != undefined do node = node.parent; node)

rollout ToolTest "ToolTest"
(
	
	button btn3 "导出选择物体"width:150
	


	on btn3 pressed do
	(
		objs = selection as Array
		if objs.count == 0 then (messageBox "需要选择指定物体!!!")
		else
		(
			names = ""
			--maxops.pivotmode = #pivotonly
			For obj in objs do
			(
				--only change root
				root = getRoot(obj)
				names = root.name
				--children unlink
				childers = root.children
				--save childers
				saveChilders = #()
				join saveChilders childers
				For chi in childers do
				(
					chi.parent = ()
					
				)
				RotatePivot root 0 0 180
				RotatePivot root 90 0 0
				
				--children link
				For chi in saveChilders do
				(
					chi.parent = root
				)
			
			)
	
			--save file path
			path = getSaveFileName caption:"保存文件路径选择" types:"*.fbx" filename:names
			Print path
			if undefined == path then (messageBox "请选择保存路径")
			else
			(
				FBXExporterSetParam "ASCII"   False
				FBXExporterSetParam "Cameras" False
				FBXExporterSetParam "Lights"  False
				FBXExporterSetParam "Skin" true
				FBXExporterSetParam "ExportAnimationOnly" false
				FBXExporterSetParam "ConvertUnit" "m"
				exportFile path #noPrompt selectedOnly:true using:FBXEXP
			)
			
	
	
			--export after
			For obj in objs do
			(
				--only change root
				root = getRoot(obj)
				--children unlink
				childers = root.children
				--save childers
				saveChilders = #()
				join saveChilders childers
				For chi in childers do
				(
					chi.parent = ()
					
				)
				RotatePivot root -90 0 0
				RotatePivot root 0 0 -180
				--children link
				For chi in saveChilders do
				(
					chi.parent = root
				)
			
			)	
		)
		
	)
)
CreateDialog ToolTest
cui.registerDialogBar ToolTest
cui.dockDialogBar ToolTest #cui_dock_left
脚本使用步骤
  • 把插件脚本放入启动文件夹

    • 列如:C:\Users\用户名\AppData\Local\Autodesk\3dsMax\max安装版本\ENU\scripts\startup
    • 插件名称 文件名.ms
  • 重启Max

  • 选择要导出的物体

  • 点击导出选择物体按钮

    • 会弹出选择保存路径窗口,现在保存路径即可
    • 可以自由拖拽窗口放在喜欢的位置

3DMax坐标系转换为Unity坐标系_第5张图片

阅读链接

附上在解决问题过程中找到的一些学习资料,感谢他们的分享
3ds Max修改模型坐标系
MaxScript官网文档 导出参数
MaxScript pivot
MaxScript官网文档 保存文件
脚本基本介绍

你可能感兴趣的:(unity,unity,TA,3DMax)