一半君的总结纸

听话只听一半君

#83 如何做到当我选择一个物体, Maya 就自动选择另一个物体?

在MEL里唯一能做到监视选择变化的方法是使用 scriptJob. 当你用鼠标点击某个物体的时候,没有什么物体上的属性能表示他当前被选中了,在DG里也没有一个”dirty”的属性来表示此DG被选中了.

这时有个可能你没想到的问题: 这个事件并不会告诉你刚才你选择了(或者减选了)什么 , 他只会告诉你选择发生了变化. 你得自己去拿到哪些物体被选中或者减选了.

还有一个 问题: 只要你在SelectionChanged 事件(event)发生后去选了别的物体, 你将会把这个操作加到undo queue里. 假如你尝试ctrl+z来 undo 的话,你又会触发SelectionChanged event, 这将导致Maya undo 你的手动undo操作,所以当前选中的物体又会被选中,最终结果是,你没办法undo.

所以你必须在 SelectionChanged event 里多’undo’ 一次, 当你改变当前选中的物体以后, 你必须再 ‘redo’ 选择操作一次. 这个方法是我从 Highend3D Maya Mailing List 里看来的,原作者是 Roger Klado.

我还发现 “点击不放手然后框选” 模式会触发SelectionChanged event, 如果你在这之后想undo的话, 之前框选中的物体会没被选到. 所以我在写callback的时候还得查询undo queue确保这个事件是由selection event 激发的(而不是被一个 move event 激发的).

下面的例子里,当”ObjectA” 被选中的时候, “ObjectB” 将会被自动选中.

// 创建 scriptJob
scriptJob -event "SelectionChanged" reactToSelection;

// "SelectionChanged" scriptJob event 的Callback.
global proc reactToSelection()
{
  string $whyAmIHere = `undoInfo -q -undoName`;

  // 在'Click Drag Select' mode下通过Wrapper 来防止不希望发生的 Undo .
  if ( `gmatch $whyAmIHere "select*"` )
  {
    string $select[] = `ls -sl`;

    // 取消当前的用户选择.
    undo;
    // 如果ObjectA最开始被选中了
    int $hasObjectA = stringArrayCount( "ObjectA", $select );

    if ( $hasObjectA )
    {
      $select = stringArrayCatenate( { "ObjectB" }, $select );
    }
    else
    // 不允许 ObjectB 被单独选中.
    {
      $select = stringArrayRemove( { "ObjectB" }, $select );
    }

    // 把选中的物体再重复选中操作一次.
    select $select;
  }
}

这个方法如果有什么问题. 请写信给 原作者.

Acknowledgements

Highend3D.com

Roger Klado, Man’O’War

09 February 2002

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: