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_rot = False

enable_scale = True

amp_pos = c4d.Vector(2, 2, 2) # cm

amp_rot = c4d.Vector(10, 20, 5) # degrees

amp_scale = 0.05 # "breathing" in % (0.15 = 15% up and down)

loop_frames = 180

freq = 1.0 # shake frequency (position/rotation)

freq_scale = 1.0 # "breath" frequency (scale)

# ——— SEED for unique behavior

seed = 35426 # you can change this for different objects

# === Random phases based on seed ===

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)

# === CALCULATIONS ===

time = doc.GetTime()

fps = doc.GetFps()

frame = time.GetFrame(fps)

phase = (frame % loop_frames) / float(loop_frames)

# shake with unique phases

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)

)

# uniform scale "breathing" with random phase

scale_phase = math.sin(phase * math.pi * 2 * freq_scale + phase_offset_scale)

scale_val = 1 + scale_phase * amp_scale

# === APPLY ===

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.

Previous
Previous

ECOFLEX YOGA MAT — VIDEO OF THE DAY AT MOTION DESIGN AWARDS

Next
Next

NAKED EYE TUTORIAL FEATURED BY SCHOOL OF MOTION