﻿<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=Dev%3APy%2FScripts%2FCookbook%2FCode_snippets%2FActions_and_drivers</id>
	<title>Dev:Py/Scripts/Cookbook/Code snippets/Actions and drivers - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=Dev%3APy%2FScripts%2FCookbook%2FCode_snippets%2FActions_and_drivers"/>
	<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:Py/Scripts/Cookbook/Code_snippets/Actions_and_drivers&amp;action=history"/>
	<updated>2026-07-04T00:11:28Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=Dev:Py/Scripts/Cookbook/Code_snippets/Actions_and_drivers&amp;diff=104681&amp;oldid=prev</id>
		<title>Yamyam: 1版 をインポートしました</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:Py/Scripts/Cookbook/Code_snippets/Actions_and_drivers&amp;diff=104681&amp;oldid=prev"/>
		<updated>2018-06-28T19:43:19Z</updated>

		<summary type="html">&lt;p&gt;1版 をインポートしました&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ja&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← 古い版&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;2018年6月28日 (木) 19:43時点における版&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ja&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(相違点なし)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Yamyam</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=Dev:Py/Scripts/Cookbook/Code_snippets/Actions_and_drivers&amp;diff=104680&amp;oldid=prev</id>
		<title>wiki&gt;Brecht: moved Dev:2.5/Py/Scripts/Cookbook/Code snippets/Actions and drivers to Dev:Py/Scripts/Cookbook/Code snippets/Actions and drivers: remove version namespace</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:Py/Scripts/Cookbook/Code_snippets/Actions_and_drivers&amp;diff=104680&amp;oldid=prev"/>
		<updated>2015-12-27T19:24:32Z</updated>

		<summary type="html">&lt;p&gt;moved &lt;a href=&quot;/Dev:2.5/Py/Scripts/Cookbook/Code_snippets/Actions_and_drivers&quot; class=&quot;mw-redirect&quot; title=&quot;Dev:2.5/Py/Scripts/Cookbook/Code snippets/Actions and drivers&quot;&gt;Dev:2.5/Py/Scripts/Cookbook/Code snippets/Actions and drivers&lt;/a&gt; to &lt;a href=&quot;/Dev:Py/Scripts/Cookbook/Code_snippets/Actions_and_drivers&quot; title=&quot;Dev:Py/Scripts/Cookbook/Code snippets/Actions and drivers&quot;&gt;Dev:Py/Scripts/Cookbook/Code snippets/Actions and drivers&lt;/a&gt;: remove version namespace&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Page/Header|2.5x|Dev:2.5/Py/Scripts/Cookbook/Code_snippets/Materials_and_textures|&lt;br /&gt;
Dev:2.5/Py/Scripts/Cookbook/Code_snippets/Other_data_types}}&lt;br /&gt;
=Actions and drivers=&lt;br /&gt;
==Object action==&lt;br /&gt;
A bouncing ball.&lt;br /&gt;
[[File:Code_Snippets_ObAction.png|640px]]&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#--------------------------------------------------&lt;br /&gt;
# File ob_action.py&lt;br /&gt;
#--------------------------------------------------&lt;br /&gt;
import bpy&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
def run(origin):&lt;br /&gt;
    # Set animation start and stop&lt;br /&gt;
    scn = bpy.context.scene&lt;br /&gt;
    scn.frame_start = 11&lt;br /&gt;
    scn.frame_end = 200&lt;br /&gt;
    &lt;br /&gt;
    # Create ico sphere&lt;br /&gt;
    bpy.ops.mesh.primitive_ico_sphere_add(location=origin)&lt;br /&gt;
    ob = bpy.context.object&lt;br /&gt;
&lt;br /&gt;
    # Insert keyframes with operator code&lt;br /&gt;
    # Object should be automatically selected&lt;br /&gt;
    z = 10&lt;br /&gt;
    t = 1&lt;br /&gt;
    for n in range(5):&lt;br /&gt;
        t += 10&lt;br /&gt;
        bpy.ops.anim.change_frame(frame = t)&lt;br /&gt;
        bpy.ops.transform.translate(value=(2, 0, z))&lt;br /&gt;
        bpy.ops.anim.keyframe_insert_menu(type='Location')&lt;br /&gt;
        t += 10&lt;br /&gt;
        bpy.ops.anim.change_frame(frame = t)&lt;br /&gt;
        bpy.ops.transform.translate(value=(2, 0, -z))&lt;br /&gt;
        bpy.ops.anim.keyframe_insert_menu(type='Location')&lt;br /&gt;
        z *= 0.67&lt;br /&gt;
&lt;br /&gt;
    action = ob.animation_data.action&lt;br /&gt;
    &lt;br /&gt;
    # Create dict with location FCurves&lt;br /&gt;
    fcus = {}&lt;br /&gt;
    for fcu in action.fcurves:&lt;br /&gt;
        if fcu.data_path == 'location':&lt;br /&gt;
            fcus[fcu.array_index] = fcu&lt;br /&gt;
    print(fcus.items())&lt;br /&gt;
            &lt;br /&gt;
    # Add new keypoints to x and z    &lt;br /&gt;
    kpts_x = fcus[0].keyframe_points&lt;br /&gt;
    kpts_z = fcus[2].keyframe_points&lt;br /&gt;
    (x0,y0,z0) = origin&lt;br /&gt;
    omega = 2*math.pi/20&lt;br /&gt;
    z *= 0.67&lt;br /&gt;
    for t in range(101, 201):&lt;br /&gt;
        xt = 20 + 0.2*(t-101)&lt;br /&gt;
        zt = z*(1-math.cos(omega*(t - 101)))&lt;br /&gt;
        z *= 0.98&lt;br /&gt;
        kpts_z.insert(t, zt+z0, options={'FAST'})&lt;br /&gt;
    kpts_x.insert(t, xt+x0)&lt;br /&gt;
    &lt;br /&gt;
    # Change extrapolation and interpolation for &lt;br /&gt;
    # X curve to linear&lt;br /&gt;
    fcus[0].extrapolation = 'LINEAR'&lt;br /&gt;
    for kp in kpts_x:&lt;br /&gt;
        kp.interpolation = 'LINEAR'        &lt;br /&gt;
&lt;br /&gt;
    # Y location constant and can be removed&lt;br /&gt;
    action.fcurves.remove(fcus[1])&lt;br /&gt;
    bpy.ops.object.paths_calculate()&lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    run((0,0,10))&lt;br /&gt;
    bpy.ops.screen.animation_play(reverse=False, sync=False)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Posebone action==&lt;br /&gt;
This program creates an armature with two bones, which rotate in some complicated curves.&lt;br /&gt;
[[File:Code_Snippets_PoseAction.png|640px]]&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#--------------------------------------------------&lt;br /&gt;
# File pose_action.py&lt;br /&gt;
#--------------------------------------------------&lt;br /&gt;
import bpy&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
def run(origin):&lt;br /&gt;
    # Set animation start and stop&lt;br /&gt;
    scn = bpy.context.scene&lt;br /&gt;
    scn.frame_start = 1&lt;br /&gt;
    scn.frame_end = 250&lt;br /&gt;
&lt;br /&gt;
    # Create armature and object    &lt;br /&gt;
    bpy.ops.object.armature_add()&lt;br /&gt;
    ob = bpy.context.object&lt;br /&gt;
    amt = ob.data&lt;br /&gt;
&lt;br /&gt;
    # Rename first bone and create second bone&lt;br /&gt;
    bpy.ops.object.mode_set(mode='EDIT')    &lt;br /&gt;
    base = amt.edit_bones['Bone']&lt;br /&gt;
    base.name = 'Base'&lt;br /&gt;
    tip = amt.edit_bones.new('Tip')&lt;br /&gt;
    tip.head = (0,0,1)&lt;br /&gt;
    tip.tail = (0,0,2)&lt;br /&gt;
    tip.parent = base&lt;br /&gt;
    tip.use_connect = True&lt;br /&gt;
&lt;br /&gt;
    # Set object location in object mode&lt;br /&gt;
    bpy.ops.object.mode_set(mode='OBJECT')    &lt;br /&gt;
    ob.location=origin    &lt;br /&gt;
&lt;br /&gt;
    # Set rotation mode to Euler ZYX&lt;br /&gt;
    bpy.ops.object.mode_set(mode='POSE')    &lt;br /&gt;
    pbase = ob.pose.bones['Base']&lt;br /&gt;
    pbase.rotation_mode = 'ZYX'&lt;br /&gt;
    ptip = ob.pose.bones['Tip']    &lt;br /&gt;
    ptip.rotation_mode = 'ZYX'&lt;br /&gt;
&lt;br /&gt;
    # Insert 26 keyframes for two rotation FCurves&lt;br /&gt;
    # Last keyframe will be outside animation range&lt;br /&gt;
&lt;br /&gt;
    for n in range(26):    &lt;br /&gt;
        pbase.keyframe_insert(&lt;br /&gt;
            'rotation_euler', &lt;br /&gt;
            index=0,&lt;br /&gt;
            frame=n,&lt;br /&gt;
            group='Base')&lt;br /&gt;
        ptip.keyframe_insert(&lt;br /&gt;
            'rotation_euler', &lt;br /&gt;
            index=2,&lt;br /&gt;
            frame=n,&lt;br /&gt;
            group='Tip')&lt;br /&gt;
    &lt;br /&gt;
    # Get FCurves from newly created action&lt;br /&gt;
    action = ob.animation_data.action&lt;br /&gt;
    fcus = {}&lt;br /&gt;
    for fcu in action.fcurves:&lt;br /&gt;
        bone = fcu.data_path.split('&amp;quot;')[1]&lt;br /&gt;
        fcus[(bone, fcu.array_index)] = fcu&lt;br /&gt;
    &lt;br /&gt;
    # Modify the keypoints&lt;br /&gt;
    baseKptsRotX = fcus[('Base', 0)].keyframe_points&lt;br /&gt;
    tipKptsRotZ = fcus[('Tip', 2)].keyframe_points&lt;br /&gt;
&lt;br /&gt;
    omega = 2*math.pi/250&lt;br /&gt;
    for n in range(26):&lt;br /&gt;
        t = 10*n&lt;br /&gt;
        phi = omega*t&lt;br /&gt;
        kp = baseKptsRotX[n]&lt;br /&gt;
        kp.co = (t+1,phi+0.7*math.sin(phi))&lt;br /&gt;
        kp.interpolation = 'LINEAR'&lt;br /&gt;
        kp = tipKptsRotZ[n]&lt;br /&gt;
        kp.co = (t+1, -3*phi+2.7*math.cos(2*phi))&lt;br /&gt;
        kp.interpolation = 'LINEAR'&lt;br /&gt;
&lt;br /&gt;
    # Calculate paths for posebones&lt;br /&gt;
    bpy.ops.pose.select_all(action='SELECT')&lt;br /&gt;
    bpy.ops.pose.paths_calculate()&lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    run((10,0,0))&lt;br /&gt;
    bpy.ops.screen.animation_play(reverse=False, sync=False)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parenting==&lt;br /&gt;
This program creates a complicated motion by consecutively parenting a few empties to each other, and assigning a simple rotation to each of them.&lt;br /&gt;
[[File:Code_Snippets_Epicycle.png|640px]]&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
# File epicycle.py&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
import bpy&lt;br /&gt;
import math&lt;br /&gt;
from math import pi&lt;br /&gt;
&lt;br /&gt;
def createEpiCycle(origin):&lt;br /&gt;
    periods = [1, 5, 8, 17]&lt;br /&gt;
    radii = [1.0, 0.3, 0.5, 0.1]&lt;br /&gt;
    axes = [0, 2, 1, 0]&lt;br /&gt;
    phases = [0, pi/4, pi/2, 0]&lt;br /&gt;
    &lt;br /&gt;
    # Add empties&lt;br /&gt;
    scn = bpy.context.scene&lt;br /&gt;
    empties = []&lt;br /&gt;
    nEmpties = len(periods)&lt;br /&gt;
    for n in range(nEmpties):&lt;br /&gt;
        empty = bpy.data.objects.new('Empty_%d' % n, None)&lt;br /&gt;
        scn.objects.link(empty)&lt;br /&gt;
        empties.append(empty)&lt;br /&gt;
&lt;br /&gt;
    # Make each empty the parent of the consecutive one&lt;br /&gt;
    for n in range(1, nEmpties):&lt;br /&gt;
        empties[n].parent = empties[n-1]&lt;br /&gt;
        empties[n].location = (0, radii[n-1], 0)&lt;br /&gt;
    &lt;br /&gt;
    # Insert two keyframes for each empty&lt;br /&gt;
    for n in range(nEmpties):&lt;br /&gt;
        empty = empties[n]&lt;br /&gt;
        empty.keyframe_insert(&lt;br /&gt;
            'rotation_euler', &lt;br /&gt;
            index=axes[n],&lt;br /&gt;
            frame=0,&lt;br /&gt;
            group=empty.name)&lt;br /&gt;
        empty.keyframe_insert(&lt;br /&gt;
            'rotation_euler', &lt;br /&gt;
            index=axes[n],&lt;br /&gt;
            frame=periods[n],&lt;br /&gt;
            group=empty.name)&lt;br /&gt;
        fcu = empty.animation_data.action.fcurves[0]&lt;br /&gt;
        print(empty, fcu.data_path, fcu.array_index)&lt;br /&gt;
&lt;br /&gt;
        kp0 = fcu.keyframe_points[0]&lt;br /&gt;
        kp0.co = (0, phases[n]) &lt;br /&gt;
        kp0.interpolation = 'LINEAR'&lt;br /&gt;
        kp1 = fcu.keyframe_points[1]&lt;br /&gt;
        kp1.co = (250.0/periods[n], 2*pi + phases[n]) &lt;br /&gt;
        kp1.interpolation = 'LINEAR'&lt;br /&gt;
        fcu.extrapolation = 'LINEAR'&lt;br /&gt;
&lt;br /&gt;
    last = empties[nEmpties-1]&lt;br /&gt;
    bpy.ops.mesh.primitive_ico_sphere_add(&lt;br /&gt;
        size = 0.2,&lt;br /&gt;
        location=last.location)&lt;br /&gt;
    ob = bpy.context.object&lt;br /&gt;
    ob.parent = last&lt;br /&gt;
&lt;br /&gt;
    empties[0].location = origin&lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
def run(origin):&lt;br /&gt;
    createEpiCycle(origin)&lt;br /&gt;
    bpy.ops.object.paths_calculate()&lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    run((0,0,0))&lt;br /&gt;
    bpy.ops.screen.animation_play(reverse=False, sync=False)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Drivers== &lt;br /&gt;
This program adds an armature with one driver bones and two driven bones. The tip's Z rotation is driven by the driver's x location. The base's Z rotation is driven both by the driver's Y location and its Z rotation.&lt;br /&gt;
[[File:Code_Snippets_driver.png|640px]]&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
# File driver.py&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
def run(origin):&lt;br /&gt;
    # Create armature and object&lt;br /&gt;
    amt = bpy.data.armatures.new('MyRigData')&lt;br /&gt;
    rig = bpy.data.objects.new('MyRig', amt)&lt;br /&gt;
    rig.location = origin&lt;br /&gt;
    amt.show_names = True&lt;br /&gt;
    # Link object to scene&lt;br /&gt;
    scn = bpy.context.scene&lt;br /&gt;
    scn.objects.link(rig)&lt;br /&gt;
    scn.objects.active = rig&lt;br /&gt;
    scn.update()&lt;br /&gt;
&lt;br /&gt;
    # Create bones&lt;br /&gt;
    bpy.ops.object.mode_set(mode='EDIT')&lt;br /&gt;
    base = amt.edit_bones.new('Base')&lt;br /&gt;
    base.head = (0,0,0)&lt;br /&gt;
    base.tail = (0,0,1)&lt;br /&gt;
&lt;br /&gt;
    tip = amt.edit_bones.new('Tip')&lt;br /&gt;
    tip.head = (0,0,1)&lt;br /&gt;
    tip.tail = (0,0,2)&lt;br /&gt;
    tip.parent = base&lt;br /&gt;
    tip.use_connect = True&lt;br /&gt;
&lt;br /&gt;
    driver = amt.edit_bones.new('Driver')&lt;br /&gt;
    driver.head = (2,0,0)&lt;br /&gt;
    driver.tail = (2,0,1)&lt;br /&gt;
&lt;br /&gt;
    bpy.ops.object.mode_set(mode='POSE')&lt;br /&gt;
&lt;br /&gt;
    # Add driver for Tip's Z rotation&lt;br /&gt;
    # Tip.rotz = 1.0 - 1.0*x, where x = Driver.locx&lt;br /&gt;
    fcurve = rig.pose.bones[&amp;quot;Tip&amp;quot;].driver_add('rotation_quaternion', 3)&lt;br /&gt;
    drv = fcurve.driver&lt;br /&gt;
    drv.type = 'AVERAGE'&lt;br /&gt;
    drv.show_debug_info = True&lt;br /&gt;
&lt;br /&gt;
    var = drv.variables.new()&lt;br /&gt;
    var.name = 'x'&lt;br /&gt;
    var.type = 'TRANSFORMS'&lt;br /&gt;
&lt;br /&gt;
    targ = var.targets[0]&lt;br /&gt;
    targ.id = rig&lt;br /&gt;
    targ.transform_type = 'LOC_X'&lt;br /&gt;
    targ.bone_target = 'Driver'&lt;br /&gt;
    targ.use_local_space_transform = True&lt;br /&gt;
&lt;br /&gt;
    fmod = fcurve.modifiers[0]&lt;br /&gt;
    fmod.mode = 'POLYNOMIAL'&lt;br /&gt;
    fmod.poly_order = 1&lt;br /&gt;
    fmod.coefficients = (1.0, -1.0)&lt;br /&gt;
&lt;br /&gt;
    # Add driver for Base's Z rotation&lt;br /&gt;
    # Base.rotz = z*z - 3*y, where y = Driver.locy and z = Driver.rotz&lt;br /&gt;
    fcurve = rig.pose.bones[&amp;quot;Base&amp;quot;].driver_add('rotation_quaternion', 3)&lt;br /&gt;
    drv = fcurve.driver&lt;br /&gt;
    drv.type = 'SCRIPTED'&lt;br /&gt;
    drv.expression = 'z*z - 3*y'&lt;br /&gt;
    drv.show_debug_info = True&lt;br /&gt;
&lt;br /&gt;
    var1 = drv.variables.new()&lt;br /&gt;
    var1.name = 'y'&lt;br /&gt;
    var1.type = 'TRANSFORMS'&lt;br /&gt;
&lt;br /&gt;
    targ1 = var1.targets[0]&lt;br /&gt;
    targ1.id = rig&lt;br /&gt;
    targ1.transform_type = 'LOC_Y'&lt;br /&gt;
    targ1.bone_target = 'Driver'&lt;br /&gt;
    targ1.use_local_space_transform = True&lt;br /&gt;
&lt;br /&gt;
    var2 = drv.variables.new()&lt;br /&gt;
    var2.name = 'z'&lt;br /&gt;
    var2.type = 'TRANSFORMS'&lt;br /&gt;
&lt;br /&gt;
    targ2 = var2.targets[0]&lt;br /&gt;
    targ2.id = rig&lt;br /&gt;
    targ2.transform_type = 'ROT_Z'&lt;br /&gt;
    targ2.bone_target = 'Driver'&lt;br /&gt;
    targ2.use_local_space_transform = True&lt;br /&gt;
&lt;br /&gt;
    return&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    run((0,0,0))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
{{Page/Footer|Dev:2.5/Py/Scripts/Cookbook/Code_snippets/Materials_and_textures|&lt;br /&gt;
Dev:2.5/Py/Scripts/Cookbook/Code_snippets/Other_data_types}}&lt;/div&gt;</summary>
		<author><name>wiki&gt;Brecht</name></author>
		
	</entry>
</feed>