Problems with sliders in the UI.

I’m trying to create a nice User interface for my rig. The problem is I’m not much of a coder, so I have been picking apart several rigs’ UI python files. I can make the bone layers come up without problems, but for some reason I don’t see the sliders just don’t show up. The title does, but the slider does not.

This is the code:

import bpy

class BiffRigProperties(bpy.types.Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_label = "Character Properties"
    
    @classmethod
    def poll(self, context):    
        try:
            ob = context.active_object  
            mode = context.mode     
            return (ob.name == "MTI_rig" and mode == "POSE")
        except AttributeError:
            return 0

    def draw(self, context):
        pose_bones = context.active_object.pose.bones
        layout = self.layout        
        col = layout.column()
       
        col.label(text="FK/IK Switches:")
        col.prop(pose_bones["master"], '["ArmIK.L"]', text="Arm L", slider=True)
        col.prop(pose_bones["master"], '["ArmIK.R"]', text="Arm R", slider=True)
        col.prop(pose_bones["master"], '["LegIK.L"]', text="Leg L", slider=True)
        col.prop(pose_bones["master"], '["LegIK.R"]', text="Leg R", slider=True)
        
        col.label(text="Follow (Hinge):")
        col.prop(pose_bones["master"], '["HeadFollow"]', text="Head", slider=True)
        col.prop(pose_bones["master"], '["ArmFKFollow.L"]', text="Arm L", slider=True)
        col.prop(pose_bones["master"], '["ArmFKFollow.R"]', text="Arm R", slider=True)
        col.prop(pose_bones["master"], '["LegFKFollow.L"]', text="Leg L", slider=True)
        col.prop(pose_bones["master"], '["LegFKFollow.R"]', text="Leg R", slider=True)

        col.label(text="Head:")
        col.prop(pose_bones["master"], '["HeadAim"]', text="Head Look At", slider=True)
        col.prop(pose_bones["master"], '["EyesAim"]', text="Eyes Look At", slider=True)
        
        col.label(text="--- Visibility ---")
        riglayers = col.row()
        riglayers.label(text="Main:")
        riglayers.prop(context.active_object.data, "layers", index=0, toggle=True, text="Root")
        riglayers.prop(context.active_object.data, "layers", index=1, toggle=True, text="Face")
        
        riglayers = col.row()
        riglayers.label(text="Body:")
        riglayers.prop(context.active_object.data, "layers", index=2, toggle=True, text="FK")
        riglayers.prop(context.active_object.data, "layers", index=3, toggle=True, text="IK")
        
        riglayers = col.row()
        riglayers.label(text="Arms:")
        riglayers.prop(context.active_object.data, "layers", index=4, toggle=True, text="FK")
        riglayers.prop(context.active_object.data, "layers", index=5, toggle=True, text="IK")
        
        riglayers = col.row()
        riglayers.label(text="Legs:")
        riglayers.prop(context.active_object.data, "layers", index=6, toggle=True, text="FK")
        riglayers.prop(context.active_object.data, "layers", index=7, toggle=True, text="IK")
        
        riglayers = col.row()
        riglayers.label(text="Other:")
        riglayers.prop(context.active_object.data, "layers", index=8, toggle=True, text="Eyes")
        riglayers.prop(context.active_object.data, "layers", index=9, toggle=True, text="Hands")
        

and this is an image of my driver settings and how the UI looks with this code.
http://img808.imageshack.us/img808/711/projectdefaultrig20.png

The example for this code comes from Denny Lindberg’s “Biff” rig. link.

I started digging through the rigify metarig UI code, (and waylow’s rigs, red neld0.8 and several others) but Biff’s is the simplest and cleanest one imo that works on 2.55.

Can anyone tell me which part is wrong here? How can I get these bloody sliders to show up?

The sliders won’t show unless the object you’re referring to in the code exists in the scene, I guess it’s a silent type of error. :slight_smile:

What’s the console output say?

take a look at the code…

col.prop(pose_bones[“master”], ‘[“ArmIK.L”]’, text=“Arm L”, slider=True)
col.prop(pose_bones[“master”], ‘[“ArmIK.R”]’, text=“Arm R”, slider=True)
col.prop(pose_bones[“master”], ‘[“LegIK.L”]’, text=“Leg L”, slider=True)
col.prop(pose_bones[“master”], ‘[“LegIK.R”]’, text=“Leg R”, slider=True)

    col.label(text="Follow (Hinge):")</i>         <i>
    col.prop(pose_bones["master"], '["HeadFollow"]', text="Head", slider=True)
    col.prop(pose_bones["master"], '["ArmFKFollow.L"]', text="Arm L", slider=True)
    col.prop(pose_bones["master"], '["ArmFKFollow.R"]', text="Arm R", slider=True)
    col.prop(pose_bones["master"], '["LegFKFollow.L"]', text="Leg L", slider=True)
    col.prop(pose_bones["master"], '["LegFKFollow.R"]', text="Leg R", slider=True)
    col.label(text="Head:")</i> <i>
    col.prop(pose_bones["master"], '["HeadAim"]', text="Head Look At", slider=True)
    col.prop(pose_bones["master"], '["EyesAim"]', text="Eyes Look At", slider=True)</i>

you must have a bone called “master” (i think character base) and this bone must have this properties:
ArmIK.L,ArmIK.R,LegIK.L,LegIK.R,HeadFollow,ArmFKFollow.L,ArmFKFollow.R,LegFKFollow.L,LegFKFollow.R,HeadAim,EyesAim

also you have to set drivers to follow sliders value using these properties.
if you have troubles send me blend and i’ll adjust for you.

The driver variable (in the screenshot) would show an error if that were missing.

Thanks guys, and aperrone in particular, because that fixed it!
Now I have all the sliders I need and they take up the entire sidebar, and more…
I didn’t realize you need to have these “labels” as custom bone properties. I thought that was some bug because in rigify sometimes double sliders appear, the sleek ones and the “fat” ones like the custom properties panel. Same in red nelb 0.8
EDIT: That is not a bug. If you assign a custom property to a bone, this custom property will show up in the sidebar/properties. It would sure be nice if you could turn that off…

@Uncle Entity, actually, I just typed in the driver var path myself, after the example from Biff. If all else fails, I thought I might try and add the driver so the slider might show up.

Thanks guys, this was driving me mad.

sorry guys, new problem.
I’m trying to achieve that I only see the sliders for the bodyparts where I have a bone selected. Both Red Nelb and the Rigify Metarig do this.

This is the code that I have now:

	torso = ["DEF_waist", "FK_spine01", "FK_spine02", "FK_chest", "COG", "IK_stomach", "IK_chest"]
	if is_selected(torso):
            layout.prop(pose_bones[torso[0]], '["spineIK"]', text="FK/IK Torso", slider=True)

The funny/annoying thing is, I get the same error on different lines if I remove something.
I get the following error:

File "MTI_rig-UI-metariglik", line 46
    torso = ["DEF_waist", "FK_spine01", "FK_spine02", "FK_chest", "COG", "IK_stomach", "IK_chest"]
                                                                                                 ^
TabError: inconsistent use of tabs and spaces in indentation

location:&lt;unknown location&gt;:-1

location:&lt;unknown location&gt;:-1

The ^arrow has pointed both to FK_chest, and is_selected(torso):
There are no spaces or tabs there, and they shouldn’t be there either, right?

These are pieces of code from Rigify’s metarig:

        ik_leg = ["foot_ik.L", "thigh_pole.L", "foot_roll.L"]
        if is_selected(fk_leg+ik_leg):
            layout.prop(pose_bones[ik_leg[0]], '["ikfk_switch"]', text="FK / IK (" + ik_leg[0] + ")", slider=True)

and red nelb 0.8:

spine = ["spine_root__CA.C","spine_pelvis__BAK.C", "spine_01__BAK.C"]
        if is_selected(context, spine):
            layout.prop(pose_bones["spine_root__CA.C"], '["Spine Flex"]', text="Spine Flex", slider=True) 

My setup should be similar to theirs. Anyone with a clue?
And maybe someone has an idea how to remove the custom property panel that shows up in the sidebar from the 3D viewport?:spin:

The helpful error message says that on line 46 your tabs/spaces don’t match the rest of the file.

Just in your code snippet you have tabs on the ‘if is_selected’ line and spaces on the line below it.

Python is funny about stuff like that, either have to use all tabs or all spaces – can’t mix the two.

There is a menu item on the text editor format > convert white spaces > tabs or spaces…

Converting didn’t do much, but just redoing all the indentation in gedit did… I still got a number of errors like:

Traceback (most recent call last):
  File "MTI_rig-UI-metariglik", line 5, in &lt;module&gt;
  File "MTI_rig-UI-metariglik", line 47, in RigUI
  File "MTI_rig-UI-metariglik", line 32, in is_selected
NameError: global name 'selected_bones' is not defined

location:&lt;unknown location&gt;:-1

location:&lt;unknown location&gt;:-1

but I think that was because I hadn’t done enough indentations (tabs) for the code after the “def” part.
After the correct indentation (one extra tab) the “Character properties” do show up in the sidebar… with nothing in it. No errors or nothing.

This is the code for my basic rig:

import bpy

class RigUI(bpy.types.Panel):
	bl_space_type = 'VIEW_3D'
	bl_region_type = 'UI'
	bl_label = "Character Properties"

	@classmethod
	def poll(self, context):
		try:
			ob = context.active_object
			mode = context.mode
			return (ob.name == "MTI_rig" and mode == "POSE")
		except AttributeError:
			return 0

	def draw(self, context):
		layout = self.layout
		pose_bones = context.active_object.pose.bones
		try:
			selected_bones = [bone.name for bone in context.selected_pose_bones]
			selected_bones += [context.active_pose_bone.name]
		except (AttributeError, TypeError):
			return

	def is_selected(names):
		# Returns whether any of the named bones are selected.
		if type(names) == list:
			for name in names:
				if name in selected_bones:
					return True
		elif names in selected_bones:
			return True
		return False

#--------------------------------------------
# Required: per bone custom properties: 
# armIK.L, armIK.R, armhinge.L, armhinge.R
# legIK.L, legIK.R, leghinge.L, leghinge.R
# spineIK, spinehinge
# headhinge, headaim, eyesaim
#--------------------------------------------

		torso = ["DEF_waist", "FK_spine01", "FK_spine02", "FK_chest", "COG", "IK_stomach", "IK_chest"]
		if is_selected(torso):
			layout.prop(pose_bones[torso[0]], '["spineIK"]', text="FK/IK Torso", slider=True)
			layout.prop(pose_bones[torso[0]], '["spinehinge"]', text="Hinge Torso", slider=True)

		leg_L = ["DEF_hip.L", "FK_upperleg.L", "FK_lowerleg.L", "DEF_shin.L", "DEF_toe.L", "foot.L", "toepivot.L", "footroll.L"]
		if is_selected(leg_L):
			layout.prop(pose_bones[leg_L[0]], '["legIK.L"]', text="FK/IK Leg.L", slider=True)
			layout.prop(pose_bones[leg_L[0]], '["leghinge.L"]', text="Hinge Leg.L", slider=True)

		leg_R = ["DEF_hip.R", "FK_upperleg.R", "FK_lowerleg.R", "DEF_shin.R", "DEF_toe.R", "foot.R", "toepivot.R", "footroll.R"]
		if is_selected(leg_R):
			layout.prop(pose_bones[leg_R[0]], '["legIK.R"]', text="FK/IK Leg.R", slider=True)
			layout.prop(pose_bones[leg_R[0]], '["leghinge.R"]', text="Hinge Leg.R", slider=True)

		head = ["DEF_head", "DEF_neck", "eyetarget", "MCH_eyetar.L", "MCH_eyetar.R", "MCH_eyebase.L", "MCH_eyebase.R", "DEF_pupil.L", "DEF_pupil.R", "DEF_eyelid-up.L", "DEF_eyelid-up.R", "DEF_eyelid-down.L", "DEF_nostril.L", "DEF_nostril.R", "DEF_cheek.L", "DEF_cheek.R", "DEF_upperlip.L", "DEF_upperlip.R", "DEF_lowerlip.L", "DEF_lowerlip.R", "DEF_upperlip-mid", "DEF_lowerlip-mid", "DEF_tongue01", "DEF_tongue02"]
		if is_selected(head[0]):
			layout.prop(pose_bones[head[0]], '["headhinge"]', text="Hinge head", slider=True)
			layout.prop(pose_bones[head[0]], '["headaim"]', text="Aim head", slider=True)
			layout.prop(pose_bones[head[0]], '["eyesaim"]', text="Aim eyes", slider=True)

		arm_L = ["DEF_shoulder.L", "FK_upperarm.L", "FK_forearm.L", "DEF_hand.L", "DEF_pinkybase.L", "thumb.L", "DEF_thumb01.L", "DEF_thumb02.L", "indexfinger.L", "DEF_indexfing02.L", "DEF_indexfing03.L", "middlefinger.L", "DEF_midfing02.L", "DEF_midfing03.L", "ringfinger.L", "DEF_ringfing02.L", "DEF_ringfing03.L", "pinky.L", "DEF_pinky02.L", "DEF_pinky03.L", "IK_hand.L", "elbowpole.L"]
		if is_selected(arm_L):
			layout.prop(pose_bones[arm_L[0]], '["armIK.L"]', text="FK/IK arm.L", slider=True)
			layout.prop(pose_bones[arm_L[0]], '["armhinge.L"]', text="Hinge arm.L", slider=True)

		arm_R = ["DEF_shoulder.R", "FK_upperarm.R", "FK_forearm.R", "DEF_hand.R", "DEF_pinkybase.R", "thumb.R", "DEF_thumb01.R", "DEF_thumb02.R", "indexfinger.R", "DEF_indexfing02.R", "DEF_indexfing03.R", "middlefinger.R", "DEF_midfing02.R", "DEF_midfing03.R", "ringfinger.R", "DEF_ringfing02.R", "DEF_ringfing03.R", "pinky.R", "DEF_pinky02.R", "DEF_pinky03.R", "IK_hand.R", "elbowpole.R"]
		if is_selected(arm_R):
			layout.prop(pose_bones[arm_R[0]], '["armIK.R"]', text="FK/IK arm.R", slider=True)
			layout.prop(pose_bones[arm_R[0]], '["armhinge.R"]', text="Hinge arm.R", slider=True)

		col.label(text="--- Visibility ---")
		riglayers = col.row()
		riglayers.label(text="Main:")
		riglayers.prop(context.active_object.data, "layers", index=0, toggle=True, text="Root")
		riglayers.prop(context.active_object.data, "layers", index=1, toggle=True, text="Face")

		riglayers = col.row()
		riglayers.label(text="Body:")
		riglayers.prop(context.active_object.data, "layers", index=2, toggle=True, text="FK")
		riglayers.prop(context.active_object.data, "layers", index=3, toggle=True, text="IK")

		riglayers = col.row()
		riglayers.label(text="Arms:")
		riglayers.prop(context.active_object.data, "layers", index=4, toggle=True, text="FK")
		riglayers.prop(context.active_object.data, "layers", index=5, toggle=True, text="IK")

		riglayers = col.row()
		riglayers.label(text="Legs:")
		riglayers.prop(context.active_object.data, "layers", index=6, toggle=True, text="FK")
		riglayers.prop(context.active_object.data, "layers", index=7, toggle=True, text="IK")

		riglayers = col.row()
		riglayers.label(text="Other:")
		riglayers.prop(context.active_object.data, "layers", index=8, toggle=True, text="Eyes")
		riglayers.prop(context.active_object.data, "layers", index=9, toggle=True, text="Hands")


The character properties also show up if I select a bone that SHOULD NOT SHOW any character properties (the master bone/root).

I replaced:

		if is_selected(torso):
			layout.prop(pose_bones[torso[0]], '["spineIK"]', text="FK/IK Torso", slider=True)

with:

		if is_selected("master"):
			layout.prop(pose_bones["master"], '["spineIK"]', text="FK/IK Torso", slider=True)

and

		layout.prop(pose_bones["master"], '["spineIK"]', text="FK/IK Torso", slider=True)

and

		layout.prop(pose_bones["IK_chest"], '["spineIK"]', text="FK/IK Torso", slider=True)

No errors, nothing in the console if I use the correct indentation, but nothing shows up in the sidebar…
Anyone who knows what I’m doing wrong?

I have an idea that might help with hiding the custom properties from the sidebar. Use a dummy bone. The selected bone doesn’t have to be a bone with an actual custom property attached, to call for that custom property… I hope that works…

i use this:


def is_selected(context, names):
    try:
        for name in names:
            if context.active_pose_bone.name == name:
                return True
        for bone in context.selected_pose_bones:
            for name in names:
                if bone.name == name:
                    return True
    except AttributeError:
        pass
    return False

and so, is_selected(context, array)
where context is inherited by draw def and array is the name of the array you need (torso, leg_l, etc.)
also I have def is_selected out of draw function, at indent 0.

Your draw function is broken up by is_selected().

Like I was saying, python is funny about stuff like that.

Thank you guys for your troubles.
@ Uncle entity: Where exactly do you mean “broken up”? You mean the script doesn’t work because there is a part of the script conflicting with another part or another darn indentation mistake?. I’ve changed the indentation part several times for the entire block of limbs:

limb = ["bone1, bone2"]
	if is_selected(limb):
		layout.prop(pose_bones[limb[0]], '["limbIK"]', text="FK/IK Limb", slider=True)

I use tabs instead of spaces, I’ve used aperrone’s code snippet and replaced the spaces with tabs…
If the problem is just with one line, could you tell me what it is?

@Aperrone, your method is the same as red nelb’s, right? Then what else do you use if you don’t mind me asking, because red nelb 0.8 is broken in blender 2.55. I’m using revision 33769 btw.

This is my latest code, it doesn’t work. I have tried several things, some parts have been commented out, and I’ve played around with indentation.

# RUN THIS FOR CUSTOM SIDEBAR CONTROLS!

import bpy

class RigUI(bpy.types.Panel):
	bl_space_type = 'VIEW_3D'
	bl_region_type = 'UI'
	bl_label = "Character Properties"

	@classmethod
	def poll(self, context):
		try:
			ob = context.active_object
			mode = context.mode
			return (ob.name == "MTI_rig" and mode == "POSE")
		except AttributeError:
			return 0

	def draw(self, context):
		layout = self.layout
		pose_bones = context.active_object.pose.bones
		try:
			selected_bones = [bone.name for bone in context.selected_pose_bones]
			selected_bones += [context.active_pose_bone.name]
		except (AttributeError, TypeError):
			return

	def is_selected(names):
		# Returns whether any of the named bones are selected.
		if type(names) == list:
			for name in names:
				if name in selected_bones:
					return True
		elif names in selected_bones:
			return True
		return False

#	------------- blenderartist/red nelb method
#	def is_selected(context, names):
#		try:
#			for name in names:
#				if context.active_pose_bone.name == name:
#					return True
#			for bone in context.selected_pose_bones:
#				for name in names:
#					if bone.name == name:
#						return True
#		except AttributeError:
#			pass
#		return False

#--------------------------------------------
# Required: per bone custom properties: 
# armIK.L, armIK.R, armhinge.L, armhinge.R
# legIK.L, legIK.R, leghinge.L, leghinge.R
# spineIK, spinehinge
# headhinge, headaim, eyesaim
#--------------------------------------------

		torso = ["DEF_waist", "FK_spine01", "FK_spine02", "FK_chest", "COG", "IK_stomach", "IK_chest"]
		if is_selected(torso):
			layout.prop(pose_bones[torso[0]], '["spineIK"]', text="FK/IK Torso", slider=True)
			layout.prop(pose_bones[torso[0]], '["spinehinge"]', text="Hinge Torso", slider=True)

		leg_L = ["DEF_hip.L", "FK_upperleg.L", "FK_lowerleg.L", "DEF_shin.L", "DEF_toe.L", "foot.L", "toepivot.L", "footroll.L"]
		if is_selected(leg_L):
			layout.prop(pose_bones[leg_L[0]], '["legIK.L"]', text="FK/IK Leg.L", slider=True)
			layout.prop(pose_bones[leg_L[0]], '["leghinge.L"]', text="Hinge Leg.L", slider=True)

		leg_R = ["DEF_hip.R", "FK_upperleg.R", "FK_lowerleg.R", "DEF_shin.R", "DEF_toe.R", "foot.R", "toepivot.R", "footroll.R"]
		if is_selected(leg_R):
			layout.prop(pose_bones[leg_R[0]], '["legIK.R"]', text="FK/IK Leg.R", slider=True)
			layout.prop(pose_bones[leg_R[0]], '["leghinge.R"]', text="Hinge Leg.R", slider=True)

		head = ["DEF_head", "DEF_neck", "eyetarget", "MCH_eyetar.L", "MCH_eyetar.R", "MCH_eyebase.L", "MCH_eyebase.R", "DEF_pupil.L", "DEF_pupil.R", "DEF_eyelid-up.L", "DEF_eyelid-up.R", "DEF_eyelid-down.L", "DEF_nostril.L", "DEF_nostril.R", "DEF_cheek.L", "DEF_cheek.R", "DEF_upperlip.L", "DEF_upperlip.R", "DEF_lowerlip.L", "DEF_lowerlip.R", "DEF_upperlip-mid", "DEF_lowerlip-mid", "DEF_tongue01", "DEF_tongue02"]
		if is_selected(head[0]):
			layout.prop(pose_bones[head[0]], '["headhinge"]', text="Hinge head", slider=True)
			layout.prop(pose_bones[head[0]], '["headaim"]', text="Aim head", slider=True)
			layout.prop(pose_bones[head[0]], '["eyesaim"]', text="Aim eyes", slider=True)

		arm_L = ["DEF_shoulder.L", "FK_upperarm.L", "FK_forearm.L", "DEF_hand.L", "DEF_pinkybase.L", "thumb.L", "DEF_thumb01.L", "DEF_thumb02.L", "indexfinger.L", "DEF_indexfing02.L", "DEF_indexfing03.L", "middlefinger.L", "DEF_midfing02.L", "DEF_midfing03.L", "ringfinger.L", "DEF_ringfing02.L", "DEF_ringfing03.L", "pinky.L", "DEF_pinky02.L", "DEF_pinky03.L", "IK_hand.L", "elbowpole.L"]
		if is_selected(arm_L):
			layout.prop(pose_bones[arm_L[0]], '["armIK.L"]', text="FK/IK arm.L", slider=True)
			layout.prop(pose_bones[arm_L[0]], '["armhinge.L"]', text="Hinge arm.L", slider=True)

		arm_R = ["DEF_shoulder.R", "FK_upperarm.R", "FK_forearm.R", "DEF_hand.R", "DEF_pinkybase.R", "thumb.R", "DEF_thumb01.R", "DEF_thumb02.R", "indexfinger.R", "DEF_indexfing02.R", "DEF_indexfing03.R", "middlefinger.R", "DEF_midfing02.R", "DEF_midfing03.R", "ringfinger.R", "DEF_ringfing02.R", "DEF_ringfing03.R", "pinky.R", "DEF_pinky02.R", "DEF_pinky03.R", "IK_hand.R", "elbowpole.R"]
		if is_selected(arm_R):
			layout.prop(pose_bones[arm_R[0]], '["armIK.R"]', text="FK/IK arm.R", slider=True)
			layout.prop(pose_bones[arm_R[0]], '["armhinge.R"]', text="Hinge arm.R", slider=True)

		col.label(text="--- Visibility ---")
		riglayers = col.row()
		riglayers.label(text="Main:")
		riglayers.prop(context.active_object.data, "layers", index=0, toggle=True, text="Root")
		riglayers.prop(context.active_object.data, "layers", index=1, toggle=True, text="Face")

		riglayers = col.row()
		riglayers.label(text="Body:")
		riglayers.prop(context.active_object.data, "layers", index=2, toggle=True, text="FK")
		riglayers.prop(context.active_object.data, "layers", index=3, toggle=True, text="IK")

		riglayers = col.row()
		riglayers.label(text="Arms:")
		riglayers.prop(context.active_object.data, "layers", index=4, toggle=True, text="FK")
		riglayers.prop(context.active_object.data, "layers", index=5, toggle=True, text="IK")

		riglayers = col.row()
		riglayers.label(text="Legs:")
		riglayers.prop(context.active_object.data, "layers", index=6, toggle=True, text="FK")
		riglayers.prop(context.active_object.data, "layers", index=7, toggle=True, text="IK")

		riglayers = col.row()
		riglayers.label(text="Other:")
		riglayers.prop(context.active_object.data, "layers", index=8, toggle=True, text="Eyes")
		riglayers.prop(context.active_object.data, "layers", index=9, toggle=True, text="Hands")

#	------------- blenderartist/red nelb method
#def is_selected(context, names):
#	try:
#		for name in names:
#			if context.active_pose_bone.name == name:
#				return True
#		for bone in context.selected_pose_bones:
#			for name in names:
#				if bone.name == name:
#					return True
#	except AttributeError:
#		pass
#	return False

#def is_selected(names):
#	# Returns whether any of the named bones are selected.
#	if type(names) == list:
#		for name in names:
#			if name in selected_bones:
#				return True
#	elif names in selected_bones:
#		return True
#	return False

Quite frustrating, sooo close to finishing this.

I still don’t know why the previous way did not work, because that is the method the rigify rig uses, but I changed my script and now it works for my rig.

First the problem WAS indentation, like Uncle Entity pointed out, but after I fixed that, the problem was in which “bone” or “list of bones” to call for the custom property.

I had this:

		torso = ["DEF_waist", "FK_spine01", "FK_spine02", "FK_chest", "COG", "IK_stomach", "IK_chest", "customprop"]
		if is_selected(torso):
			layout.prop(pose_bones[torso], '["spineIK"]', text="FK/IK Torso", slider=True)
			layout.prop(pose_bones[torso], '["spinehinge"]', text="Hinge Torso", slider=True)
			layout.prop(pose_bones[torso], '["spinestretch"]', text="Stretch Torso", slider=True)

And I needed this:

		torso = ["DEF_waist", "FK_spine01", "FK_spine02", "FK_chest", "COG", "IK_stomach", "IK_chest"]
		if is_selected(torso):
			col.prop(pose_bones["customprop"], '["spineIK"]', text="FK/IK Torso", slider=True)
			col.prop(pose_bones["customprop"], '["spinehinge"]', text="Hinge Torso", slider=True)
			col.prop(pose_bones["customprop"], '["spinestretch"]', text="Stretch Torso", slider=True)

The difference is this:
In the first example, a bone with the custom properties is part of the list of bones to select. Then if a bone from that list got selected, it would call the custom property of the LIST!, not the individual bone.

In the second example, the bone with custom properties is no longer part of the list (it can be, but you don’t ever need to select it so it’s useless), and if a bone from the list gets selected, the bone with the custom property will have a call for it’s custom property.

“col” can be replaced by “layout”, I needed it set to col so it would be aligned the same as the riglayers, which are lower in the menu. I did need to add “col = layout.column()” to the draw function. Like this:

	def draw(self, context):
		layout = self.layout
		col = layout.column()

ps. Found a bug in blender. If a bone previously had a custom property, it will still show a “Properties” panel in the 3D view’s sidebar…
The main reason for moving the custom properties from the limb bones to a custom bone is to get rid of that panel. AND! if one bone holds all the custom properties, it’s a lot easier to manage what custom properties your rig has…

This UI issue was really frustrating me, I hope someone finds this info useful.
And if somebody knows why it DOES work for the rigify rig, feel free to share :slight_smile:

In your non-functional example you’re missing quotation marks. Could be that.
pose_bones[torso] -> pose_bones[torso]

Okay guys, another question. I’m using build 34669, because that is the last build where the rig menu still appears, and one of the first builds where the bone shifting bug is fixed (switching between editmode/posemode made bones move in editmode).
In recent builds, the rig menu won’t show up and I haven’t found the reason for this yet.
Does anyone here have a clue?

i think this might be it :

https://svn.blender.org/svnroot/bf-extensions/trunk/py/scripts/addons/mesh_relax.py
if you look at the last register() and unregister() they include


bpy.utils.register_module(__name__)
and
bpy.utils.unregister_module(__name__)

Thank you very much! It was not the solution, but it was pretty darn close. It helped me find the problem.
To get it working again, I had to add the following code:

def register():
	bpy.utils.register_class(whatever-you-called-your-class)

def unregister():
	bpy.utils.unregister_class(whatever-you-called-your-class)

if __name__ == "__main__":
	register()

So I have this code:


import bpy

class whatever-you-called-your-class(bpy.types.Panel):
	bl_space_type = 'VIEW_3D'
	bl_region_type = 'UI'
	bl_label = "Character Properties"

#blahblah draw menu
#blahblah bone select
#blahblah rig sliders
#blahblah rig layers

def register():
	bpy.utils.register_class(whatever-you-called-your-class)

def unregister():
	bpy.utils.unregister_class(whatever-you-called-your-class)

if __name__ == "__main__":
	register()

I found these links where it is explained:
http://wiki.blender.org/index.php/Dev:2.5/Py/API/Overview (under multiple classes)
http://www.mail-archive.com/[email protected]/msg05329.html

But the easiest way to see it is to open an older build against the new build, open a text window, and go to the header: Text>Script Templates>Panel Simple…
And check the difference between the old and new script. The new script adds the following:


def register():
    bpy.utils.register_class(OBJECT_PT_hello)


def unregister():
    bpy.utils.unregister_class(OBJECT_PT_hello)


if __name__ == "__main__":
    register()

bl_info wasn’t needed, but it’s not a lot of trouble to add it. But I don’t know where it would be used. Thanks for your trouble. It’s great to have this working again.