我有一个简短的Maya脚本,只是在一个圆圈中连续旋转相机。问题是,当我尝试运行脚本时,一旦它运行,我就不能关闭应用程序,直到我杀死脚本。我正在使用cmd .refresh(),但这只刷新UI,仍然延迟其他操作(如关闭程序)。我知道我可以手工终止脚本,但我希望能够通过回调或其他类似的事情以编程方式完成。
下面是我的代码现在的样子:import sys
import time
import maya.cmds as cmds
import maya.api.OpenMayaUI as omui
view = omui.M3dView.active3dView()
currentCamera = view.getCamera()
while(True):
cmds.orbit(currentCamera, ha = 1)
view.setCamera(currentCamera)
cmds.refresh()
time.sleep(.01)
基本上有什么我可以放在while()而不是"True",将杀死脚本自动当你去关闭程序?或者我可以做一些完全不同的事情?
您真的不想在这里使用while True:
。Maya是非常老式的线程——从一个单独的线程触摸可视场景或UI是一个禁忌——所以你不能很容易地创建你想要的行为,而不完全接管Maya会话。不幸的是,这会给你带来你正在经历的行为。
你可以尝试两种基本策略:
简单的事情是使用一个maya scriptjob在'idle'事件上触发。这只会在Maya没有做任何其他事情的时候运行——因为Maya在主线程中为你触发它——不会导致任何问题。然而,这只会在Maya没有做任何其他事情时触发——所以如果用户在UI或场景中做某事,你的脚本不会触发。比如:
def orbit_cam():
cmds.orbit('persp', ha = .01)
cmds.scriptJob(e=('idle', orbit_cam))
这样做的最大缺点是你无法控制脚本触发的频率:这取决于Maya。
第二个选项是创建一个单独的线程,以您自己的方式触发脚本。但是,这里必须小心,因为从第二个线程触发的函数将导致崩溃,除非您将它们封装在对maya.util.executeDeferred的调用中。
更多背景知识:如何使用python (maya)多线程以及如何定期执行maya MEL过程
您可以将scriptJob
附加到idle
事件。
import time
import sys
import maya.cmds as cmds
import maya.api.OpenMayaUI as omui
view = omui.M3dView.active3dView()
currentCamera = view.getCamera()
def rotate_camera():
cmds.orbit(currentCamera, ha = 1)
view.setCamera(currentCamera)
cmds.refresh()
time.sleep(.01)
cmds.scriptJob(event=['idle', rotate_camera], killWithScene=True)
这将持续旋转相机,同时允许用户随时退出应用程序或与UI交互。请注意,您可能需要一个回调,用于在动画结束时删除脚本作业。