Die Oberfläche ist lokalisiert; Skill-Beschreibungen und -Dokumente werden per KI automatisch in Ihre Sprache übersetzt. Code, Befehle, Pfade und Fachbegriffe bleiben im Original, maßgeblich ist das Dokument des Autors.
Skills entdecken
Produktivität · SKILL.md

blender-syntax-properties

blender-syntax-properties

Use when adding custom properties to Blender objects -- BoolProperty, IntProperty, FloatProperty, EnumProperty, PointerProperty, or PropertyGroup. Prevents the common mistake of not using update callbacks (changes not reflected in UI) or returning stale items from dynamic EnumProperty. Covers all bpy.props types, subtypes, units, getters/ setters, and Colle…

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill-Dokumentation

GitHub

name: blender-syntax-properties description: > Use when adding custom properties to Blender objects -- BoolProperty, IntProperty, FloatProperty, EnumProperty, PointerProperty, or PropertyGroup. Prevents the common mistake of not using update callbacks (changes not reflected in UI) or returning stale items from dynamic EnumProperty. Covers all bpy.props types, subtypes, units, getters/ setters, and CollectionProperty patterns. Keywords: bpy.props, PropertyGroup, BoolProperty, IntProperty, FloatProperty, EnumProperty, PointerProperty, CollectionProperty, update callback, dynamic enum, add custom property, user input, settings. license: MIT compatibility: "Designed for Claude Code. Requires Blender 3.x/4.x/5.x with Python." metadata: author: OpenAEC-Foundation version: "1.0"

blender-syntax-properties

Quick Reference

Property Type Selection

NeedProperty TypePython Type
Toggle/flagBoolPropertybool
Count/indexIntPropertyint
Size/factorFloatPropertyfloat
Name/pathStringPropertystr
Dropdown/modeEnumPropertystr (identifier)
Axis toggles (X, Y, Z)BoolVectorPropertytuple[bool, ...]
DimensionsIntVectorPropertytuple[int, ...]
Color/position/rotationFloatVectorPropertytuple[float, ...]
Link to another typePointerPropertyReference to PropertyGroup or ID
Dynamic listCollectionPropertyList of PropertyGroup items

Critical Warnings

ALWAYS use Python annotation syntax (: not =) for property declarations in classes.

ALWAYS register sub-PropertyGroups BEFORE parent PropertyGroups — registration order matters.

ALWAYS store dynamic enum callback results in a module-level variable to prevent garbage collection crashes.

ALWAYS set explicit unique integer values in enum items used with ENUM_FLAG or getter/setter patterns.

NEVER modify the property that triggered an update callback — causes infinite recursion.

NEVER define set without a matching get callback — Blender raises an error.

NEVER call operators inside update callbacks — they trigger undo and corrupt state.

NEVER set default on EnumProperty when items is a callback — use default=None or omit it.


Version-Critical Changes

VersionChangeImpact
4.1Enum ID properties via id_properties_uiInteger custom properties can display as dropdowns
5.0property_unset() replaces del obj["prop"]RNA properties use separate storage from custom properties
5.0get_transform / set_transform callbacksFaster alternative to get/set using internal storage
5.0IDProperty storage splitbpy.props-defined properties no longer accessible via dict syntax

Blender 5.0 Property Storage Split

# Blender <5.0: dict access to RNA properties worked
value = obj["my_rna_prop"]  # WORKED in 4.x

# Blender 5.0+: dict access BROKEN for bpy.props-defined properties
value = obj["my_rna_prop"]  # Returns None or KeyError

# CORRECT in 5.0+: use RNA path
value = obj.my_rna_prop

# Reset property to default (replaces del obj["prop"]):
obj.property_unset("my_rna_prop")

Essential Patterns

Pattern 1: Basic Property Declaration

# Blender 3.x/4.x/5.x: annotation syntax REQUIRED
class MyOperator(bpy.types.Operator):
    bl_idname = "object.my_operator"
    bl_label = "My Operator"

    count: bpy.props.IntProperty(name="Count", default=5, min=1, max=100)
    factor: bpy.props.FloatProperty(name="Factor", default=1.0, subtype='FACTOR')
    name_input: bpy.props.StringProperty(name="Name", default="Object")

Pattern 2: PropertyGroup Registration

# Blender 3.x/4.x/5.x
class MySettings(bpy.types.PropertyGroup):
    enabled: bpy.props.BoolProperty(name="Enabled", default=True)
    count: bpy.props.IntProperty(name="Count", default=5, min=1)
    scale: bpy.props.FloatProperty(name="Scale", default=1.0, min=0.01)

def register():
    bpy.utils.register_class(MySettings)
    bpy.types.Scene.my_settings = bpy.props.PointerProperty(type=MySettings)

def unregister():
    del bpy.types.Scene.my_settings
    bpy.utils.unregister_class(MySettings)

Pattern 3: Nested PropertyGroups

# Blender 3.x/4.x/5.x: registration order is CRITICAL
class SubSettings(bpy.types.PropertyGroup):
    value: bpy.props.FloatProperty(name="Value", default=0.0)

class MainSettings(bpy.types.PropertyGroup):
    sub: bpy.props.PointerProperty(type=SubSettings)
    items: bpy.props.CollectionProperty(type=SubSettings)
    active_index: bpy.props.IntProperty()

def register():
    bpy.utils.register_class(SubSettings)    # FIRST: sub-types
    bpy.utils.register_class(MainSettings)   # SECOND: parent type
    bpy.types.Scene.settings = bpy.props.PointerProperty(type=MainSettings)

def unregister():
    del bpy.types.Scene.settings
    bpy.utils.unregister_class(MainSettings)  # Reverse order
    bpy.utils.unregister_class(SubSettings)

Pattern 4: Static EnumProperty

# Blender 3.x/4.x/5.x
# Items: (identifier, name, description[, icon[, number]])
my_mode: bpy.props.EnumProperty(
    name="Mode",
    items=[
        ('FAST', "Fast", "Low quality, fast render", 'PLAY', 0),
        ('MEDIUM', "Medium", "Balanced quality", 'PAUSE', 1),
        ('HIGH', "High", "High quality, slow render", 'RENDER_STILL', 2),
    ],
    default='MEDIUM',
)

Pattern 5: Dynamic EnumProperty

# Blender 3.x/4.x/5.x
# WARNING: MUST store results to prevent garbage collection crash

_enum_items_cache = []  # Module-level storage REQUIRED

def get_object_items(self, context):
    global _enum_items_cache
    _enum_items_cache = [
        (obj.name, obj.name, f"Select {obj.name}", 'OBJECT_DATA', i)
        for i, obj in enumerate(bpy.data.objects)
    ]
    if not _enum_items_cache:
        _enum_items_cache = [('NONE', "None", "No objects available", 'ERROR', 0)]
    return _enum_items_cache

my_object: bpy.props.EnumProperty(
    name="Object",
    items=get_object_items,
    # default MUST be None or omitted when items is a callback
)

Pattern 6: Update Callback

# Blender 3.x/4.x/5.x
def on_count_changed(self, context):
    # SAFE: modify OTHER properties on self
    if self.count > 10:
        self.warning = "High count may impact performance"
    # UNSAFE: do NOT modify self.count here (infinite recursion)
    # UNSAFE: do NOT call bpy.ops.* here (undo corruption)

class MySettings(bpy.types.PropertyGroup):
    count: bpy.props.IntProperty(
        name="Count", default=5, update=on_count_changed,
    )
    warning: bpy.props.StringProperty()

Pattern 7: Getter/Setter

# Blender 3.x/4.x/5.x
def get_computed(self):
    # Compute value on read — no internal storage
    return len(bpy.data.objects)

def set_computed(self, value):
    # Handle write — must store somewhere if persistence needed
    self["_cached_count"] = value

class MySettings(bpy.types.PropertyGroup):
    object_count: bpy.props.IntProperty(
        name="Object Count",
        get=get_computed,
        set=set_computed,
    )

Pattern 8: Get/Set Transform (Blender 5.0+)

# Blender 5.0+ ONLY: faster than get/set, uses internal storage
def clamp_transform(self, new_value, curr_value, is_set):
    """Transform value before storing."""
    return max(0.0, min(new_value, 100.0))

def display_transform(self, curr_value, is_set):
    """Transform value on read."""
    return curr_value * 2.0 if is_set else 0.0

class MySettings(bpy.types.PropertyGroup):
    clamped: bpy.props.FloatProperty(
        name="Clamped",
        set_transform=clamp_transform,
        get_transform=display_transform,
    )

Pattern 9: ENUM_FLAG (Multi-Select)

# Blender 3.x/4.x/5.x: numbers MUST be powers of 2
my_flags: bpy.props.EnumProperty(
    name="Axes",
    items=[
        ('X', "X Axis", "Include X axis", 1),
        ('Y', "Y Axis", "Include Y axis", 2),
        ('Z', "Z Axis", "Include Z axis", 4),
    ],
    options={'ENUM_FLAG'},
    default={'X', 'Z'},  # Default is a SET, not a string
)

Pattern 10: PointerProperty with Poll

# Blender 3.x/4.x/5.x: filter selectable objects
def filter_mesh_objects(self, obj):
    return obj.type == 'MESH'

class MySettings(bpy.types.PropertyGroup):
    target: bpy.props.PointerProperty(
        type=bpy.types.Object,
        name="Target",
        poll=filter_mesh_objects,
    )

Pattern 11: CollectionProperty Operations

# Blender 3.x/4.x/5.x
scene = bpy.context.scene

# Add item
item = scene.my_settings.items.add()
item.name = "New Item"
item.value = 42.0

# Remove by index
scene.my_settings.items.remove(0)

# Move item (from_index, to_index)
scene.my_settings.items.move(0, 2)

# Clear all
scene.my_settings.items.clear()

# Iterate
for item in scene.my_settings.items:
    print(item.name, item.value)

# Access by index
first = scene.my_settings.items[0]

# Find by name (returns index or -1)
idx = scene.my_settings.items.find("New Item")

Subtype and Unit Quick Reference

Numeric Subtypes

SubtypeApplies ToEffect
'NONE'AllDefault display
'PIXEL'Int/FloatPixel unit display
'UNSIGNED'IntUnsigned display
'PERCENTAGE'Float0-100% display
'FACTOR'Float0.0-1.0 slider
'ANGLE'FloatRadians with degree display
'TIME'FloatScene-relative time (frames)
'TIME_ABSOLUTE'FloatAbsolute time (seconds)
'DISTANCE'FloatDistance in scene units
'POWER'FloatPower unit display
'TEMPERATURE'FloatTemperature display

Vector Subtypes

SubtypeApplies ToEffect
'COLOR'FloatVectorLinear RGB color picker
'COLOR_GAMMA'FloatVectorGamma-space color picker
'TRANSLATION'FloatVectorPosition in scene units
'DIRECTION'FloatVectorNormalized direction
'VELOCITY'FloatVectorVelocity vector
'ACCELERATION'FloatVectorAcceleration vector
'EULER'FloatVectorEuler rotation (radians)
'QUATERNION'FloatVectorQuaternion rotation (size=4)
'AXISANGLE'FloatVectorAxis-angle rotation (size=4)
'XYZ'FloatVectorGeneric XYZ coordinates
'MATRIX'FloatVectorMatrix representation

String Subtypes

SubtypeEffect
'NONE'Plain text input
'FILE_PATH'File browser button
'DIR_PATH'Directory browser button
'FILE_NAME'File name field
'BYTE_STRING'Byte string
'PASSWORD'Masked input (***)

Unit Values (FloatProperty / FloatVectorProperty only)

UnitDisplay
'NONE'No unit
'LENGTH'Scene length unit
'AREA'Area (length²)
'VOLUME'Volume (length³)
'ROTATION'Degrees/radians
'TIME'Scene-relative time
'TIME_ABSOLUTE'Absolute seconds
'VELOCITY'Speed
'ACCELERATION'Acceleration
'MASS'Mass
'CAMERA'Camera distance
'POWER'Power
'TEMPERATURE'Temperature

Options Flags

FlagApplies ToEffect
'HIDDEN'AllHidden from UI, accessible via Python
'SKIP_SAVE'AllValue not saved between operator invocations
'ANIMATABLE'All (default)Can be keyframed
'LIBRARY_EDITABLE'AllEditable on linked data-blocks
'PROPORTIONAL'NumericProportional editing support
'TEXTEDIT_UPDATE'StringUpdates on each keystroke
'ENUM_FLAG'Enum onlyMulti-select with power-of-2 values

Decision Trees

When to Use PointerProperty vs CollectionProperty

Need to reference ONE item?
├── YES → PointerProperty
│   ├── Reference to another PropertyGroup? → type=MyPropertyGroup
│   └── Reference to an ID type? → type=bpy.types.Object (or Material, etc.)
└── NO → Need a LIST of items?
    └── YES → CollectionProperty(type=MyPropertyGroup)
        └── Track active selection? → Add IntProperty for active_index

When to Use get/set vs get_transform/set_transform

Blender version?
├── <5.0 → Use get/set (only option)
└── >=5.0
    ├── Need custom storage logic? → Use get/set
    └── Only need value transformation?
        └── Use get_transform/set_transform (faster, uses internal storage)

When to Use update vs msgbus

Property changes on THIS class?
├── YES → Use update callback on the property
└── NO → Watching EXTERNAL property changes?
    └── YES → Use bpy.msgbus.subscribe_rna()

Attachment Points

Properties can be attached to any Blender ID type:

# Per-scene settings
bpy.types.Scene.my_prop = bpy.props.PointerProperty(type=MySettings)

# Per-object settings
bpy.types.Object.my_prop = bpy.props.PointerProperty(type=MySettings)

# Per-material settings
bpy.types.Material.my_prop = bpy.props.FloatProperty(name="Custom")

# Per-mesh settings
bpy.types.Mesh.my_prop = bpy.props.IntProperty(name="Custom")

# Per-bone settings
bpy.types.Bone.my_prop = bpy.props.StringProperty(name="Custom")

# Per-window-manager (session-only, not saved)
bpy.types.WindowManager.my_prop = bpy.props.BoolProperty(name="Temp")

WindowManager properties are session-only — they reset when Blender restarts. Use for temporary UI state.


Reference Links

Official Sources

Gespeicherte Skills