1
$\begingroup$

I'm currently driving the hair and body base color from a single property on the character below. However, I'd like the hair to be driven by another property as well. So that both properties (when changed) will drive the hair color to the exact color of only the changed property.

So, for example, I'd like to be able to do this:

  1. Change (2)Diffuse Color for body and hair to Orange with one property
  2. Change hair color to green with another property (body remains orange)
  3. Change body and hair color to purple from original (2)Diffuse Color property

I would like these steps to be repeatable.

Example

Any idea how to pull this off?

I've been trying to find scripted expressions that only send a value when a driven property variable is changed. But if it remains the same it is not read.

$\endgroup$
6
  • $\begingroup$ If I were to do the 3 steps in order, would I go from 1) hair & body both orange to 2) hair green & body orange to 3) hair & body both purple or would 3) leave the hair green because I changed it in 2? $\endgroup$ Oct 9 '21 at 14:11
  • $\begingroup$ @MartyFouts I would like to have hair and body both purple in step 3. I would also like these steps to be repeatable after that. So if I wanted to (4) use the other property to change both the hair and body again, I could. $\endgroup$
    – Tyler
    Oct 9 '21 at 14:12
  • 1
    $\begingroup$ I think that Message Bus is one right way to get the notifications you want; and This question discusses how to do that; except I can't for the life of me figure out how to use datablock.path_resolve("property_name", False) to get a valid value for a custom color picker property I added to world, no matter what I replace datablock with. $\endgroup$ Oct 9 '21 at 17:13
  • $\begingroup$ Ohhh, this is a great starting point though! I'll see what I can find out. Thanks for those links. $\endgroup$
    – Tyler
    Oct 9 '21 at 17:18
  • 1
    $\begingroup$ Ah, apparently this only works on custom properties you attach to Scene via python and not on custom properties you add with the add button $\endgroup$ Oct 9 '21 at 18:02
-1
$\begingroup$

Turns out that you don't really need msgbus for this. I don't know exactly how this would integrate into your code, so I'm just going to post the necessary code fragments and let you figure out where to put them.

First, you need two custom color properties, attached to anything, but I've attached them to bpy.types.Scene because that means you can use them anywhere in your scene and each scene will have its own copy.

bpy.types.Scene.mainColor = bpy.props.FloatVectorProperty(
    name='main color',
    description = 'The primary color',
    default=(0.8,0.8,0.8),
    min=0.0,
    max=1.0,
    subtype='COLOR',
    update=update_colors,
)
bpy.types.Scene.secondaryColor = bpy.props.FloatVectorProperty(
    name = 'secondary color',
    description = 'The secondary color',
    default=(0.8,0.8,0.8),
    min=0.0,
    max=1.0,
    subtype='COLOR',
)

You can, of course call them whatever you want. In my example, mainColor is the color that you would use for both the body and hair, and secondaryColor is the color for just the hair.

The "sneaky" bit is the last line of the definition of mainColor: the addition of update=update_colors to an otherwise typical Color custom property.

This tells bpy that you want a function called update_colors called each time mainColor is updated. That function handles resetting secondaryColor when mainColor changes:

def update_colors(self, context):
    context.scene.secondaryColor = context.scene.mainColor

I added a panel class so I could test this, but you could just integrate the two new properties into your existing panel:

class VIEW3D_PT_color_pair(bpy.types.Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Monkeys'
    bl_label = 'Color Pair'
    def draw(self, context):
        layout = self.layout
        col = layout.column(align=True)
        col.prop(context.scene, 'mainColor')
        col.prop(context.scene, 'secondaryColor')

bpy.utils.register_class(VIEW3D_PT_color_pair)

For my test, this creates a panel that looks like:

panel for testing

(The panel shows up in the Monkeys tab of the sidebar because I've been following the Scripting for Artists tutorial and that's the tab used in the tutorial.)

Here's the tab showing the two colors being different after I change first the main and then the secondary:

panel showing different colors

Here's the tab immediately after changing the main color without modifying the secondary.

panel after modifying primary

Having done this, you can use the new custom properties as drivers for RGB inputs in shaders, or anyplace else you want to use them.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.