pg09

テーマ CGとプログラム(続編)


demo1 demo2 demo3 demo4


今回の内容:

・CGソフト Blender のスクリプト機能を利用し、プログラムによる3DCGを作成する。

Blender はオープンソースのフリーソフトウェアです。無償で利用できます。

参考サイト: Blender入門


・プログラム言語 Python を使用する。

Python はテキスト処理を手軽に書けるのでWebサービスの開発(サーバサイド)に利用されています。

また、AIの研究分野で機械学習用のツールを利用する際のスクリプト言語としても利用されています。

オープンソースのフリーソフトウェアで無償で利用できます。

Pythonで嫁を見つけた話 - みんなのPython第四版に寄せて http://coreblog.org/ats/thinking-about-minpy-4th/Pythonで仕事をされている方のBlogで、Pythonやっててよかったという記事を見つけたので紹介します。みんなのPython は大学の図書館にも第3版があります。Webアプリ編の関連書もあります。興味がある受講生は借りて勉強してみましょう。


以下の演習ではブラウザは Google Chrome を使うこと。

コードをこのWebからコピペすると Edge や InternetExplorer を使用した場合Bugります。

原因: HTML の空白文字 &nbsp が ascii文字 0x20 のspaceとしてコピペされずに unicodeの マルチバイトの空白文字としてコピペされるため。


Blenderの起動: 解説動画(演習1に一部対応。Blender Ver.2.79でUIが古い)

スタート → Blender → blender をクリック


今回はBlenderの操作方法についてはほとんど触れずにPython スクリプトによるCG作成を中心に演習をする。

Blenderによる3DCG作成に興味のある受講者は入門サイトを検索するか関連資料をみて取り組んでみよう。(昔の 資料1 資料2


今回の演習は デフォルト設定(英語)メニューで作業を行ってください

設定をデフォルトに戻すには、

File -> Defaults -> Load Factory Settings

File -> Defaults -> Save Start up File

1.Edit -> 2.Preferences -> 3.ハンバーガーボタン -> 4.Save Preferences

これで設定が普及しない場合は、次も試す。

1.Edit -> 2.Preferences -> 3.ハンバーガーボタン -> 4.Load Factory Preferences

演習1

BlenderのスクリーンレイアウトScripting に変更する

次のBlenderの画像の 0. の矢印で Scriptingタブをクリック

上の画像で、2.の New をクリックする。下の画像のようにPythonスクリプト(プログラムのこと)を入力できるようになる。授業の後半で3の部分にスクリプトを入力していく。

Pythonスクリプトの動作を確認するために、まずは 1.の部分(コンソールと呼ばれる)にプログラムを入力していく。


3Dビュー(CGが表示されている部分)を広げておくとよい(各ウィンドウの境界付近をマウスでドラッグして調節する)


左サイドのツールを表示する。

2.のアイコンを押して3DビューのビューポートのShadingをRendered(レンダリング済み)に切り替える。

1の移動ツールで 3.のLightを移動する。Light(光源)移動に応じてCubeの印影が変化する。

Blenderの制御用スクリプトはプログラム言語 Python で記述できます。

以下の演習ではPython を利用して3DCGを作成します。

まず Pythonのコードを コンソール(上の画像で青色の1の部分)に入力して動作を確認しましょう。

コンソールに文字入力カーソルが表示されているので(表示されていなければ、コンソールをマウスでクリック)

キーボードから以下のコードを入力する。

1行入力して、enter キーで コードを実行する。

実行するたびに、処理結果が表示されたり、3Dビューでオブジェクトが変化する。


1+1


bpy.data.objects['Cube'].location.x += 1


bpy.data.objects['Cube'].location.y += 1


bpy.data.objects['Cube'].location.z += 1


※ コンソールのキーボード操作

(マウスでコンソールウィンドウを選択してから)

上下矢印キー ↓ ↑ で入力履歴の呼び出しが可能

同じコードを繰り返したり以前実行したコードを編集して実行できる

.y.z のコードはコピペせずにコンソール上でコマンドの文字を修正して実行させてみよう。


コードの解説:

bpy.data.objects['Cube']

作業中のシーンから Cube キューブという名前の付いたオブジェクトを検索して利用する。

objects['Cube']はPythonの連想配列を使用している。

参照: 【python入門者必見!】配列・連想配列を徹底解説


.location

オブジェクトの3D空間の座標を操作する。

.x .y .z

座標をそれぞれ x軸 y軸 z軸 に沿って操作する。

+=

記号の左側(操作対象)の値を右側の数値分増加する。

A += 1 なら Aを1増加させる。


コマンドを実行すると 3DビューのCubeが移動することが確認できる。

また、右パネルをObject Proerties 表示に切り替えると Cube の Location X の値を確認できる。

Blenderの3Dビューの add メニューから Mesh -> Ico SphereでICO球モデルを追加する。

次のコードでICO球モデルのZ座標を変更する。

bpy.data.objects['Icosphere'].location.z += 10


3Dビューの表示範囲を調整する。

ここではキーボードの HOME キーでシーン全体を表示しておく。


その他の3Dビューの操作方法:

・マウスホイール ズームイン・アウト

・ミドルボタン(ホイール)でドラッグ すると シーン回転

解説動画(つづき)

アウトライナーパネルのシーンツリーを確認

Icosphere を選択

プロパティパネルの表示内容をオブジェクトに変更

リストデータ [ x, y, z] を使用して プロパティをセットする。

次のコードを scriptのコンソールに入力して実行する。

bpy.data.objects['Icosphere'].location = [ -10 , 0 , 0]


bpy.data.objects['Icosphere'].scale = [2,2,2]


Cubeを回転操作する。回転にはオイラー角(euler)を使用して、X軸、Y軸、Z軸の順番で回転させる。

←オイラー角の説明図(Wikipediaより)

このアニメーションでは 球体を回転させている。


この図ではSphereを回転させているが次のコードでは Cube を回転させる。

上から順に、 約180度回転、約90度回転、約45度回転

bpy.data.objects['Cube'].rotation_euler = [0,0,3.14]


bpy.data.objects['Cube'].rotation_euler = [0,0,3.14/2]


bpy.data.objects['Cube'].rotation_euler = [0,0,3.14/4]

回転の角度指定は、 度(degree)ではなく、ラジアン(radian)を使う。 π=3.141592…=180度

←ラジアンnの説明図(Wikipediaより)

マテリアル(色)を作成し、オブジェクトに設定する

※ diffuse_color 散乱光(物に光を当てたときに見える物質の色)

color0 = bpy.data.materials.new('mycolor')

color0.diffuse_color = [1, 0, 0, 1]


マテリアルが未設定のオブジェクトに対して、マテリアルを追加する場合。

bpy.data.objects['Icosphere'].data.materials.append( color0 )


マテリアルが設定済みのオブジェクトに対して、マテリアルを上書きする場合。

bpy.data.objects['Cube'].material_slots[0].material = color0

※うまくいかないことも有るようです(原因不明)その場合は、マテリアルが未設定のオブジェクト用のコードで試すとうまくいく模様。


スクリプトでオブジェクトを生成して、場所を移動し、色を設定する。

bpy.ops.mesh.primitive_ico_sphere_add()

bpy.context.object.location = [2, 4, 8]

bpy.context.object.data.materials.append(color0)

bpy.context.object で現在操作中のオブジェクトにアクセスできる。この例ではprimitive_ico_sphere_addで新規作成したico sphere のlocationにアクセスしている。

Swift Playgroundsの Shape テンプレートのコードの様にオブジェクトに名前 b を付けて操作するには次のようにする。

bpy.ops.mesh.primitive_cube_add()

b = bpy.data.objects[bpy.context.active_object.name]

b.location = [2, 4, 0]

課題1の提出

ここまでの状況を Pythonスクリプトと3Dビューを1枚のスクリーンショットに記録しておく。

Webclassにアップロードして提出する。


(補足)3Dモデルの配置や撮影する方向や色はアレンジしてあってもよい。

オブジェクトの配置は パースをOFFにして確認すると分かりやすい。(3Dビューの右サイドのアイコン、カメラアイコンの下のアイコンで切り替える)

演習2

解説動画(旧手順で説明)

準備:

1.View Layerの Scene Collection をマウスで選択。

2.新規コレクション作成ボタンを押す。

3.Collection を非表示にする。

4.Collection 2 をマウスで選択する。

以下の Python スクリプトをエディターに入力し実行する。コピペしてOK

コンソール には入力しません。

import bpy

import math


materials = []

for i in [0, 1, 2, 3, 4, 5, 6]:

materials.append(bpy.data.materials.new('Color' + str(i)))


materials[0].diffuse_color = [1,0,0,1]

materials[1].diffuse_color = [0,1,0,1]

materials[2].diffuse_color = [0,0,1,1]

materials[3].diffuse_color = [0,1,1,1]

materials[4].diffuse_color = [1,0,1,1]

materials[5].diffuse_color = [1,1,0,1]

materials[6].diffuse_color = [1,1,1,1]


for i in [0, 1, 2, 3, 4, 5, 6]:

t = 2.0 * math.pi * i / 7

x = 1.0 * math.cos(t)

y = 1.0 * math.sin(t)

bpy.ops.mesh.primitive_ico_sphere_add()

bpy.context.object.location = [x, y, 0]

bpy.context.object.scale = [0.5, 0.5, 0.5]

bpy.context.object.data.materials.append(materials[i % 7])

スクリプトを実行するには 再生ボタン(run script)を押す。


光源の調整またはシェーディングの変更:

Add -> Light -> Sun で光源を追加して、光の方向を調整する。

または、

3Dビューの Viewport Shading を Material Preview に切り替える。


球をいくつか削除する。

マウス操作でオブジェクトを削除するには、左クリックで削除するオブジェクトを選択 → deleteキー


オブジェクトを配置する座標の半径を変更する。

先ほどのコードを修正する。

x = 4.0 * math.cos(t)

y = 4.0 * math.sin(t)


※参照 Scratchで学ぶ三角関数オールペンで三角関数 ~sin,cos~scratchで三角関数で検索


前回作成したオブジェクトで不要な範囲をマウスで選択して削除(x キー)する。

スクリプトを実行する。


配置するオブジェクト数の増加(7~12の追加)、半径の拡大(6倍)、配置間隔の角度変更(/2で半分に)をする

for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:

t = 2.0 * math.pi * i / 7 / 2

x = 6.0 * math.cos(t)

y = 6.0 * math.sin(t)

他にも

for i in [0, 1, 2, 3, 4, 5, 6]:

t = 2.0 * math.pi * i / 7

x = 1.5 * math.cos(t)

y = 6.0 * math.sin(t)

for i in [0, 1, 2, 3, 4, 5, 6]:

t = 2.0 * math.pi * i / 7

x = -6.0 * math.cos(t)

y = 6.0 * math.sin(t)

for i in [0, 1, 2, 3, 4, 5, 6]:

t = 2.0 * math.pi * i / 7

x = 6.0 * math.cos(0.5*t)

y = 6.0 * math.sin(0.5*t)

for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:

t = 2.0 * math.pi * i / 7

x = 6.0 * math.cos(t)

y = 6.0 * math.sin(2.0*t)

などを試して現れる図形の様子を確かめてみよう。


Pythonの文法について:

Python入門(外部サイト)

Pythonは繰り返し構文や条件分岐構文などのコードの制御範囲を「インデント」で示します。

例)forループ構文が繰り返すコードは code1 code2 code3 まで。code4は範囲外

for i in [ 1,2,3]

code1

code2

code3

code4

プログラム言語毎に様々な文法があります。

コードの範囲を { } などのかっこを用いて表すものや、begin end などの予約語を用いるもの、Pythonのようにインデントでコードを記述したレイアウトで表すものがあります。


課題2

Python スクリプト と 3Dビューを収めたスクリーンショット を Webclass の第9回課題2に提出

HOMEボタンを押して、全てのオブジェクトが表示されるようにしておくこと。

例)

提出期限 来週まで。


ヒント:一旦、授業中に作成したCGを 仮提出 しておく。

ヒント:授業中制作のCGと混ざらないようにアウトライナーウインドウでCollectionを追加して実験するとよい。

ヒント:Text Editorで New Textボタンを押して新規にスクリプトを作成してもよい。

以下の応用例を示す。コピペして実験に利用するとよい。


・ 色の設定は [1,0,0,1] のほか、 [0.5, 0.5, 0.5,1] (この数値は灰色になる)など、 0.0 から 1.0 までの値が指定できる。

・ 色の数や順番を入れ替えてみる

・ オブジェクトの変更

bpy.ops.mesh.primitive_ico_sphere_add()

bpy.ops.mesh.primitive_cube_add()

へ変更すると 球体 から 立方体に オブジェクトを変更できる。

他の種類の立体を使いたい場合は3Dビューメニューの Add -> Mesh からオブジェクトの種類を表示して使用するコマンドを確認できる。


以下のコードは Shader Node を作成し、さらにアニメーションを設定するコードである。

上に記載したコードに追記して使用できる。

点滅スピードを mulの値で、各色の点滅タイミングを pha の値で調整できる。

# blink speed

mul = 10

pha = 5


for i in [0, 1, 2, 3, 4, 5, 6]:

materials[i].use_nodes = True

material_output = materials[i].node_tree.nodes.get('Material Output')

glass = materials[i].node_tree.nodes.new('ShaderNodeBsdfGlass')

materials[i].node_tree.links.new(material_output.inputs[0], glass.outputs[0])

br = materials[i].node_tree.nodes.new('ShaderNodeBrightContrast')

br.inputs[0].default_value = materials[i].diffuse_color

materials[i].node_tree.links.new(glass.inputs[0], br.outputs[0])

sin = materials[i].node_tree.nodes.new('ShaderNodeMath')

sin.operation = 'SINE'

materials[i].node_tree.links.new(br.inputs[1], sin.outputs[0])

phase = 3.141592/7*i*pha/10

sin.inputs[0].default_value=0 + phase

sin.inputs[0].keyframe_insert( 'default_value', frame = 1)

sin.inputs[0].default_value=3.141592 * mul + phase

sin.inputs[0].keyframe_insert( 'default_value', frame = 250)

materials[i].node_tree.animation_data.action.fcurves[0].keyframe_points[0].interpolation = 'LINEAR'

・for ループの部分をコピーして、 オブジェクトを表示する座標や サイズ を変更する

※ location = (x, y, 0) を location = (x, y, 2) と変更すると表示位置のZ座標を変更できる。

・for ループを2重にする。

例) Python はインデント(コードの表示位置)の高さでループ範囲(ブロック)を表現するので、↓のコードを使用する際は左側の空白部分も正確に入力すること。

import bpy

import math


materials = []

for i in [0, 1, 2, 3, 4, 5, 6]:

materials.append(bpy.data.materials.new('Color' + str(i)))


materials[0].diffuse_color = [1,0,0,1]

materials[1].diffuse_color = [0,1,0,1]

materials[2].diffuse_color = [0,0,1,1]

materials[3].diffuse_color = [0,1,1,1]

materials[4].diffuse_color = [1,0,1,1]

materials[5].diffuse_color = [1,1,0,1]

materials[6].diffuse_color = [1,1,1,1]


for z in [0, 2, 4]:

for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:

t = 2.0 * math.pi * i / 7 / 2

x = 6.0 * math.cos(t)

y = 6.0 * math.sin(t)

bpy.ops.mesh.primitive_ico_sphere_add()

bpy.context.object.location = [x, y, z]

bpy.context.object.scale = [0.5, 0.5, 0.5]

bpy.context.object.data.materials.append(materials[i % 7])

※↑このコードには、 インデントが 2レベル ある。外側が z座標を変化させるループ、 内側が円周に配置するループ。

※インデントの調整は TABキーを使用する。Shift+TABキーでインデントを低くできる。複数の行を纏めて選択してTABでインデントの調整可能。


・range の応用

range(0,10) で、 [0,1,2,3,4,5,6,7,8,9,10]

range(0,10,2 ) で、 [0, 2, 4, 6, 8] 2つおき

range(10,0,-1)で、 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] の逆順をリストを作成できる。

例)

for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:

for i in range(0,13):

と同じ動作。 range は丸括弧 ( ) を使うので注意。

・Python の リスト内包表記 を利用して規則的な数列を生成できる。

例) 2乗の数列の生成

[i*i/10 for i in range(0, 10)]

↑で、↓を生成

[0.0, 0.1, 0.4, 0.9, 1.6, 2.5, 3.6, 4.9, 6.4, 8.1]


作成例1)

高さ z の 値に反比例(1/z)するように半径をすぼめるコード。

import bpy

import math


materials = []

for i in [0, 1, 2, 3, 4, 5, 6]:

materials.append(bpy.data.materials.new('Color' + str(i)))


materials[0].diffuse_color = [1,0,0,1]

materials[1].diffuse_color = [0,1,0,1]

materials[2].diffuse_color = [0,0,1,1]

materials[3].diffuse_color = [0,1,1,1]

materials[4].diffuse_color = [1,0,1,1]

materials[5].diffuse_color = [1,1,0,1]

materials[6].diffuse_color = [1,1,1,1]


for z in [1, 2, 3, 4, 5, 6, 7]:

for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:

t = 2.0 * math.pi * i / 7 / 2

x = 6.0 * math.cos(t)

y = 6.0 * math.sin(t)

bpy.ops.mesh.primitive_ico_sphere_add(location = (x/z, y/z, z*2))

bpy.context.object.scale = [0.5, 0.5, 0.5]

bpy.context.object.data.materials.append(materials[i % 7])

作成例2)

高さzに比例して半径を拡大するコード。

import bpy

import math


materials = []

for i in [0, 1, 2, 3, 4, 5, 6]:

materials.append(bpy.data.materials.new('Color' + str(i)))


materials[0].diffuse_color = [1,0,0,1]

materials[1].diffuse_color = [0,1,0,1]

materials[2].diffuse_color = [0,0,1,1]

materials[3].diffuse_color = [0,1,1,1]

materials[4].diffuse_color = [1,0,1,1]

materials[5].diffuse_color = [1,1,0,1]

materials[6].diffuse_color = [1,1,1,1]


for z in [1, 2, 3, 4, 5, 6, 7]:

for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:

t = 2.0 * math.pi * i / 7 / 2

x = 6.0 * math.cos(t)

y = 6.0 * math.sin(t)

bpy.ops.mesh.primitive_ico_sphere_add(location = (x*z/7, y*z/7, z*2))

bpy.context.object.scale = [0.5, 0.5, 0.5]

bpy.context.object.data.materials.append(materials[i % 7])



作例3)

2種類のオブジェクト(cubeico_sphere) を使用。5色に減色。上下の段で、色を連続して使用。

import bpy

import math


materials = []

for i in [0, 1, 2, 3, 4, 5, 6]:

materials.append(bpy.data.materials.new('Color' + str(i)))


materials[0].diffuse_color = [1,0,0,1]

materials[1].diffuse_color = [0,1,0,1]

materials[2].diffuse_color = [0,0,1,1]

materials[3].diffuse_color = [0,1,1,1]

materials[4].diffuse_color = [1,0,1,1]

materials[5].diffuse_color = [1,1,0,1]

materials[6].diffuse_color = [1,1,1,1]


for i in [0, 1, 2, 3, 4, 5, 6]:

t = 2.0 * math.pi * i / 7

x = 6.0 * math.cos(t)

y = 6.0 * math.sin(t)

bpy.ops.mesh.primitive_cube_add()

bpy.context.object.location = [x, y, 0]

bpy.context.object.data.materials.append(materials[i % 7])


c = 0


for z in [12, 10, 8, 6, 4, 2, 0]:

for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:

t = 2.0 * math.pi * i / 7 / 2

x = 4.0 * math.cos(t)

y = 4.0 * math.sin(t)

bpy.ops.mesh.primitive_ico_sphere_add()

bpy.context.object.location = [x*z/12, y*z/12, 12 - z]

bpy.context.object.scale = [0.5, 0.5, 0.5]

bpy.context.object.data.materials.append(materials[c % 5])

c += 1



さらに複雑な例。ランダムの利用例。

XYZ空間の一定の範囲で一定の間隔の全ての格子点について、5%の確率で四角い板を配置し、位置に応じた色を付ける。

実行完了までしばらくの時間が必要。

import bpy

import math

import random


materials = []

for i in [0, 1, 2, 3, 4, 5, 6]:

materials.append(bpy.data.materials.new('Color' + str(i)))


materials[0].diffuse_color = [1,0,0,1]

materials[1].diffuse_color = [0,1,0,1]

materials[2].diffuse_color = [0,0,1,1]

materials[3].diffuse_color = [0,1,1,1]

materials[4].diffuse_color = [1,0,1,1]

materials[5].diffuse_color = [1,1,0,1]

materials[6].diffuse_color = [1,1,1,1]


for i in [0, 1, 2, 3, 4, 5, 6]:

materials[i].use_nodes = True

material_output = materials[i].node_tree.nodes.get('Material Output')

emission = materials[i].node_tree.nodes.new('ShaderNodeEmission')

emission.inputs['Strength'].default_value = 5.0

# link emission shader to material

materials[i].node_tree.links.new(material_output.inputs[0], emission.outputs[0])

materials[i].node_tree.nodes["Emission"].inputs[0].default_value = materials[i].diffuse_color

for z in range(-120,-10,20):

for x in range(int(z),-int(z),8):

for y in range(int(z),-int(z),8):

if random.random() < 0.05:

bpy.ops.mesh.primitive_plane_add()

bpy.context.object.location = [x, y, z]

bpy.context.object.scale = [6, 6, 6]

bpy.context.object.data.materials.append(materials[(x+y+z) % 7])



上のコードを修正する。

xy座標で0,0から離れるにしたがて板の発生確率を下げる調整とランダムに少し回転させるエフェクトを加えた例。demo1

コード random.choice([0,0,0,0.75]) は、 0 が3個、 0.75が1個の、合計4個のデータの中からランダムに1つ選んでいる。つまり、1/4の確率で、0.75、それ以外は0になる。

import bpy

import math

import random


materials = []

for i in [0, 1, 2, 3, 4, 5, 6]:

materials.append(bpy.data.materials.new('Color' + str(i)))


materials[0].diffuse_color = [1,0,0,1]

materials[1].diffuse_color = [0,1,0,1]

materials[2].diffuse_color = [0,0,1,1]

materials[3].diffuse_color = [0,1,1,1]

materials[4].diffuse_color = [1,0,1,1]

materials[5].diffuse_color = [1,1,0,1]

materials[6].diffuse_color = [1,1,1,1]


for i in [0, 1, 2, 3, 4, 5, 6]:

materials[i].use_nodes = True

material_output = materials[i].node_tree.nodes.get('Material Output')

emission = materials[i].node_tree.nodes.new('ShaderNodeEmission')

emission.inputs['Strength'].default_value = 5.0

# link emission shader to material

materials[i].node_tree.links.new(material_output.inputs[0], emission.outputs[0])

materials[i].node_tree.nodes["Emission"].inputs[0].default_value = materials[i].diffuse_color


for z in range(-190,-10,30):

z2=z

if z2<-100: z2= -100

for x in range(z2,-z2,8):

for y in range(z2,-z2,8):

if random.random() < 0.005 + (0.15/(1+abs(x)/40+abs(y)/40)):

bpy.ops.mesh.primitive_plane_add()

bpy.context.object.location = [x, y, z+20]

bpy.context.object.scale = [6, 6, 6]

rx = random.choice([0,0,0,0.75])

ry = random.choice([0,0,0,0.75])

bpy.context.object.rotation_euler = [rx, ry, 0]

bpy.context.object.data.materials.append(materials[(x+y+z) % 7])



重力や摩擦など、物理属性を設定する例。 demo2

このコード例は、プログラム全体を入れ替えて利用すること。

※ 余分なオブジェクトはすべて削除しておくとよい。物理シミュレーションでアニメーションさせる際に衝突して上手くいかなくなる。

全削除方法: 3D画面で a キーで画面内オブジェクトを全選択。 x キーで削除。

import bpy


bpy.ops.mesh.primitive_plane_add()

bpy.context.object.location = [0, 0, 0]

bpy.context.object.scale = [40, 2, 0]

bpy.ops.rigidbody.object_add()

bpy.context.object.rigid_body.friction = 1

bpy.context.object.rigid_body.enabled = False


for i in range(0,22):

x = -24 + 3.0 * i

bpy.ops.mesh.primitive_cube_add()

bpy.context.object.location = [x, 0, 1.5]

bpy.context.object.scale = [0.5, 1, 1.5]

bpy.ops.rigidbody.object_add()

bpy.context.object.rigid_body.friction = 0.5

bpy.context.object.rigid_body.mass = 2

bpy.context.object.rigid_body.enabled = True


bpy.context.scene.cursor.location = [38.5, 0, 0]

bpy.ops.object.origin_set(type='ORIGIN_CURSOR')

bpy.ops.transform.rotate(value= -0.33, orient_axis="Y")

bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')

bpy.context.object.rigid_body.mass = 4


bpy.context.scene.frame_end = 600

bpy.context.scene.rigidbody_world.point_cache.frame_end = 600


スペースキーでアニメーションを再生・停止する。フレームの操作は 矢印キー (+Shiftキー)


参考:

音に合わせてアニメーションさせる


フリー音楽素材/魔王魂 https://maoudamashii.jokersounds.com/list/game13.html

強弱のハッキリした音源をDLする。ドラムなどがあるとよい。


Blender×Pythonでパーティクルライブの素材を大量に自動生成する https://styly.cc/ja/tips/blender-python-particlelive/


作業手順の概略:

1 frame に戻す。

3Dビューで音でアニメーションさせるオブジェクトを選ぶ。全て選ぶなら a キー

アニメーションキーフレームの設定。 i キーに続けて s キー (スケールにアニメーションを付ける)

animation window に切り替える

Dope Sheet から Graph Editor に切り替える。

a キー で全てのカーブを選択する。

検索窓で scale に絞り込む

key -> bake sounds to F curve から音源ファイルを設定する。(ファイル選択画面に調整メニューが出るので調整してもよい)

+ボタンから Video Editing モードを表示する。

add -> Sound

先ほど key frame の bakeで使用した音源ファイルを選択する。

timeline上の音源クリップの位置を 1 frame から開始するようにトラック上の位置をスライドして調整する。

animation window に戻して スペース キーで再生。