max各种相机导出到ue4匹配镜头的工具集

总览

javascript 复制代码
 rollout export_UE4Cam_v2 "导出UE4Cam_v2:半自动" width:200 height:120
 (
	HyperLink  explain "在打开的max文件中使用" pos:[25,12] width:200 height:15 color:(color 255 155 0)	 
	GroupBox grp1 "要导出的相机名" pos:[5,28] width:179 height:40
	pickbutton OutCam "拾取相机" pos:[20,40] width:150 height:20
	GroupBox grp2 "要导出的fbx文件名" pos:[5,70] width:179 height:50
	button	 bt_create	"Create UE4 Camera" pos:[20,85] width:150 height:32 enabled:true
	 
-----逐行写入文本------------
fn format_txt FilePath filetext1 filetext2=
(	
	if doesFileExist FilePath == true
		then
	(
		fin = openfile FilePath mode:"r+"
		seek fin #eof
		txt = filetext1+RenderWidth as string+"\n"+filetext2+RenderHeight as string+"\n"
		format txt to:fin
		close fin
	)
	else
	(
		newfile = createFile FilePath writeBOM:true
		close newfile
		format_txt FilePath filetext1 filetext2
		)
)
-----end逐行写入文本-----------------

    on OutCam picked obj do
    (
     OutCam.text = obj.name
        )
 
 	on bt_create pressed do
 	(		
		Freecamera fov:45 targetDistance:314.512 nearclip:1 farclip:1000 nearrange:0 farrange:1000 mpassEnabled:off mpassRenderPerPass:off pos:[0,0,0] isSelected:on
		mycam = OutCam.text
		$.name = mycam
		UE4CAM =$
		MAXCAM =getnodebyname mycam
		UE4CAM.Position=MAXCAM.position
		UE4CAM.FOV=MAXCAM.FOV
		--位置约束
		UE4CAM.Position.controller= Position_Constraint ()
		A = UE4CAM.Position.controller
		A.appendTarget MAXCAM 100
		--方向约束
		UE4CAM.rotation.controller= Orientation_Constraint ()
		B = UE4CAM.rotation.controller
		
		B.appendTarget MAXCAM 100

		--开始塌陷
				local forceUpdate = keyboard.shiftPressed -- if SHIFT is pressed when the macro is called, a viewport redraw is enforced for each timestep to ensure a full update of all controllers
				if forceUpdate then format "MB Collapse: Enforcing full viewport update. This might be slow but will ensure proper updating of all controllers\n"
				
					local p = undefined
					local old_prs_ctrl = copy UE4CAM.transform.controller		-- store old controller for catch()
					with undo on (
						if not forceUpdate then disableSceneRedraw();	-- not using redraw context for max4 compatibility
						-- disableSceneRedraw is problematic as not all scripted controllers are updated!
						try (
							p = Point()			-- create temp point object
							-- copy global transform of source object into temp object
							for i = animationRange.start to animationRange.end do (
								if forceUpdate then sliderTime = i	-- set slider time to force a global update of all animation data
								at time i (
									with animate on p.transform = UE4CAM.transform
								)
							)
							-- kill old transform controller and assign new, clean one
							UE4CAM.transform.controller = transform_script()	
							UE4CAM.transform.controller = prs()	
							
							if not (isGroupMember UE4CAM) then UE4CAM.parent = undefined	-- unlink if not in a group
							-- copy temp object animation back into source object
							for i = animationRange.start to animationRange.end do (
								at time i (
									with animate on	UE4CAM.transform = p.transform
								)
							)

							delete p			-- delete temp point obj
							p = undefined
							if not forceUpdate then enableSceneRedraw()
						)--try
					catch(
						format "coder zsz:QQ  : Fatal error - exiting\n"
									if p!=undefined then delete p
									UE4CAM.transform.controller = old_prs_ctrl
									if not forceUpdate then enableSceneRedraw()
						  )-- catch				
					)--with undo
		--塌陷结束
					
		-----导出fbx文件----
        -- 使用一个.net文件windows窗口---导出fbx文件
		browse_dialog = dotNetObject "System.Windows.Forms.SaveFileDialog" --建立一个打开文件对话框
		DotNetFile = DotNetClass "System.IO.File"--创建.net文件
		browse_dialog.title = "保存文件" --设置标题
		browse_dialog.Filter = "fbx Files (*.fbx)|*.fbx|All Files (*.*)|*.*" --确认这个文件过滤
		browse_dialog.fileName = trimright maxfilename ".max"
		browse_dialog.FilterIndex = 2 --设置文件过滤下拉菜单长度
		result = browse_dialog.showDialog() --显示对话框,得到的结果进变量
		if (result.Equals result.OK) then
		(
			if ( not (DotNetFile.Exists browse_dialog.FileName)) then
			(
				select UE4CAM
				if selection.count !=0 then(	
				AA=browse_dialog.fileName+".fbx"
				exportFile AA  #noPrompt selectedOnly:true using:fbxexp
				BB=browse_dialog.fileName+".TXT"
				format_txt BB "renderWidth=" "renderHight="
				)
			)

		)			
		--删除相机 	
		delete UE4CAM
        free(filepath)					
	)
	
 )
 rollout exportFBX "导出fbx模:半自动" width:200 height:100
 (
	HyperLink explain "在打开的max文件中使用" pos:[25,0] width:200 height:15 color:(color 255 155 0)	 
	GroupBox grp1 "要导出的角色根骨骼" pos:[5,15] width:179 height:80
	pickbutton PickRoot "拾取根骨骼" pos:[20,30] width:150 height:20
	button	 bt_OutFBX	"输出fbx模型" pos:[20,55] width:150 height:30 enabled:true

	 on PickRoot picked obj do
 	( 
		PickRoot.text = obj.name
	)		
	 on bt_OutFBX pressed do
 	( 
		ChrBone=getnodebyname PickRoot.text
		select ChrBone
		--根据根选择此层级所有物体
		if selection.count !=0 then(
			fn getTheChildren obj:selection[1] includeParent:false = (execute ("$'" + (obj.name)+"'/"+(if includeParent then "" else "*/")+".../*"))
			  
			  select (getTheChildren includeParent:true)
			  select (getTheChildren())
			  
			  getTheChildren includeParent:true as array
			  getTheChildren() as array
		  )
		mysel=selection as array 
		-----对齐帧处理-----
					debb = 10000
					finn=-10000 
						for a in selection do
					(
						if  (classof a == BoneGeometry) then(
							if (numKeys a.position.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.position.controller
								starttime = getkeytime a.position.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.position.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
						if (classof a == Biped_Object) then(
							if (numKeys a.transform.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.transform.controller
								starttime = getkeytime a.transform.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.transform.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
					)
					animationRange = interval debb finn	
	-----end对齐帧处理-----
					
	------------查找蒙皮中具有bip字样的模型并一起选择---------------
		if selection.count !=0 then(
			actionMan.executeAction 0 "283"  -- Tools: Unfreeze All
			max unfreeze all	  
			allTheSkin = for obj in objects where (classof obj==PolyMeshObject)  collect obj
			for f in allTheSkin do(
			skinMods = getclassinstances Skin target:f 
			max modify mode
			modPanel.setCurrentObject f.modifiers[#Skin]
			skinOps.getnumberbones skinMods[1]
			bonename =skinOps.getBoneName skinMods[1] 1 0
			bonename =skinOps.getBoneName skinMods[1] 2 0	
			if findString bonename "Bip" ==1 then (join mysel f)else(deselect f)
			selectmore mysel
			)
		)
        -----使用一个.net文件windows窗口---导出fbx文件------
		browse_dialog = dotNetObject "System.Windows.Forms.SaveFileDialog" --建立一个打开文件对话框
		DotNetFile = DotNetClass "System.IO.File"--创建.net文件
		browse_dialog.title = "保存文件" --设置标题
		browse_dialog.Filter = "fbx Files (*.fbx)|*.fbx|All Files (*.*)|*.*" --确认这个文件过滤
		browse_dialog.fileName = trimright maxfilename ".max"
		browse_dialog.FilterIndex = 2 --设置文件过滤下拉菜单长度
		result = browse_dialog.showDialog() --显示对话框,得到的结果进变量
		if (result.Equals result.OK) then
		(
			if ( not (DotNetFile.Exists browse_dialog.FileName)) then
			(
				if selection.count !=0 then(	
				AA=browse_dialog.fileName+"."+"model"+".fbx"
				exportFile AA #noPrompt selectedOnly:true using:fbxexp
				)
			)

		)
	)
 )
 rollout exportFBX_ue4cam_v1 "批出fbx模&UEcam_V1:自动" width:200 height:120
 (
HyperLink explain "指定目录即可,不需要打开文件" pos:[25,0] width:200 height:15  color:(color 255 155 0)
edittext selfile "" pos:[10,20] width:140 height:19 text:"...请选择目录"
button btn_browse "..."  pos:[160,20] width:30 height:19 
checkBox ignore "忽略backup文件" pos:[60,40] width:100 height:19
-- radioButtons rdo1 "" pos:[30,40] width:168 height:16 labels:#("输出相机", "输出模型") default:1 columns:2	 
button	 bt_create	"批量输出fbx" pos:[20,60] width:150 height:32 enabled:true

-------逐行写入文本------------
fn format_txt filepath filetext1 filetext2=
(	
	if doesFileExist filepath == true
		then
	(
		fin = openfile filepath mode:"r+"
		seek fin #eof
		txt = filetext1+RenderWidth as string+"\n"+filetext2+RenderHeight as string+"\n"
		format txt to:fin
		close fin
	)
	else
	(
		newfile = createFile filepath writeBOM:true
		close newfile
		format_txt filepath filetext1 filetext2
		)
)  -- 逐行写入文本	 
	 
	 on btn_browse pressed do
 	( 		
		global DIR = getSavePath caption:"选择max目录"
		if (DIR != undefined) then ( selfile.text = dir )
	)		
	 on bt_create pressed do
 	( 
	 files =DIR+"\*.max"
	OldFiles=getfiles files	
	GetFile= getFiles files	 
	if (ignore.checked) then(
		 ---排除掉backup文件--
		 UndoFiles=getfiles (DIR+"\*backup*.max")
		 for j = 1 to UndoFiles.count do	while (index = (findItem GetFile UndoFiles[j])) != 0 do (deleteItem GetFile index)
		---排除掉backup文件end--	 
	)	
	 Maxfiles=GetFile
		 
	 for f in Maxfiles do (
		--打开max文件--- 
		 loadMaxfile f missingExtFilesAction:#logmsg

		---切割文本内容
		mydir=trimRight f ".max"
		global filename=trimLeft mydir DIR
        global filepath=(DIR+"/"+filename+".txt") as string		 
 		--------start 输出model.fbx-------	
		 
		---------只输出bip模型------------
		--选择所有bip物体
		select $'*bip*' 
			
		mysel= selection as array
		--根据bip选择根
		for f in mysel do(
		fn getRoot node = if isvalidnode node do (while node.parent != undefined do node = node.parent; node)
		aaa=getRoot f
		select aaa
		)
		--根据根选择此层级所有物体
		if (selection.count !=0) then(
			fn getTheChildren obj:selection[1] includeParent:false = (execute ("$'" + (obj.name)+"'/"+(if includeParent then "" else "*/")+".../*"))
			  
			  select (getTheChildren includeParent:true)
			  select (getTheChildren())
			  
			  getTheChildren includeParent:true as array
			  getTheChildren() as array
		  )

		if (selection.count !=0) do(
		-----对齐帧处理-----
					debb = 10000
					finn=-10000 
						for a in selection do
					(
						if  (classof a == BoneGeometry) then(
							if (numKeys a.position.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.position.controller
								starttime = getkeytime a.position.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.position.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
						else if (classof a == Biped_Object) then(
							if (numKeys a.transform.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.transform.controller
								starttime = getkeytime a.transform.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.transform.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
					)
					animationRange = interval debb finn	

	-----end对齐帧处理-----
				)
				
	------------查找蒙皮中具有bip字样的模型并一起选择---------------
		if selection.count !=0 then(
			actionMan.executeAction 0 "283"  -- Tools: Unfreeze All
			max unfreeze all	  
			allTheSkin = for obj in objects where (classof obj==PolyMeshObject)  collect obj
			for f in allTheSkin do(
			skinMods = getclassinstances Skin target:f 
			max modify mode
			modPanel.setCurrentObject f.modifiers[#Skin]
			skinOps.getnumberbones skinMods[1]
			bonename =skinOps.getBoneName skinMods[1] 1 0
			bonename =skinOps.getBoneName skinMods[1] 2 0	
			if findString bonename "Bip" ==1 then (join mysel f)else(deselect f)
			selectmore mysel
			)
		)
		---------只输出bip模型------------

		if selection.count !=0 then(
        AA=Dir+"/"+filename+"."+"model"+".fbx"	
		exportFile  AA #noPrompt selectedOnly:true using:fbxexp
		deselect $	
		)
		----end 输出model.fbx---
		 
		 --选择相机(包括隐藏的)跳过目标物体
		camsARr = for o in cameras where classof o != targetobject collect o
		select camsARr  filter:FilterCameras showHidden:true
		MaxCamSelSet = selection as array	
		------start输出cam.fbx------
		for i in MaxCamSelSet do(
					MAXCAM= i
	
					Freecamera fov:45 targetDistance:314.512 nearclip:1 farclip:1000 nearrange:0 farrange:1000 mpassEnabled:off mpassRenderPerPass:off pos:[0,0,0] isSelected:on
					hide $
					$.name =FileName+"."+i.name --设置相机名称
					UE4CAM =$
					UE4CAM.Position=MAXCAM.position
					UE4CAM.FOV=MAXCAM.FOV
						
					--位置约束
					UE4CAM.Position.controller= Position_Constraint ()
					A = UE4CAM.Position.controller
					A.appendTarget MAXCAM 100
					--方向约束
					UE4CAM.rotation.controller= Orientation_Constraint ()
					B = UE4CAM.rotation.controller
					
					B.appendTarget MAXCAM 100

		--开始塌陷
				local forceUpdate = keyboard.shiftPressed -- if SHIFT is pressed when the macro is called, a viewport redraw is enforced for each timestep to ensure a full update of all controllers
				if forceUpdate then format "MB Collapse: Enforcing full viewport update. This might be slow but will ensure proper updating of all controllers\n"
				
					local p = undefined
					local old_prs_ctrl = copy UE4CAM.transform.controller		-- store old controller for catch()
					with undo on (
						if not forceUpdate then disableSceneRedraw();	-- not using redraw context for max4 compatibility
						-- disableSceneRedraw is problematic as not all scripted controllers are updated!
						try (
							p = Point()			-- create temp point object
							-- copy global transform of source object into temp object
							for i = animationRange.start to animationRange.end do (
								if forceUpdate then sliderTime = i	-- set slider time to force a global update of all animation data
								at time i (
									with animate on p.transform = UE4CAM.transform
								)
							)
							-- kill old transform controller and assign new, clean one
							UE4CAM.transform.controller = transform_script()	
							UE4CAM.transform.controller = prs()	
							
							if not (isGroupMember UE4CAM) then UE4CAM.parent = undefined	-- unlink if not in a group
							-- copy temp object animation back into source object
							for i = animationRange.start to animationRange.end do (
								at time i (
									with animate on	UE4CAM.transform = p.transform
								)
							)
							delete p			-- delete temp point obj
							p = undefined
							if not forceUpdate then enableSceneRedraw()
						)--try
					catch(
						format "coder zsz:QQ  : Fatal error - exiting\n"
									if p!=undefined then delete p
									UE4CAM.transform.controller = old_prs_ctrl
									if not forceUpdate then enableSceneRedraw()
						  )-- catch				
					)--with undo
		--塌陷结束

					----对齐相机的关键帧到动画范围---

					debb = 10000
					finn=-10000 
					for a in selection do
					(
						if (numKeys a.position.controller > 0)then(
							sortKeys a.controller
							num_keys = numkeys a.position.controller
							starttime = getkeytime a.position.controller 1
							endtime = starttime
							for O = 1 to num_keys do 
							(
						 
								key_time = getkeytime a.position.controller O
								if key_time > endtime then
									 endtime = key_time
							)
							if starttime < debb then debb = starttime
							if endtime > finn then finn = endtime
						)
						else(
							starttime = 1
							endtime = 100				
							if starttime < debb then debb = starttime
							if endtime > finn then finn = endtime				
							)
					)
					animationRange = interval debb finn	
					----对齐相机的关键帧到动画范围end---	
					
		--------导出fbx文件-------
						CAM=MAXCAM.name
						BB=DIR+"/"+filename+"."+CAM+".fbx"

					exportFile  BB #noPrompt selectedOnly:true using:fbxexp	
					
				)	
		------end输出cam.fbx------
				
-- 		------输出cam.txt------
		if MaxCamSelSet.count !=0 then(		
		format_txt filepath "renderWidth=" "renderHight="
		)
-- 		------end输出cam.txt------	
			
		 ------重置max场景-------		
		resetMaxFile #noPrompt
		
		)
	----删除导入机制生产的备份文件---
		
	 ---排除掉新产生的backup文件--
	 NewFiles=getfiles (DIR+"\*.max")
	
	 for j = 1 to OldFiles.count do	while (index = (findItem NewFiles OldFiles[j])) != 0 do (deleteItem NewFiles index)
	 WillDelFiles=NewFiles
	---排除掉新产生的backup文件end--
 
	for a in WillDelFiles do
	(			
		deletefile a
		) 
	----删除导入机制生产的备份文件---
		
	----释放全局变量DIR	
 	free(DIR)
	)
 )

 rollout exportFBX_ue4cam_v2 "批出fb模&UEcam_V2:模式自选" width:200 height:100
 (
HyperLink explain "指定目录即可,不需要打开文件" pos:[25,0] width:200 height:15 color:(color 255 155 0)
edittext selfile "" pos:[10,15] width:140 height:19 text:"...请选择目录"
button btn_browse "..."  pos:[160,15] width:30 height:19
checkBox ignore "忽略backup文件" pos:[60,35] width:100 height:19
label explain1 "输出相机是打开模式,输出模型是导入模式" pos:[0,64] width:200 height:15 
radioButtons rdo1 "" pos:[30,50] width:168 height:16 labels:#("输出相机", "输出模型") default:1 columns:2	 
button	 bt_create	"批量输出fbx" pos:[20,80] width:150 height:32 enabled:true

---函数部分--
 fn LoadOrMergeFile f = (
		 if rdo1.state ==1 then (
			loadMaxfile f missingExtFilesAction:#logmsg
		)
		if rdo1.state ==2 then (
			mergeMaxfile f 
		)
 )  

---------逐行写入文本------------
fn format_txt FilePath filetext1 filetext2=
(	
	if doesFileExist FilePath == true
		then
	(
		fin = openfile FilePath mode:"r+"
		seek fin #eof
		txt = filetext1+RenderWidth as string+"\n"+filetext2+RenderHeight as string+"\n"
		format txt to:fin
		close fin
	)
	else
	(
		newfile = createFile FilePath writeBOM:true
		close newfile
		format_txt FilePath filetext1 filetext2
		)
)
-- 逐行写入文本
			
---///end函数部分--
	 on btn_browse pressed do
 	( 
		global DIR = getSavePath caption:"选择max目录"
		if (DIR != undefined) do ( selfile.text = DIR )	
	)	
	
	 on bt_create pressed do
 	( 
	 files =DIR+"/"+"*.max"
	 OldFiles=getfiles files	
	 GetFile= getFiles files
    if (ignore.checked)then(		
 	 ---排除掉backup文件--
	 WillDelFiles=getfiles (DIR+"\*backup*.max")
	 for j = 1 to WillDelFiles.count do	while (index = (findItem GetFile WillDelFiles[j])) != 0 do (deleteItem GetFile index)
	---排除掉backup文件end-- 
	)
	
	Maxfiles=GetFile 
		 
	 for f in Maxfiles do (
			---切割文本内容
			mydir=trimRight f ".max"
			global FileName=trimLeft mydir DIR
			global FilePath=(DIR+"/"+FileName+".txt") as string	
			--导入max文件--- 
			LoadOrMergeFile f	 
			----输出model.fbx ---		 
	-- 		ExportModel,见 rdo1的写在那里面
			 if rdo1.state ==1 then (
		---选择相机(包括隐藏的)跳过目标物体
		camsArr = for o in cameras where classof o != targetobject collect o
		select camsArr  filter:FilterCameras showHidden:true
		MaxCamSelSet = selection as array	
		------start输出cam.fbx------
		for i in MaxCamSelSet do(
					MAXCAM= i
			
					Freecamera fov:45 targetDistance:314.512 nearclip:1 farclip:1000 nearrange:0 farrange:1000 mpassEnabled:off mpassRenderPerPass:off pos:[0,0,0] isSelected:on
					hide $
					$.name =FileName+"."+i.name --设置相机名称
					UE4CAM =$
					UE4CAM.Position=MAXCAM.position
					UE4CAM.FOV=MAXCAM.FOV
						
					--位置约束
					UE4CAM.Position.controller= Position_Constraint ()
					A = UE4CAM.Position.controller
					A.appendTarget MAXCAM 100
					--方向约束
					UE4CAM.rotation.controller= Orientation_Constraint ()
					B = UE4CAM.rotation.controller
					
					B.appendTarget MAXCAM 100

		--开始塌陷
				local forceUpdate = keyboard.shiftPressed -- if SHIFT is pressed when the macro is called, a viewport redraw is enforced for each timestep to ensure a full update of all controllers
				if forceUpdate then format "MB Collapse: Enforcing full viewport update. This might be slow but will ensure proper updating of all controllers\n"
				
					local p = undefined
					local old_prs_ctrl = copy UE4CAM.transform.controller		-- store old controller for catch()
					with undo on (
						if not forceUpdate then disableSceneRedraw();	-- not using redraw context for max4 compatibility
						-- disableSceneRedraw is problematic as not all scripted controllers are updated!
						try (
							p = Point()								-- create temp point object
							
							-- copy global transform of source object into temp object
							for i = animationRange.start to animationRange.end do (
								if forceUpdate then sliderTime = i	-- set slider time to force a global update of all animation data
								at time i (
									with animate on p.transform = UE4CAM.transform
								)
							)
							-- kill old transform controller and assign new, clean one
							UE4CAM.transform.controller = transform_script()	
							UE4CAM.transform.controller = prs()	
							
							if not (isGroupMember UE4CAM) then UE4CAM.parent = undefined	-- unlink if not in a group
							-- copy temp object animation back into source object
							for i = animationRange.start to animationRange.end do (
								at time i (
									with animate on	UE4CAM.transform = p.transform
								)
							)
							delete p			-- delete temp point obj
							p = undefined
							if not forceUpdate then enableSceneRedraw()
						)--try
					catch(
						format "coder zsz:QQ  : Fatal error - exiting\n"
									if p!=undefined then delete p
									UE4CAM.transform.controller = old_prs_ctrl
									if not forceUpdate then enableSceneRedraw()
						  )-- catch				
					)--with undo
		--塌陷结束
					
					----对齐相机的关键帧到动画范围---
					debb = 10000
					finn=-10000 
					for a in selection do
					(
						if (numKeys a.position.controller > 0)then(
							sortKeys a.controller
							num_keys = numkeys a.position.controller
							starttime = getkeytime a.position.controller 1
							endtime = starttime
							for O = 1 to num_keys do 
							(
						 
								key_time = getkeytime a.position.controller O
								if key_time > endtime then
									 endtime = key_time
							)
							if starttime < debb then debb = starttime
							if endtime > finn then finn = endtime
						)
						else(
							starttime = 1
							endtime = 100				
							if starttime < debb then debb = starttime
							if endtime > finn then finn = endtime				
							)
					)
					animationRange = interval debb finn	
					----对齐相机的关键帧到动画范围end---	
					
		--------导出fbx文件-------
					CAM=MAXCAM.name
					FBXFileName=DIR+"/"+FileName+"."+CAM+".fbx"
					exportFile FBXFileName #noPrompt selectedOnly:true using:fbxexpp	
				)	
		------end输出cam.fbx------
				 
				------输出cam.txt------
				if MaxCamSelSet.count !=0 then(				
				format_txt FilePath "renderWidth=" "renderHight="
				)
				------end输出cam.txt------
				 
			)
			if rdo1.state ==2 then (

		---------只输出bip模型------------
		--选择所有bip物体
		select $'*bip*' 
		
		mysel= selection as array
		--根据bip选择根
		for f in mysel do(
		fn getRoot node = if isvalidnode node do (while node.parent != undefined do node = node.parent; node)
		aaa=getRoot f
		select aaa
		)
		--根据根选择此层级所有物体
		if selection.count !=0 then(
		fn getTheChildren obj:selection[1] includeParent:false = (execute ("$'" + (obj.name)+"'/"+(if includeParent then "" else "*/")+".../*"))
		  
		  select (getTheChildren includeParent:true)
		  select (getTheChildren())
		  
		  getTheChildren includeParent:true as array
		  getTheChildren() as array
		)
		-----对齐帧处理-----
					debb = 10000
					finn=-10000 
						for a in selection do
					(
						if  (classof a == BoneGeometry) then(
							if (numKeys a.position.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.position.controller
								starttime = getkeytime a.position.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.position.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
						if (classof a == Biped_Object) then(
							if (numKeys a.transform.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.transform.controller
								starttime = getkeytime a.transform.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.transform.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
					)
					animationRange = interval debb finn	
	-----end对齐帧处理-----
					
	------------查找蒙皮中具有bip字样的模型并一起选择---------------
		if selection.count !=0 then(		  
			actionMan.executeAction 0 "283"  -- Tools: Unfreeze All
			max unfreeze all
			allTheSkin = for obj in objects where (classof obj==PolyMeshObject)  collect obj
			for f in allTheSkin do(
			skinMods = getclassinstances Skin target:f 
			max modify mode
			modPanel.setCurrentObject f.modifiers[#Skin]
			skinOps.getnumberbones skinMods[1]
			bonename =skinOps.getBoneName skinMods[1] 1 0
			bonename =skinOps.getBoneName skinMods[1] 2 0	
			if findString bonename "Bip" ==1 then (join mysel f)else(deselect f)
			selectmore mysel
			)
		)
		---------只输出bip模型------------
	
				----start 输出model.fbx---	
				if selection.count !=0 then(		
				AA=Dir+"/"+FileName+"."+"model"+".fbx"	
				exportFile  AA #noPrompt selectedOnly:true using:fbxexp
				)
				----end 输出model.fbx---
			) 
			
			 ------重置max场景-------
			resetMaxFile #noPrompt	
		)
	----删除导入机制生产的备份文件---
		
	 ---排除掉新产生的backup文件--
	 NewFiles=getfiles (DIR+"\*.max")
	
	 for j = 1 to OldFiles.count do	while (index = (findItem NewFiles OldFiles[j])) != 0 do (deleteItem NewFiles index)
	 WillDelFiles=NewFiles
	---排除掉新产生的backup文件end--
 
	for a in WillDelFiles do
	(			
		deletefile a
		) 
	----删除导入机制生产的备份文件---
		
	----释放全局变量DIR	
 	free(DIR)
	)
 )

-------------------------------------------------------------	
globalrollout = newrolloutfloater "导ue4模型和相机工具集" 200 535
addRollout export_UE4Cam_v2 globalrollout
addRollout exportFBX globalrollout
addRollout exportFBX_ue4cam_v1 globalrollout
addRollout exportFBX_ue4cam_v2 globalrollout 
-------------------------------------------------------------------------

------分部件代码展示:-----

cs 复制代码
 rollout export_UE4Cam_v2 "导出UE4Cam_v2:半自动" width:200 height:120
 (
	HyperLink  explain "在打开的max文件中使用" pos:[25,12] width:200 height:15 color:(color 255 155 0)	 
	GroupBox grp1 "要导出的相机名" pos:[5,28] width:179 height:40
	pickbutton OutCam "拾取相机" pos:[20,40] width:150 height:20
	GroupBox grp2 "要导出的fbx文件名" pos:[5,70] width:179 height:50
	button	 bt_create	"Create UE4 Camera" pos:[20,85] width:150 height:32 enabled:true
	 
-----逐行写入文本------------
fn format_txt FilePath filetext1 filetext2=
(	
	if doesFileExist FilePath == true
		then
	(
		fin = openfile FilePath mode:"r+"
		seek fin #eof
		txt = filetext1+RenderWidth as string+"\n"+filetext2+RenderHeight as string+"\n"
		format txt to:fin
		close fin
	)
	else
	(
		newfile = createFile FilePath writeBOM:true
		close newfile
		format_txt FilePath filetext1 filetext2
		)
)
-----end逐行写入文本-----------------

    on OutCam picked obj do
    (
     OutCam.text = obj.name
        )
 
 	on bt_create pressed do
 	(		
		Freecamera fov:45 targetDistance:314.512 nearclip:1 farclip:1000 nearrange:0 farrange:1000 mpassEnabled:off mpassRenderPerPass:off pos:[0,0,0] isSelected:on
		mycam = OutCam.text
		$.name = mycam
		UE4CAM =$
		MAXCAM =getnodebyname mycam
		UE4CAM.Position=MAXCAM.position
		UE4CAM.FOV=MAXCAM.FOV
		--位置约束
		UE4CAM.Position.controller= Position_Constraint ()
		A = UE4CAM.Position.controller
		A.appendTarget MAXCAM 100
		--方向约束
		UE4CAM.rotation.controller= Orientation_Constraint ()
		B = UE4CAM.rotation.controller
		
		B.appendTarget MAXCAM 100

		--开始塌陷
				local forceUpdate = keyboard.shiftPressed -- if SHIFT is pressed when the macro is called, a viewport redraw is enforced for each timestep to ensure a full update of all controllers
				if forceUpdate then format "MB Collapse: Enforcing full viewport update. This might be slow but will ensure proper updating of all controllers\n"
				
					local p = undefined
					local old_prs_ctrl = copy UE4CAM.transform.controller		-- store old controller for catch()
					with undo on (
						if not forceUpdate then disableSceneRedraw();	-- not using redraw context for max4 compatibility
						-- disableSceneRedraw is problematic as not all scripted controllers are updated!
						try (
							p = Point()			-- create temp point object
							-- copy global transform of source object into temp object
							for i = animationRange.start to animationRange.end do (
								if forceUpdate then sliderTime = i	-- set slider time to force a global update of all animation data
								at time i (
									with animate on p.transform = UE4CAM.transform
								)
							)
							-- kill old transform controller and assign new, clean one
							UE4CAM.transform.controller = transform_script()	
							UE4CAM.transform.controller = prs()	
							
							if not (isGroupMember UE4CAM) then UE4CAM.parent = undefined	-- unlink if not in a group
							-- copy temp object animation back into source object
							for i = animationRange.start to animationRange.end do (
								at time i (
									with animate on	UE4CAM.transform = p.transform
								)
							)

							delete p			-- delete temp point obj
							p = undefined
							if not forceUpdate then enableSceneRedraw()
						)--try
					catch(
						format "coder zsz:QQ  : Fatal error - exiting\n"
									if p!=undefined then delete p
									UE4CAM.transform.controller = old_prs_ctrl
									if not forceUpdate then enableSceneRedraw()
						  )-- catch				
					)--with undo
		--塌陷结束
					
		-----导出fbx文件----
        -- 使用一个.net文件windows窗口---导出fbx文件
		browse_dialog = dotNetObject "System.Windows.Forms.SaveFileDialog" --建立一个打开文件对话框
		DotNetFile = DotNetClass "System.IO.File"--创建.net文件
		browse_dialog.title = "保存文件" --设置标题
		browse_dialog.Filter = "fbx Files (*.fbx)|*.fbx|All Files (*.*)|*.*" --确认这个文件过滤
		browse_dialog.fileName = trimright maxfilename ".max"
		browse_dialog.FilterIndex = 2 --设置文件过滤下拉菜单长度
		result = browse_dialog.showDialog() --显示对话框,得到的结果进变量
		if (result.Equals result.OK) then
		(
			if ( not (DotNetFile.Exists browse_dialog.FileName)) then
			(
				select UE4CAM
				if selection.count !=0 then(	
				AA=browse_dialog.fileName+".fbx"
				exportFile AA  #noPrompt selectedOnly:true using:fbxexp
				BB=browse_dialog.fileName+".TXT"
				format_txt BB "renderWidth=" "renderHight="
				)
			)

		)			
		--删除相机 	
		delete UE4CAM
        free(filepath)					
	)
	
 )
javascript 复制代码
rollout exportFBX "导出fbx模:半自动" width:200 height:100
 (
	HyperLink explain "在打开的max文件中使用" pos:[25,0] width:200 height:15 color:(color 255 155 0)	 
	GroupBox grp1 "要导出的角色根骨骼" pos:[5,15] width:179 height:80
	pickbutton PickRoot "拾取根骨骼" pos:[20,30] width:150 height:20
	button	 bt_OutFBX	"输出fbx模型" pos:[20,55] width:150 height:30 enabled:true

	 on PickRoot picked obj do
 	( 
		PickRoot.text = obj.name
	)		
	 on bt_OutFBX pressed do
 	( 
		ChrBone=getnodebyname PickRoot.text
		select ChrBone
		--根据根选择此层级所有物体
		if selection.count !=0 then(
			fn getTheChildren obj:selection[1] includeParent:false = (execute ("$'" + (obj.name)+"'/"+(if includeParent then "" else "*/")+".../*"))
			  
			  select (getTheChildren includeParent:true)
			  select (getTheChildren())
			  
			  getTheChildren includeParent:true as array
			  getTheChildren() as array
		  )
		mysel=selection as array 
		-----对齐帧处理-----
					debb = 10000
					finn=-10000 
						for a in selection do
					(
						if  (classof a == BoneGeometry) then(
							if (numKeys a.position.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.position.controller
								starttime = getkeytime a.position.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.position.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
						if (classof a == Biped_Object) then(
							if (numKeys a.transform.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.transform.controller
								starttime = getkeytime a.transform.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.transform.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
					)
					animationRange = interval debb finn	
	-----end对齐帧处理-----
					
	------------查找蒙皮中具有bip字样的模型并一起选择---------------
		if selection.count !=0 then(
			actionMan.executeAction 0 "283"  -- Tools: Unfreeze All
			max unfreeze all	  
			allTheSkin = for obj in objects where (classof obj==PolyMeshObject)  collect obj
			for f in allTheSkin do(
			skinMods = getclassinstances Skin target:f 
			max modify mode
			modPanel.setCurrentObject f.modifiers[#Skin]
			skinOps.getnumberbones skinMods[1]
			bonename =skinOps.getBoneName skinMods[1] 1 0
			bonename =skinOps.getBoneName skinMods[1] 2 0	
			if findString bonename "Bip" ==1 then (join mysel f)else(deselect f)
			selectmore mysel
			)
		)
        -----使用一个.net文件windows窗口---导出fbx文件------
		browse_dialog = dotNetObject "System.Windows.Forms.SaveFileDialog" --建立一个打开文件对话框
		DotNetFile = DotNetClass "System.IO.File"--创建.net文件
		browse_dialog.title = "保存文件" --设置标题
		browse_dialog.Filter = "fbx Files (*.fbx)|*.fbx|All Files (*.*)|*.*" --确认这个文件过滤
		browse_dialog.fileName = trimright maxfilename ".max"
		browse_dialog.FilterIndex = 2 --设置文件过滤下拉菜单长度
		result = browse_dialog.showDialog() --显示对话框,得到的结果进变量
		if (result.Equals result.OK) then
		(
			if ( not (DotNetFile.Exists browse_dialog.FileName)) then
			(
				if selection.count !=0 then(	
				AA=browse_dialog.fileName+"."+"model"+".fbx"
				exportFile AA #noPrompt selectedOnly:true using:fbxexp
				)
			)

		)
	)
 )
javascript 复制代码
 rollout exportFBX_ue4cam_v1 "批出fbx模&UEcam_V1:自动" width:200 height:120
 (
HyperLink explain "指定目录即可,不需要打开文件" pos:[25,0] width:200 height:15  color:(color 255 155 0)
edittext selfile "" pos:[10,20] width:140 height:19 text:"...请选择目录"
button btn_browse "..."  pos:[160,20] width:30 height:19 
checkBox ignore "忽略backup文件" pos:[60,40] width:100 height:19
-- radioButtons rdo1 "" pos:[30,40] width:168 height:16 labels:#("输出相机", "输出模型") default:1 columns:2	 
button	 bt_create	"批量输出fbx" pos:[20,60] width:150 height:32 enabled:true

-------逐行写入文本------------
fn format_txt filepath filetext1 filetext2=
(	
	if doesFileExist filepath == true
		then
	(
		fin = openfile filepath mode:"r+"
		seek fin #eof
		txt = filetext1+RenderWidth as string+"\n"+filetext2+RenderHeight as string+"\n"
		format txt to:fin
		close fin
	)
	else
	(
		newfile = createFile filepath writeBOM:true
		close newfile
		format_txt filepath filetext1 filetext2
		)
)  -- 逐行写入文本	 
	 
	 on btn_browse pressed do
 	( 		
		global DIR = getSavePath caption:"选择max目录"
		if (DIR != undefined) then ( selfile.text = dir )
	)		
	 on bt_create pressed do
 	( 
	 files =DIR+"\*.max"
	OldFiles=getfiles files	
	GetFile= getFiles files	 
	if (ignore.checked) then(
		 ---排除掉backup文件--
		 UndoFiles=getfiles (DIR+"\*backup*.max")
		 for j = 1 to UndoFiles.count do	while (index = (findItem GetFile UndoFiles[j])) != 0 do (deleteItem GetFile index)
		---排除掉backup文件end--	 
	)	
	 Maxfiles=GetFile
		 
	 for f in Maxfiles do (
		--打开max文件--- 
		 loadMaxfile f missingExtFilesAction:#logmsg

		---切割文本内容
		mydir=trimRight f ".max"
		global filename=trimLeft mydir DIR
        global filepath=(DIR+"/"+filename+".txt") as string		 
 		--------start 输出model.fbx-------	
		 
		---------只输出bip模型------------
		--选择所有bip物体
		select $'*bip*' 
			
		mysel= selection as array
		--根据bip选择根
		for f in mysel do(
		fn getRoot node = if isvalidnode node do (while node.parent != undefined do node = node.parent; node)
		aaa=getRoot f
		select aaa
		)
		--根据根选择此层级所有物体
		if (selection.count !=0) then(
			fn getTheChildren obj:selection[1] includeParent:false = (execute ("$'" + (obj.name)+"'/"+(if includeParent then "" else "*/")+".../*"))
			  
			  select (getTheChildren includeParent:true)
			  select (getTheChildren())
			  
			  getTheChildren includeParent:true as array
			  getTheChildren() as array
		  )

		if (selection.count !=0) do(
		-----对齐帧处理-----
					debb = 10000
					finn=-10000 
						for a in selection do
					(
						if  (classof a == BoneGeometry) then(
							if (numKeys a.position.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.position.controller
								starttime = getkeytime a.position.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.position.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
						else if (classof a == Biped_Object) then(
							if (numKeys a.transform.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.transform.controller
								starttime = getkeytime a.transform.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.transform.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
					)
					animationRange = interval debb finn	

	-----end对齐帧处理-----
				)
				
	------------查找蒙皮中具有bip字样的模型并一起选择---------------
		if selection.count !=0 then(
			actionMan.executeAction 0 "283"  -- Tools: Unfreeze All
			max unfreeze all	  
			allTheSkin = for obj in objects where (classof obj==PolyMeshObject)  collect obj
			for f in allTheSkin do(
			skinMods = getclassinstances Skin target:f 
			max modify mode
			modPanel.setCurrentObject f.modifiers[#Skin]
			skinOps.getnumberbones skinMods[1]
			bonename =skinOps.getBoneName skinMods[1] 1 0
			bonename =skinOps.getBoneName skinMods[1] 2 0	
			if findString bonename "Bip" ==1 then (join mysel f)else(deselect f)
			selectmore mysel
			)
		)
		---------只输出bip模型------------

		if selection.count !=0 then(
        AA=Dir+"/"+filename+"."+"model"+".fbx"	
		exportFile  AA #noPrompt selectedOnly:true using:fbxexp
		deselect $	
		)
		----end 输出model.fbx---
		 
		 --选择相机(包括隐藏的)跳过目标物体
		camsARr = for o in cameras where classof o != targetobject collect o
		select camsARr  filter:FilterCameras showHidden:true
		MaxCamSelSet = selection as array	
		------start输出cam.fbx------
		for i in MaxCamSelSet do(
					MAXCAM= i
	
					Freecamera fov:45 targetDistance:314.512 nearclip:1 farclip:1000 nearrange:0 farrange:1000 mpassEnabled:off mpassRenderPerPass:off pos:[0,0,0] isSelected:on
					hide $
					$.name =FileName+"."+i.name --设置相机名称
					UE4CAM =$
					UE4CAM.Position=MAXCAM.position
					UE4CAM.FOV=MAXCAM.FOV
						
					--位置约束
					UE4CAM.Position.controller= Position_Constraint ()
					A = UE4CAM.Position.controller
					A.appendTarget MAXCAM 100
					--方向约束
					UE4CAM.rotation.controller= Orientation_Constraint ()
					B = UE4CAM.rotation.controller
					
					B.appendTarget MAXCAM 100

		--开始塌陷
				local forceUpdate = keyboard.shiftPressed -- if SHIFT is pressed when the macro is called, a viewport redraw is enforced for each timestep to ensure a full update of all controllers
				if forceUpdate then format "MB Collapse: Enforcing full viewport update. This might be slow but will ensure proper updating of all controllers\n"
				
					local p = undefined
					local old_prs_ctrl = copy UE4CAM.transform.controller		-- store old controller for catch()
					with undo on (
						if not forceUpdate then disableSceneRedraw();	-- not using redraw context for max4 compatibility
						-- disableSceneRedraw is problematic as not all scripted controllers are updated!
						try (
							p = Point()			-- create temp point object
							-- copy global transform of source object into temp object
							for i = animationRange.start to animationRange.end do (
								if forceUpdate then sliderTime = i	-- set slider time to force a global update of all animation data
								at time i (
									with animate on p.transform = UE4CAM.transform
								)
							)
							-- kill old transform controller and assign new, clean one
							UE4CAM.transform.controller = transform_script()	
							UE4CAM.transform.controller = prs()	
							
							if not (isGroupMember UE4CAM) then UE4CAM.parent = undefined	-- unlink if not in a group
							-- copy temp object animation back into source object
							for i = animationRange.start to animationRange.end do (
								at time i (
									with animate on	UE4CAM.transform = p.transform
								)
							)
							delete p			-- delete temp point obj
							p = undefined
							if not forceUpdate then enableSceneRedraw()
						)--try
					catch(
						format "coder zsz:QQ  : Fatal error - exiting\n"
									if p!=undefined then delete p
									UE4CAM.transform.controller = old_prs_ctrl
									if not forceUpdate then enableSceneRedraw()
						  )-- catch				
					)--with undo
		--塌陷结束

					----对齐相机的关键帧到动画范围---

					debb = 10000
					finn=-10000 
					for a in selection do
					(
						if (numKeys a.position.controller > 0)then(
							sortKeys a.controller
							num_keys = numkeys a.position.controller
							starttime = getkeytime a.position.controller 1
							endtime = starttime
							for O = 1 to num_keys do 
							(
						 
								key_time = getkeytime a.position.controller O
								if key_time > endtime then
									 endtime = key_time
							)
							if starttime < debb then debb = starttime
							if endtime > finn then finn = endtime
						)
						else(
							starttime = 1
							endtime = 100				
							if starttime < debb then debb = starttime
							if endtime > finn then finn = endtime				
							)
					)
					animationRange = interval debb finn	
					----对齐相机的关键帧到动画范围end---	
					
		--------导出fbx文件-------
						CAM=MAXCAM.name
						BB=DIR+"/"+filename+"."+CAM+".fbx"

					exportFile  BB #noPrompt selectedOnly:true using:fbxexp	
					
				)	
		------end输出cam.fbx------
				
-- 		------输出cam.txt------
		if MaxCamSelSet.count !=0 then(		
		format_txt filepath "renderWidth=" "renderHight="
		)
-- 		------end输出cam.txt------	
			
		 ------重置max场景-------		
		resetMaxFile #noPrompt
		
		)
	----删除导入机制生产的备份文件---
		
	 ---排除掉新产生的backup文件--
	 NewFiles=getfiles (DIR+"\*.max")
	
	 for j = 1 to OldFiles.count do	while (index = (findItem NewFiles OldFiles[j])) != 0 do (deleteItem NewFiles index)
	 WillDelFiles=NewFiles
	---排除掉新产生的backup文件end--
 
	for a in WillDelFiles do
	(			
		deletefile a
		) 
	----删除导入机制生产的备份文件---
		
	----释放全局变量DIR	
 	free(DIR)
	)
 )
javascript 复制代码
 rollout exportFBX_ue4cam_v2 "批出fb模&UEcam_V2:模式自选" width:200 height:100
 (
HyperLink explain "指定目录即可,不需要打开文件" pos:[25,0] width:200 height:15 color:(color 255 155 0)
edittext selfile "" pos:[10,15] width:140 height:19 text:"...请选择目录"
button btn_browse "..."  pos:[160,15] width:30 height:19
checkBox ignore "忽略backup文件" pos:[60,35] width:100 height:19
label explain1 "输出相机是打开模式,输出模型是导入模式" pos:[0,64] width:200 height:15 
radioButtons rdo1 "" pos:[30,50] width:168 height:16 labels:#("输出相机", "输出模型") default:1 columns:2	 
button	 bt_create	"批量输出fbx" pos:[20,80] width:150 height:32 enabled:true

---函数部分--
 fn LoadOrMergeFile f = (
		 if rdo1.state ==1 then (
			loadMaxfile f missingExtFilesAction:#logmsg
		)
		if rdo1.state ==2 then (
			mergeMaxfile f 
		)
 )  

---------逐行写入文本------------
fn format_txt FilePath filetext1 filetext2=
(	
	if doesFileExist FilePath == true
		then
	(
		fin = openfile FilePath mode:"r+"
		seek fin #eof
		txt = filetext1+RenderWidth as string+"\n"+filetext2+RenderHeight as string+"\n"
		format txt to:fin
		close fin
	)
	else
	(
		newfile = createFile FilePath writeBOM:true
		close newfile
		format_txt FilePath filetext1 filetext2
		)
)
-- 逐行写入文本
			
---///end函数部分--
	 on btn_browse pressed do
 	( 
		global DIR = getSavePath caption:"选择max目录"
		if (DIR != undefined) do ( selfile.text = DIR )	
	)	
	
	 on bt_create pressed do
 	( 
	 files =DIR+"/"+"*.max"
	 OldFiles=getfiles files	
	 GetFile= getFiles files
    if (ignore.checked)then(		
 	 ---排除掉backup文件--
	 WillDelFiles=getfiles (DIR+"\*backup*.max")
	 for j = 1 to WillDelFiles.count do	while (index = (findItem GetFile WillDelFiles[j])) != 0 do (deleteItem GetFile index)
	---排除掉backup文件end-- 
	)
	
	Maxfiles=GetFile 
		 
	 for f in Maxfiles do (
			---切割文本内容
			mydir=trimRight f ".max"
			global FileName=trimLeft mydir DIR
			global FilePath=(DIR+"/"+FileName+".txt") as string	
			--导入max文件--- 
			LoadOrMergeFile f	 
			----输出model.fbx ---		 
	-- 		ExportModel,见 rdo1的写在那里面
			 if rdo1.state ==1 then (
		---选择相机(包括隐藏的)跳过目标物体
		camsArr = for o in cameras where classof o != targetobject collect o
		select camsArr  filter:FilterCameras showHidden:true
		MaxCamSelSet = selection as array	
		------start输出cam.fbx------
		for i in MaxCamSelSet do(
					MAXCAM= i
			
					Freecamera fov:45 targetDistance:314.512 nearclip:1 farclip:1000 nearrange:0 farrange:1000 mpassEnabled:off mpassRenderPerPass:off pos:[0,0,0] isSelected:on
					hide $
					$.name =FileName+"."+i.name --设置相机名称
					UE4CAM =$
					UE4CAM.Position=MAXCAM.position
					UE4CAM.FOV=MAXCAM.FOV
						
					--位置约束
					UE4CAM.Position.controller= Position_Constraint ()
					A = UE4CAM.Position.controller
					A.appendTarget MAXCAM 100
					--方向约束
					UE4CAM.rotation.controller= Orientation_Constraint ()
					B = UE4CAM.rotation.controller
					
					B.appendTarget MAXCAM 100

		--开始塌陷
				local forceUpdate = keyboard.shiftPressed -- if SHIFT is pressed when the macro is called, a viewport redraw is enforced for each timestep to ensure a full update of all controllers
				if forceUpdate then format "MB Collapse: Enforcing full viewport update. This might be slow but will ensure proper updating of all controllers\n"
				
					local p = undefined
					local old_prs_ctrl = copy UE4CAM.transform.controller		-- store old controller for catch()
					with undo on (
						if not forceUpdate then disableSceneRedraw();	-- not using redraw context for max4 compatibility
						-- disableSceneRedraw is problematic as not all scripted controllers are updated!
						try (
							p = Point()								-- create temp point object
							
							-- copy global transform of source object into temp object
							for i = animationRange.start to animationRange.end do (
								if forceUpdate then sliderTime = i	-- set slider time to force a global update of all animation data
								at time i (
									with animate on p.transform = UE4CAM.transform
								)
							)
							-- kill old transform controller and assign new, clean one
							UE4CAM.transform.controller = transform_script()	
							UE4CAM.transform.controller = prs()	
							
							if not (isGroupMember UE4CAM) then UE4CAM.parent = undefined	-- unlink if not in a group
							-- copy temp object animation back into source object
							for i = animationRange.start to animationRange.end do (
								at time i (
									with animate on	UE4CAM.transform = p.transform
								)
							)
							delete p			-- delete temp point obj
							p = undefined
							if not forceUpdate then enableSceneRedraw()
						)--try
					catch(
						format "coder zsz:QQ  : Fatal error - exiting\n"
									if p!=undefined then delete p
									UE4CAM.transform.controller = old_prs_ctrl
									if not forceUpdate then enableSceneRedraw()
						  )-- catch				
					)--with undo
		--塌陷结束
					
					----对齐相机的关键帧到动画范围---
					debb = 10000
					finn=-10000 
					for a in selection do
					(
						if (numKeys a.position.controller > 0)then(
							sortKeys a.controller
							num_keys = numkeys a.position.controller
							starttime = getkeytime a.position.controller 1
							endtime = starttime
							for O = 1 to num_keys do 
							(
						 
								key_time = getkeytime a.position.controller O
								if key_time > endtime then
									 endtime = key_time
							)
							if starttime < debb then debb = starttime
							if endtime > finn then finn = endtime
						)
						else(
							starttime = 1
							endtime = 100				
							if starttime < debb then debb = starttime
							if endtime > finn then finn = endtime				
							)
					)
					animationRange = interval debb finn	
					----对齐相机的关键帧到动画范围end---	
					
		--------导出fbx文件-------
					CAM=MAXCAM.name
					FBXFileName=DIR+"/"+FileName+"."+CAM+".fbx"
					exportFile FBXFileName #noPrompt selectedOnly:true using:fbxexpp	
				)	
		------end输出cam.fbx------
				 
				------输出cam.txt------
				if MaxCamSelSet.count !=0 then(				
				format_txt FilePath "renderWidth=" "renderHight="
				)
				------end输出cam.txt------
				 
			)
			if rdo1.state ==2 then (

		---------只输出bip模型------------
		--选择所有bip物体
		select $'*bip*' 
		
		mysel= selection as array
		--根据bip选择根
		for f in mysel do(
		fn getRoot node = if isvalidnode node do (while node.parent != undefined do node = node.parent; node)
		aaa=getRoot f
		select aaa
		)
		--根据根选择此层级所有物体
		if selection.count !=0 then(
		fn getTheChildren obj:selection[1] includeParent:false = (execute ("$'" + (obj.name)+"'/"+(if includeParent then "" else "*/")+".../*"))
		  
		  select (getTheChildren includeParent:true)
		  select (getTheChildren())
		  
		  getTheChildren includeParent:true as array
		  getTheChildren() as array
		)
		-----对齐帧处理-----
					debb = 10000
					finn=-10000 
						for a in selection do
					(
						if  (classof a == BoneGeometry) then(
							if (numKeys a.position.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.position.controller
								starttime = getkeytime a.position.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.position.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
						if (classof a == Biped_Object) then(
							if (numKeys a.transform.controller > 0)then(
								sortKeys a.controller
								num_keys = numkeys a.transform.controller
								starttime = getkeytime a.transform.controller 1
								endtime = starttime
								for O = 1 to num_keys do 
								(
							 
									key_time = getkeytime a.transform.controller O
									if key_time > endtime then
										 endtime = key_time
								)
								if starttime < debb then debb = starttime
								if endtime > finn then finn = endtime
							)
						)
					)
					animationRange = interval debb finn	
	-----end对齐帧处理-----
					
	------------查找蒙皮中具有bip字样的模型并一起选择---------------
		if selection.count !=0 then(		  
			actionMan.executeAction 0 "283"  -- Tools: Unfreeze All
			max unfreeze all
			allTheSkin = for obj in objects where (classof obj==PolyMeshObject)  collect obj
			for f in allTheSkin do(
			skinMods = getclassinstances Skin target:f 
			max modify mode
			modPanel.setCurrentObject f.modifiers[#Skin]
			skinOps.getnumberbones skinMods[1]
			bonename =skinOps.getBoneName skinMods[1] 1 0
			bonename =skinOps.getBoneName skinMods[1] 2 0	
			if findString bonename "Bip" ==1 then (join mysel f)else(deselect f)
			selectmore mysel
			)
		)
		---------只输出bip模型------------
	
				----start 输出model.fbx---	
				if selection.count !=0 then(		
				AA=Dir+"/"+FileName+"."+"model"+".fbx"	
				exportFile  AA #noPrompt selectedOnly:true using:fbxexp
				)
				----end 输出model.fbx---
			) 
			
			 ------重置max场景-------
			resetMaxFile #noPrompt	
		)
	----删除导入机制生产的备份文件---
		
	 ---排除掉新产生的backup文件--
	 NewFiles=getfiles (DIR+"\*.max")
	
	 for j = 1 to OldFiles.count do	while (index = (findItem NewFiles OldFiles[j])) != 0 do (deleteItem NewFiles index)
	 WillDelFiles=NewFiles
	---排除掉新产生的backup文件end--
 
	for a in WillDelFiles do
	(			
		deletefile a
		) 
	----删除导入机制生产的备份文件---
		
	----释放全局变量DIR	
 	free(DIR)
	)
 )
相关推荐
二DUAN帝2 天前
UE实现路径回放、自动驾驶功能简记
人工智能·websocket·机器学习·ue5·自动驾驶·ue4·cesiumforue
3A是个坏同志1 个月前
UE4手动实现billboard效果让物体始终面向相机正面
ue4
致命的邂逅2 个月前
UE4游戏查找本地角色数据的方法-SDK
游戏·ue4
北冥没有鱼啊2 个月前
UE 材质几个输出向量节点
ue5·游戏引擎·ue4·虚幻·材质
北冥没有鱼啊2 个月前
UE 材质 条纹循环发光
游戏·ue5·游戏引擎·ue4·材质
北冥没有鱼啊2 个月前
UE 滚动提示条材质制作
游戏·ue5·游戏引擎·ue4·虚幻·材质
北冥没有鱼啊3 个月前
UE 使用事件分发器设计程序
游戏·ue5·ue4·游戏开发·虚幻
GR903 个月前
UE4 踩坑记录
ue4
程序猿熊跃晖3 个月前
解决 Unreal Engine 5.2 中服务器目标构建问题:从源码编译到项目配置优化
ue4
Ⅰㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ3 个月前
开篇 - Unlua+VsCode的智能提示、调试
vscode·ue4·智能提示·unlua