SEAMLESS LOOPING ANIMATION SCRIPT FOR CINEMA 4D (VIBRATE TAG ALTERNATIVE)
Notice the seamless loop? The Vibrate Tag canβt do it, so hereβs a Python Tag solution I built with ChatGPT.
The script creates a perfectly looping animation for your objects.
THE SCRIPT
import c4d
import math
import random
def main():
obj = op.GetObject()
if obj is None:
return
# === MAIN SETTINGS ===
enable_pos = True # Enable position vibration
enable_rot = False # Enable rotation vibration
enable_scale = False # Enable scale breathing
amp_pos = c4d.Vector(2, 2, 2) # Amplitude for position (cm)
amp_rot = c4d.Vector(10, 20, 5) # Amplitude for rotation (degrees)
amp_scale = 0.08 # Amplitude for uniform scale (0.08 = 8%)
loop_frames = 75 # Loop length in frames
freq = 1.0 # Frequency for position/rotation
freq_scale = 1.0 # Frequency for scale breathing
seed = 38738
rnd = random.Random(seed)
phase_offset_x = rnd.uniform(0, 2 * math.pi)
phase_offset_y = rnd.uniform(0, 2 * math.pi)
phase_offset_z = rnd.uniform(0, 2 * math.pi)
phase_offset_scale = rnd.uniform(0, 2 * math.pi)
time = doc.GetTime()
fps = doc.GetFps()
frame = time.GetFrame(fps)
phase = (frame % loop_frames) / float(loop_frames)
vibr = c4d.Vector(
math.sin(phase * math.pi * 2 * freq + phase_offset_x),
math.sin(phase * math.pi * 2 * freq + phase_offset_y),
math.sin(phase * math.pi * 2 * freq + phase_offset_z)
)
scale_phase = math.sin(phase * math.pi * 2 * freq_scale + phase_offset_scale)
scale_val = 1 + scale_phase * amp_scale
if enable_pos:
obj.SetRelPos(c4d.Vector(
vibr.x * amp_pos.x,
vibr.y * amp_pos.y,
vibr.z * amp_pos.z
))
if enable_rot:
obj.SetRelRot(c4d.Vector(
math.radians(vibr.x * amp_rot.x),
math.radians(vibr.y * amp_rot.y),
math.radians(vibr.z * amp_rot.z)
))
if enable_scale:
obj.SetRelScale(c4d.Vector(scale_val, scale_val, scale_val))
Note:
π The script is not perfect: seamless looping works only for whole-number frequencies (1, 2, 3, etc).
π To keep the original object position, use Freeze Transform before applying the tag.
Good news:
π True seamless loop (with the loop period set via loop_frames)
π You can start motion from any frame by adjusting fade_start.