Seid ihr jemals da gesessen und habt gedacht: ich mache das Gleiche jetzt zum x-ten Mal, kann das nicht mein Computer für mich machen? Gute Neuigkeiten: er kann! Mit ein wenig Verständnis für Python-Skripte kann man repetitive Aufgaben stark vereinfachen. Schaut euch an, wie:
- 00:00 - 03:30 Intro und Überblick
- 04:00 - 07:10 Anfang des Skripts
- 07:10 - 13:40 Weiterführung und Tipps, wie man Python-Befehle findet
- 13:40 - 19:40 Die Animation Data replizieren
- 19:40 - 25:06 Delta Location und Rotation
Die fertige Blendfile inklusive des Skripts kann hier heruntergeladen werden!
Wer nur das Skript nutzen möchte kann zur Addon-Version mit GUI-Elementen greifen... (Rechtsklick -> Speichern unter)
Hier das fertige Skript inklusive Erläuterungen. Beim Kopieren in den Blender Skript-Editor ist zu beachten, dass die Einrückungen korrekt gesetzt sind.
import bpy loops = 20 distanceX = 1.083 distanceY = 0 distanceZ = 0 offset = 10 for i in range(loops): bpy.ops.object.duplicate_move(OBJECT_OT_duplicate = {"linked":False}) obj = bpy.context.active_object obj.delta_location[0] += distanceX obj.delta_location[1] += distanceY obj.delta_location[2] += distanceZ animData = obj.animation_data action = animData.action fcurves = action.fcurves for curve in fcurves: keyframePoints = curve.keyframe_points for keyframe in keyframePoints: keyframe.co[0] += offset keyframe.handle_left[0] += offset keyframe.handle_right[0] += offset
#Erklärung der einzelnen Zeilen:
import bpy #Wir müssen die Blender Python-Bibliothek importieren, damit Python Blender-Objekte versteht. loops = 20 distanceX = 1.083 distanceY = 0 distanceZ = 0 offset = 10 #Ist eine Liste von Variablen, die man ändern kann, wenn man das kcript für andere Zwecke benutzen möchte. #Also habe ich diese Parameter an den Anfang geschrieben, und nicht als Zahl in die Zeile, #in der sie tatsächlich Verwendung finden. #So hat man sie als Liste am Anfang und muss nicht sein Skript durchsuchen, wenn man es anpassen will.
for i in range(loops): #Ruft eine for-Schleife auf. i ist ein austauschbarer Variablenname, der in diesem Fall eine Zahl ist, #was durch das Wort range definiert ist. Im ersten Durchgang der Schleife ist i = 0, im letzten loops 1, #danach hat die Schleife die darunter definierten Aktionen loops mal ausgeführt. bpy.ops.object.duplicate_move(OBJECT_OT_duplicate = {"linked":False}) #Diese Zeile macht dasselbe, wie mit der Maus über dem Viewport SHIFT+D zu drücken. obj = bpy.context.active_object #obj ist der Name einer Variablen, die nun das aktive Objekt ist. #Es ist wichtig, dass es sich dabei um die neueste Kopie handelt und nicht um das Objekt, #das aktiv war als wir "run script" gedrückt haben. obj.delta_location[0] += distanceX obj.delta_location[1] += distanceY obj.delta_location[2] += distanceZ #Diese Zeilen verändern die delta Position des Objekts. #Delta bezieht sich hier auf den Abstand zwischen der im Keyframe gespeicherten Position des Objekts und dem Wert, #den wir eingeben. Hat also unser Objekt location keyframes, wird es dennoch im Raum versetzt, #weil die Werte distance x, y und z dazugezählt werden. #Das Gleiche gilt für delta_rotation. Wichtig ist noch die [0] hinter den Werten. #[i] ist ein gängiges Zeichen dafür, dass es sich um ein Array handelt. #Die Position eines Objekts besteht natürlich aus 3 Werten, x, y und z. Analog werden [0], [1] und [2] verwendet. animData = obj.animation_data action = animData.action fcurves = action.fcurves #Diese 3 Variablen werden die folgenden Zeilen kürzer halten. for curve in fcurves: #Hier wird wieder eine for-Schleife aufgerufen. curve ist der Variablenname, #und die Schleife wird so oft ausgeführt wie es Parameter in fcurves gibt. #curves hält in diesem Fall keine Zahl, sondern tatsächlich alle Informationen der fcurves in der action des Objekts. for keyframe in keyframePoints: #Dementsprechend wird hier die Schleife so oft ausgeführt, wie es keyframes in den actions gibt. keyframe.co[0] += offset #co[0] ist das "Zentrum" des Keyframes. Zu seiner x Position wird also der Wert, den wir oben in offset gespeichert haben dazugezählt. #Bei einem Keyframe ist die X Koordinate dessen Position in der Zeit. keyframe.handle_left[0] += offset keyframe.handle_right[0] += offset #Macht dasselbe für die Bezier Handles der Keyframes. #Also in aller Kürze: Das Skript nimmt das aktive Objekt im View port, verdoppelt es, #versetzt es im Raum und versetzt dessen Animation in der Zeit.
#EDIT: wenn ihr möchtet, dass eure Keyframes zusätzlich einen zufälligen offset bekommen, fügt diese Zeilen in euer Script ein:
import random #ganz oben
rand = (0.5 - random.random()) * 10 #gibt eine Zufallszahl zwischen -5 und +5 aus, da random.random() eine Zahl zwischen 0 und 1 erstellt.
newOffset = offset + rand #diese beiden Zeilen vor animData = obj.animation_data
#und ersetzt die übrigen "offsets" durch "newOffset"