You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Maya材质纹理切换脚本修改:下拉选材质+滑块调纹理

解决Maya材质纹理切换脚本的问题

嘿,我帮你梳理了原脚本里的几个问题,并且重新写了一个完整的版本,完全满足你通过下拉菜单切换材质、滑块调节纹理,还能把设置应用到选中模型的需求。先说说原脚本的几个小疏漏:

  • 删除窗口时误用了未定义的变量ram,应该用窗口名字符串"ram"
  • 图片路径定义后没写完引用,会导致图片加载失败
  • 缺少核心的材质选择、纹理调节UI组件,以及对应的功能逻辑

下面是修改后的完整脚本:

import maya.cmds as mc

# 全局变量,存储当前编辑的材质和纹理节点
current_shader = None
current_texture_place2d = None

def delete_existing_window():
    """清理已存在的窗口"""
    if mc.window("ram", exists=True):
        mc.deleteUI("ram")

def create_shader(shader_type):
    """创建指定类型的材质,并绑定纹理"""
    global current_shader, current_texture_place2d
    
    # 清理旧的材质节点(避免节点过多冗余)
    if current_shader and mc.objExists(current_shader):
        mc.delete(current_shader)
    if current_texture_place2d and mc.objExists(current_texture_place2d):
        mc.delete(current_texture_place2d)
    
    # 创建材质与材质组
    shader_name = f"{shader_type}_custom_shader"
    current_shader = mc.shadingNode(shader_type, asShader=True, name=shader_name)
    shader_sg = mc.sets(renderable=True, noSurfaceShader=True, empty=True, name=f"{shader_name}SG")
    mc.connectAttr(f"{current_shader}.outColor", f"{shader_sg}.surfaceShader", force=True)
    
    # 创建纹理与UV放置节点(这里用棋盘格示例,可替换为自定义图片)
    texture_node = mc.shadingNode("checker", asTexture=True, name="base_texture")
    current_texture_place2d = mc.shadingNode("place2dTexture", asUtility=True, name="texture_uv_place")
    
    # 连接纹理与材质的属性
    mc.connectAttr(f"{current_texture_place2d}.outUV", f"{texture_node}.uvCoord")
    mc.connectAttr(f"{current_texture_place2d}.outUvFilterSize", f"{texture_node}.uvFilterSize")
    mc.connectAttr(f"{texture_node}.outColor", f"{current_shader}.color")

def on_shader_selected(*args):
    """材质下拉菜单选择后的回调逻辑"""
    shader_type = mc.optionMenu("shader_menu", query=True, value=True)
    create_shader(shader_type)
    # 重置滑块初始值
    mc.floatSlider("texture_repeat_slider", edit=True, value=2)
    on_texture_repeat_changed(2)

def on_texture_repeat_changed(value):
    """滑块调节纹理重复次数的回调"""
    if not current_texture_place2d:
        return
    mc.setAttr(f"{current_texture_place2d}.repeatU", value)
    mc.setAttr(f"{current_texture_place2d}.repeatV", value)

def apply_to_selected():
    """将当前材质应用到选中模型"""
    if not current_shader:
        mc.warning("请先选择一种材质!")
        return
    
    selected_objs = mc.ls(selection=True, transforms=True)
    if not selected_objs:
        mc.warning("请先选中要应用材质的模型!")
        return
    
    shader_sg = f"{current_shader}SG"
    for obj in selected_objs:
        # 获取模型的形状节点并分配材质
        shape_nodes = mc.listRelatives(obj, shapes=True)
        if shape_nodes:
            for shape in shape_nodes:
                mc.sets(shape, forceElement=shader_sg)

# 主窗口初始化
delete_existing_window()
ram = mc.window("ram", title="Material and Texture v0.9", width=300, height=300)
mc.columnLayout(adjustableColumn=True, rowSpacing=12)

# 加载Logo图片(路径错误时显示提示文本)
try:
    imagePath = mc.internalVar(upd=True) + "icons/scriptlogo.jpg"
    mc.image(width=300, height=200, image=imagePath)
except:
    mc.text(label="Logo加载失败", align="center", height=200, font="boldLabelFont")

# 材质选择下拉菜单
mc.text(label="选择材质类型", align="center")
mc.optionMenu("shader_menu", changeCommand=on_shader_selected)
mc.menuItem(label="Blinn")
mc.menuItem(label="Phong")
mc.menuItem(label="Lambert")
mc.menuItem(label="SurfaceShader")

# 纹理重复次数调节滑块
mc.text(label="调节纹理重复次数", align="center")
create_shader("blinn")  # 初始化默认材质
mc.floatSlider("texture_repeat_slider", 
               min=0.1, max=10.0, value=2, step=0.1,
               changeCommand=lambda val: on_texture_repeat_changed(val))

# 应用按钮
mc.button(label="应用到选中模型", command=lambda _: apply_to_selected(), width=220, height=30)

# 显示窗口
mc.showWindow(ram)

几个关键功能说明:

  • 材质自动创建:选中下拉菜单里的材质类型时,会自动创建对应材质并绑定纹理,旧材质节点会被清理避免冗余
  • 纹理参数调节:滑块控制纹理的UV重复次数,你可以修改回调函数里的属性,换成调节纹理偏移、旋转或者材质的高光强度等参数
  • 模型材质应用:点击按钮后,会把当前设置好的材质批量应用到你选中的所有模型,自动处理形状节点的材质组分配
  • 自定义纹理替换:如果想用自己的图片纹理,把create_shader里的checker换成file,再添加一行设置图片路径:
    mc.setAttr(f"{texture_node}.fileTextureName", "你的纹理文件绝对路径", type="string")
    

这样整个脚本就能正常运行,实现你想要的功能啦!

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

火山引擎 最新活动