Associating a label with a player

Hi Guys:

I’m kind of confused on this. I want to associate a directlabel that says a player’s name, so that it shows up on top of a player’s head.

class player(Actor.Actor, DirectObject):
    '''a player is both an actor and a event listener class'''
    def __init__(self, parent, player_data, pos):
        # Set player's label
        self.label = DirectLabel(scale=.5,
        self.label.setPos(self, 0, 0, 2)        
        self.label['text_bg'] = (.9,.9,.8,.7)           

This code doesn’t put the label on top of him, it just puts “on” him. Also, if I would like the label to always face me, would I need to use a “billboard” effect?

Thanks very much,

John :laughing:

I’m not sure what you mean by ‘it just puts “on” him’. What’s the problem that you’re seeing?

Although this isn’t your problem, you do appear to be abusing the relative setPos() and wrtReparentTo() operations. You are setting the position of your label to (0, 0, 2) relative to self, which goes through some effort to compute the label’s actual position value (something whacky, unless self is at the origin), and then you use wrtReparentTo() to move your label from where it is, recomputing the position along the way to be what is is relative to self–and the answer will of course be (0, 0, 2).

But you could have saved Panda a lot of trouble by just setting it exactly to (0, 0, 2) in the first place, and there is less danger of introducing an error from numerical imprecision:

self.label.setPos(0, 0, 2)       

Note that you have put the label 2 feet above the origin. If the origin of your character is on the ground, then unless he is very short (or you are not using feet as units), the label will him him in the knees.

Yes, a billboard effect would make your label rotate to face the camera:



Thanks for your reply again Dave.

My challenge was:

  1. I have a isometric game where I’m building models in maya. Now a 1x1 sized square is supposed to be a area big enough to put a building on (in my game design).
    So I’m using the built in panda model to test as the player first. Of course, I’d have to shrink the panda using scale= .00005 or something.

  2. Second of all, each character has a distinct color, during game loading up, I do a player.setColor(hisown_color).

With these two things that I’m doing, when I do a self.label.reparentTo(self), I will have to enlarge the label by like 10000 times for me to see it, also the label also inherits the color property of its parent (the player). THus, I am not able to see the text on the label because it’s painted with its parent’s color. Now, this color problem I still can’t resolve using wrtReparentTo, but at least by using wrtReparentTo I could use self.label.setPos(0,0,2) where I know exactly what that “2” translates to. So I would only need to call wrtRepantTo one time per player. (I read the doc :slight_smile:, it said not to use it unless you have to)

Maybe, using different textures instead of doing a setColor would be better :slight_smile:.

So my original problem was that I needed to move the label much further up in order for it to appear on top of the player instead of lying around the panda’s belly somehwere.

Does what I’m doing make sense?

Thanks again,


Ah, I see. One easy way to avoid inheriting an attribute you didn’t want to inherit is to only set the attribute on a lower node, rather than on the parent of everything. For instance, suppose you are doing this now:

player = NodePath('player')
panda = loader.loadModel('panda.egg')
player.setColor(1, 0, 0, 1)

If you really only wanted the panda to turn red, and not its nametag too, you could just change the last line to:

panda.setColor(1, 0, 0, 1)

A similar trick can often be used for applying the scale.

There are other ways to explicitly specify that an attribute should not be inherited from above, but I think it’s better and clearer to set up your scene graph so that these explicit overrides are not necessary.


Great! :smiley: