You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Maya的半随机太阳系生成器问题:点灯光复制异常

问题与解决方案

问题说明

目标是制作一个基于polySphere、曲线并支持颜色分配的半随机生成太阳系工具。目前已实现通过下拉菜单选择四种规格polyPlane作为背景的功能,但尝试用for循环复制pointLight模拟星空时,复制的却是polyPlane而非灯光。使用环境:Maya 2022.4,Windows 10。

错误原因

  1. 创建pointLight后未保存其节点名称,后续依赖cmds.ls(sl=True)获取对象,但执行cmds.polyPlane后,选中的是新创建的平面而非灯光,导致复制对象错误。
  2. 复制灯光后仍修改原灯光的属性,而非新生成的灯光节点。
  3. 星空灯光逻辑仅针对Small背景,其他尺寸未实现。
  4. 重命名函数中错误地将选中对象作为textField的查询参数,逻辑完全错误。

修正后的完整代码

import maya.cmds as cmds
import random

star_count = 10

def solar_UI(): 
    # 删除旧窗口
    if cmds.window("MainWindow", exists=True):
        cmds.deleteUI("MainWindow")

    # 创建UI窗口
    cmds.window("MainWindow", t="自定义太阳系生成器", w=500, h=700, mnb=False, mxb=False, sizeable=False)
    cmds.columnLayout("MainLayout", w=300, cal=('center'), adj=False, en=True)
    cmds.rowColumnLayout(nc=2)
    
    # 背景选择菜单
    cmds.optionMenu("BackgroundCreationList", w=250, label="背景尺寸选择:")
    cmds.menuItem(label=" ")
    cmds.menuItem(label="小型")
    cmds.menuItem(label="中型")
    cmds.menuItem(label="大型")
    cmds.menuItem(label="超大型")

    cmds.button("Create_Background", l="创建背景", w=150, align='middle', c=BackgroundCreation)
    cmds.setParent('..')    
    
    cmds.separator(h=2, en=True)
    
    # 恒星重命名
    cmds.rowColumnLayout(nc=3)
    cmds.text(l="恒星名称:", w=75)
    cmds.textField('star_name', w=100, pht='输入名称')    
    cmds.button(l="重命名", w=100, c=rename_star)
    cmds.setParent('..')

    # 全删除按钮
    cmds.columnLayout()
    cmds.button("Delete", l="删除所有对象", w=200, align='middle', bgc=[0.5, 0, 0], c=DeleteButton)
    cmds.setParent('..')   

    cmds.showWindow("MainWindow")

# 背景与星空创建
def BackgroundCreation(*args):
    bgValue = cmds.optionMenu("BackgroundCreationList", q=True, v=True)
    # 根据选择创建对应尺寸的背景平面
    if bgValue == "小型": 
        bg_size = 75
        star_range = (-15, 15)
    elif bgValue == "中型":
        bg_size = 200
        star_range = (-50, 50)
    elif bgValue == "大型":
        bg_size = 500
        star_range = (-125, 125)
    elif bgValue == "超大型":
        bg_size = 1000
        star_range = (-250, 250)
    else:
        return  # 未选择尺寸时直接返回
    
    cmds.polyPlane(n=f"{bgValue}_背景", w=bg_size, h=bg_size)
    # 创建星空灯光
    for _ in range(star_count):
        # 直接创建新灯光,而非复制
        star_light = cmds.shadingNode('pointLight', asLight=True, n=f"Star_Light_{_+1}")
        # 设置灯光位置
        cmds.setAttr(f"{star_light}.tx", random.uniform(*star_range))
        cmds.setAttr(f"{star_light}.tz", random.uniform(*star_range))
        cmds.setAttr(f"{star_light}.ty", 3)
        # 设置灯光属性模拟星星
        cmds.setAttr(f"{star_light}.intensity", random.uniform(8, 12))
        cmds.setAttr(f"{star_light}.rgb", (1, 1, random.uniform(0.8, 1)))  # 暖白色星星
        cmds.setAttr(f"{star_light}.decayRate", 2)

# 恒星重命名函数
def rename_star(*args):
    selected_objs = cmds.ls(sl=True, type='transform')
    if not selected_objs:
        cmds.warning("请先选择要重命名的恒星!")
        return
    new_name = cmds.textField('star_name', q=True, text=True)
    if new_name:
        cmds.rename(selected_objs[0], new_name)
    else:
        cmds.warning("请输入有效的名称!")

# 删除所有对象
def DeleteButton(*args):
    # 直接删除所有可删除对象,避免重复选择
    all_objs = cmds.ls(tr=True)
    if all_objs:
        cmds.delete(all_objs)

solar_UI()

关键修改说明

  • 避免依赖选择: 创建灯光时直接捕获返回的节点名称,不再使用cmds.ls(sl=True),彻底解决选到平面的问题。
  • 统一星空逻辑: 将星空灯光生成逻辑扩展到所有背景尺寸,根据背景大小自动调整星星分布范围。
  • 修复重命名功能: 正确从textField获取输入名称,先检查是否有选中对象,避免无效操作。
  • 优化删除函数: 直接获取所有变换节点并删除,无需循环选择,效率更高。
  • 增强星空效果: 随机设置灯光强度和颜色,模拟真实星星的明暗差异。

内容的提问来源于stack exchange,提问作者MasWeird

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:39:22