Maya:ScriptNode 弹出菜单出现错误 "invalid directive"

Maya : ScriptNode pop up menu with error "invalid directive"

我正在编写一个 GUI 和脚本,当特定对象在场景中被 select 时执行。我以前没有任何问题,但现在我...

当我 select 我的对象时,我创建的 scriptJob 说要启动程序...此时,它没有。进一步研究它,我尝试测试 scriptNode,结果是:

// Error:  //
// Error: Line 0.0: invalid directive //

现在,我最初遇到这个问题是因为出现了“;”在我的评论中。我删除了我能找到的所有分号...它工作了一次,然后就停止工作了。

============================================= ============================

另一个补充...我已经从我的脚本中删除了所有要嵌入的注释,它现在将我的 类 称为语法错误。见下文:

// Error: class x2m_info: //
// Error: Line 9.15: Syntax error //

我还应该包括 运行 脚本通常 DOES 使其正常工作。这严格来说是 运行 作为 scriptNode 和 scriptJob。

============= 下面是尝试复制 ==============

# Below is a saved py file, its mother file is similar and run in Maya
# Let us say it is saved in this dir, "D:\USER\JAMES\" as "coolscript.py"
import modules # a list of modules, os, sys, subprocess, etc.
class numberOne: # Interpret this as the x2m_info class I specified above
    def about_info(self, x):
        # Does stuff
        if x==1:
            print("Does stuff, like display information: %s" % x)
        else:
            print("Does stuff, like display contact info: %s" % x)
    # Has a few more similar functions

class something:
     def func1(self, x):
         numberOne().about_info(1)
     def func2(self):
         numberOne().about_info(2)
def main():
    something().func1(1)
    something().func1(2)

import maya.cmds as cmds
# Portion in Maya that takes this and embeds it
embedThisFile = "D:\USER\JAMES\coolscript.py"
embeddedStr   = open(embedThisfile, "r")
embed         = embeddedStr.read()
cmds.scriptNode(name="WhereToEmbed", beforeScript=embed, scriptType=1, sourceType="python")

scriptToVar   = cmds.scriptNode("WhereToEmbed", query=1, beforeScript=1)
scriptJobName = cmds.scriptJob(conditionTrue=("SomethingSelected",
                               "if (cmds.ls(selected=1)[0]) == 'pCube1':\
                               exec('%s'); main()" % (scriptToVar)),
                               killWithScene=1, protected=1)

您的方法在 Maya 中完全合法。

将 mel 代码翻译成 Pymel

我们大多数人都是通过监视脚本编辑器来学习 Maya 命令的。它在 Maya 中打印命令。将mel代码翻译成python是有一定顺序的。首先让我们看看mel command sample for scriptJob。您可以在页面底部找到示例代码。请参阅此示例代码行:

//create a job that deletes things when they are seleted
int $jobNum = `scriptJob -ct "SomethingSelected" "delete" -protected`;

-ct 标志是 shorthand for for conditionTrue.

{flag} -ct {space} {first parameter} "SomethingSelected" {space}
              {second parameter-this is the command to execute} "delete". 

所以当你将这个命令翻译成pymel时我们必须遵循以下顺序:

cmds.command(flag_1=paramaters,flag_2=paramaters,.......,flag_n=paramaters)

当你必须传递多个标志时,你必须将它们放入数组、列表或元组中。他们必须遵循正确的顺序。通常对象名称是第一个参数。

cmds.command(flag=[parameter_1,parameter_1,....,parameter_n])

所以在你的情况下:

scriptJobName = cmds.scriptJob(conditionTrue=["SomethingSelected",
    "if (cmds.ls(selected=1)[0]) == 'pCube1':exec('%s'); main()" 
    % (scriptToVar)], killWithScene=1, protected=1,)

conditionTrue = [条件,你的脚本]

但是,如果您设置的条件都正确,它可以帮助更改代码在 scriptJob 内部的 运行 方式。主要是:

exec('%s')

应该是:

exec('''%s''')

考虑到正在嵌入的代码中的任何注释、换行符、returns 或 semi-colons...三引号充当注释块,反过来有助于处理整个代码都是真实的。

在您的示例代码中,语法错误 是 Maya 没有看到针对条件执行的代码。 无效指令 是 Maya 无法处理代码并在某一点挂起,因为它正在尝试将命令作为指令处理("flag" 的 MEL 术语)。

这都是由不正确的嵌套引号造成的。尽管您所做的是合法且可行的,但如果您有注释 ("#")、semi-colons (";") 以及 new-lines 和 returns ("\n","\ r",分别),最好提供一个块注释...单引号/双引号可能与代码中已有的信息冲突,并且会错误地拆分代码。

这应该可以解决您的问题。

有关 pyMel 中的 scriptJobs 的更多信息,请查看以下内容:

see the sample pymel code for scriptJob

您的情况可能过于复杂,您可以简单地注入一个事件消息并通过它来处理。这是一个例子

runInsideMaya.py

import maya.cmds as cmds
import maya.OpenMaya as OpenMaya
import runpy
def testMod(*args, **kwargs):
    getCurrentSel = cmds.ls(sl=True)
    if getCurrentSel:
        if getCurrentSel[0] == "pSphere2":
            fileToInclude = "/tmp/whatIsSelected.py"
            runpy.run_path(fileToInclude, run_name='__main__')

idx = OpenMaya.MEventMessage.addEventCallback("SelectionChanged", testMod)

#when ever you finish doing your stuff
#OpenMaya.MMessage.removeCallback(idx)

whatIsSelected.py

import maya.cmds as cmds

def testFunc():
    getSelection = cmds.ls(sl=True) or []
    if getSelection:
        print "You selected %s" % getSelection[0]

if __name__ == '__main__':
    testFunc()

因此,只要有选择更改,它就会触发事件,如果选择是 pSphere2,它将调用外部 script.Also 尽可能远离 scriptsjobs。