見出し画像

マテリアル色切り替えアニメーションスクリプト修正版、関数冒頭に設定事項をまとめて扱いやすいようにしました。

"""
タイトル: マテリアル色切り替えアニメーションスクリプト
説明:
Blender内で任意の2色を交互に切り替えるミックスシェーダーを使用して、
球体のマテリアル色をアニメーション化するシーンを作成します。
色の切り替え方向(色1→色2、色2→色1)は引数で指定可能で、
切り替え回数と間隔は設定辞書で簡単に変更可能です。

作成日時: 2024年11月14日
バージョン: 2.1.0
"""

import bpy

# 設定辞書
SETTINGS = {
    "frame_start": 1,
    "frame_interval": 120,
    "toggle_count": 10,
    "colors": [(1.0, 0.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0)]  # 赤と緑
}

def clear_objects_except_camera_and_light():
    """カメラとライト以外のオブジェクトを削除"""
    for obj in bpy.data.objects:
        if obj.type not in {'CAMERA', 'LIGHT'}:
            bpy.data.objects.remove(obj, do_unlink=True)


def create_camera_and_light():
    """カメラとライトがなければ新規作成"""
    if not any(obj.type == 'CAMERA' for obj in bpy.data.objects):
        bpy.ops.object.camera_add(location=(0, -10, 5), rotation=(1.1, 0, 0))
        bpy.context.object.name = "Camera"
    if not any(obj.type == 'LIGHT' for obj in bpy.data.objects):
        bpy.ops.object.light_add(type='POINT', location=(5, -5, 10))
        bpy.context.object.name = "Light"


def create_floor():
    """床を生成"""
    bpy.ops.mesh.primitive_plane_add(size=10, location=(0, 0, 0))
    bpy.context.object.name = "Floor"


def create_sphere(location=(0, 0, 1)):
    """スムースシェーディングを適用した球体を生成"""
    bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=location)
    sphere = bpy.context.object
    bpy.ops.object.shade_smooth()
    sphere.name = "Sphere"
    return sphere


def create_mixed_material(name, color1, color2):
    """任意の2色を切り替えるミックスマテリアルを作成"""
    mat = bpy.data.materials.new(name=name)
    mat.use_nodes = True
    
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links
    nodes.clear()
    
    output_node = nodes.new(type="ShaderNodeOutputMaterial")
    mix_shader = nodes.new(type="ShaderNodeMixShader")
    diffuse_1 = nodes.new(type="ShaderNodeBsdfDiffuse")
    diffuse_2 = nodes.new(type="ShaderNodeBsdfDiffuse")
    
    diffuse_1.inputs["Color"].default_value = color1
    diffuse_2.inputs["Color"].default_value = color2
    
    links.new(diffuse_1.outputs["BSDF"], mix_shader.inputs[1])
    links.new(diffuse_2.outputs["BSDF"], mix_shader.inputs[2])
    links.new(mix_shader.outputs["Shader"], output_node.inputs["Surface"])
    
    mat["mix_shader"] = mix_shader.name
    return mat


def animate_mixed_material(mat, frame, direction):
    """指定フレームでミックスシェーダの色を切り替え"""
    mix_shader = mat.node_tree.nodes.get(mat.get("mix_shader"))
    if mix_shader:
        mix_shader.inputs["Fac"].default_value = 1.0 if direction else 0.0
        mix_shader.inputs["Fac"].keyframe_insert(data_path="default_value", frame=frame)


def main():
    clear_objects_except_camera_and_light()
    create_camera_and_light()
    create_floor()
    sphere = create_sphere()
    
    colors = SETTINGS["colors"]
    mixed_material = create_mixed_material("CustomMixedMaterial", colors[0], colors[1])
    sphere.data.materials.append(mixed_material)
    
    frame_start = SETTINGS["frame_start"]
    frame_interval = SETTINGS["frame_interval"]
    toggle_count = SETTINGS["toggle_count"]
    
    for i in range(toggle_count):
        direction = (i % 2 == 0)  # 偶数回は色1、奇数回は色2
        animate_mixed_material(mixed_material, frame=frame_start + i * frame_interval, direction=direction)
    
    bpy.context.scene.frame_set(1)


# 実行
main()

いいなと思ったら応援しよう!