Setting a name above player

Hey i’m having a little problem getting the name above players. It seems to just want to put it in the 2d/onscreen. Is there a way to put it out into the 3d world? I know its default is aspect2d but I tried aspect3d and it didnt seem to work.

there is no aspect3D. the 3d counterpart is just ‘render’.

for placing something above a model, use this:

yourtextnode.setPos(modelnode, 0, 0, 3)

(i’m assuming you use Z-up) With this code, the textnode should be placed 3 panda units above your model.

if you wish the text to always look at the camera (means: being readable), use the billboard effect (see manual)

                self.userlistnametext[self.data[0]] = TextNode(str(self.data[0]))
                self.userlistnametext[self.data[0]].setText(self.data[0])
                self.userlistnametextNode[self.data[0]].attachNewNode(str(self.userlistnametext[self.data[0]]))
                self.userlistnametextNode[self.data[0]].setPos=(self.userlist[self.data[0]], 0, 0, 6)
                self.userlistnametextNode[self.data[0]].setBillboardPointEye()

Ok I did what you said but now i’m sorta having another problem. It says keyerror then post the name of that user or aka self.data[0].

That’s a python error, you’re referencing an item in a sequence (list or dict or tuple etc, looks like lists in your case) that doesn’t exist. But you probably already knew that, so I’ll be quiet.

Yea your right ish… I put a . instead a = sign by mistake lol.

Afer playing around with the naming I fine I cant set the postion or can only set it onces… ? Just prints the old postion or (0,0)

                self.userlistnametext[self.data[0]] = OnscreenText(text = str(self.data[0]),scale = 1.5, mayChange=1)
                self.userlistnametext[self.data[0]].reparentTo(render)
                self.userlistnametext[self.data[0]].setPos(Point3(float(self.data[2]),float(self.data[3]),-20.0))
                self.userlistnametext[self.data[0]].setBillboardPointEye()

Hmm now I think I got it to work but its giving some other error XD

    self.userlistnametext[self.data[0]].setPos(0,0,20)
TypeError: setPos() takes exactly 3 arguments (4 given)

Count your parentheses. I’m guessing you’re not closing the Point3() or one of the float()s, which results in the setPos() not getting closed before the next line. In general, you shouldn’t even need to be doing any casting or constructing of new coordinate objects- setPos can be passed the 3 coordinates you want without any special wrapping (i.e. myNP.setPos(x,y,z)).

Oh I know, I just do that cus I need to turn the strings into the floats, but I did try with just the numbers (0,0,-20) and it still says the same thing. So its not just the float() or any wrappering.

That’s odd, then… setPos, when used with raw x/y/z, does implicitly take a 4th argument- self- unless OnscreenText has overridden the default NodePath operation. In fact, that may be what’s happening. OnscreenText may be a specific shortcut for placing text in 2D on aspect2D. You may want to use TextNodes instead. The manual has info. Iirc, you need to wrap the TextNodes in new NodePaths to work with them in space, but that’s trivial.

Tried that all ready… instead I cant use setpos at all.

There isnt a example I can go off is there? I’ve all ready tried from what I know… seems to not be working… so theres got to be something i’m missing or not doing right…

from the manual ( panda3d.org/manual/index.php/Text_Node ):

text = TextNode('node name')
text.setText("Every day in every way I'm getting better and better.")
textNodePath = aspect2d.attachNewNode(text)
textNodePath.setScale(0.07)

only try render.attachNewNode() rather than aspect2d.attachNewNode()
If you’re using a text node properly wrapped in a NodePath, the NodePath does have a setPos.
The only trouble I’ve ever had with this approach is that the text color and size may be changed independently of the NodePath’s color and scale (and with different argument formats to boot), which can be confusing, but so long as you only change one or the other, you should be fine.

    self.userlistnametextNode[self.data[0]].setPos=(0.0, 0.0, 3.0)
AttributeError: 'libpanda.NodePath' object attribute 'setPos' is read-only

Bla I give up v.v; It wont work… I tried differnt ways to make it a read-only…but no luck…

Is there really no other example (beside that one showen) on how it was used like this to post a text over a object, like a user name?

The code at the end of this thread works great for me.

discourse.panda3d.org/viewtopic.php?t=1087

For the record, this statement:

self.userlistnametextNode[self.data[0]].setPos=(0.0, 0.0, 3.0)

looks to Python like an attempt to assign a value to the “setPos” member of a NodePath. It’s not an attempt to call the setPos() method, it’s an attempt to assign to it. If you look closely at the statement you’ll see the “=” sign that makes all the difference between those two completely different actions. This is why Python is telling you that you can’t modify the “setPos” member, because it thinks that’s what you’re trying to do.

Eventually you will get used to understanding the error messages that you get from Python, or at least using them to help locate the real problem.

David

Yea… I been trying to get this to work for almost 7-9 days now and wasn’t having much luck. I was starting to just mistake code after code and my code to shoot has been giving the most terrible time that I started getting confused on the errors them selfs and what they mean. I’m not to bad with python (Been learning it by my self for half a year now) but coding with panda, i’m not so hot at. I do learn from my mistakes and get a new understand between each new error.

Ok 2 more questions and i’ll be done asking for a while I hope.

  1. This model that I was setting the name over moves randomly… or aka its a user that moves around. I tried using the setPos, setfluidPos and posInterval and find them to be a little slow/fast or to jumpy. I was woundering if there was a way to set it to the model it self.

What I tried:
I tried using reparentTo to the model but I find that the node/text disappeared from view. To make sure it was there I made one of my client games to lookAt() that nodel and it didnt seem to look at it… so not sure whats up with that…

  1. Like I said befor I cant seem to get my shooting code to work just right… I can get it to shoot… but I cant get it to go by where the mouse is for say.

What I tried:

              self.shootforward = (base.camera, 0, int(base.camera.getY()) + 5, 0)
              self.bullets[self.NumberOfBullits].posInterval(3, self.shootforward, fluid=1).start()

I’m not sure what to get to send this bullet forward. I treid alot of differnt combinations but to no luck either. I all read know this code doesnt work but it was just a shoot in the dark to try. Been using the base.camera.getX-Y-Z-H-P-R() but it eithers goes right one way but not the other.

Sorry I rather just find this stuff on the forum and try to do it my self, so I can learn how to do it by my self, but just sometimes I just dont understand it and have to ask.

Keep in mind that when you reparent, the node you’re reparenting is placed in the coordinate space of the node you’re parenting to. That means position, rotation, scale, and everything else on the child node is relative to the parent. If you’ve scaled your text down significantly (which iirc you need to do once you put it in render), and your parent is already scaled down, your text may be too small to be visible, or may be rendering inside the parent geometry (i.e. completely occluded from view). Likewise, if you parent your text to a model, and then set its position to model.getPos(), you’ll set the position of the text-relative-to-the-model to the position of the model-relative-to-the-origin, which is not what you want: you probably just want it a unit or three above the model’s origin, or (0,0,z) in the model’s coordinate space.

self.shootforward = (base.camera, 0, int(base.camera.getY()) + 5, 0)

so self.shootforward is a 4-tuple of your camera, 0, an offset from the discretized render-relative Y position of the camera, and 0. Is this what you want?

self.bullets[self.NumberOfBullits].posInterval(3, self.shootforward, fluid=1)

since self.shootforward isn’t actually a vector/position, this line is going to confuse Panda and probably throw errors.

I think what you’re going for is a position interval from the camera to a point 5 units in front of the camera. Using a posInterval for something like a bullet may not be the most elegant way to go, and may give you some trouble later if you want to do things like cull the bullet when it hits something, but it’s probably the quickest and easiest method to set up.

First, you want to know the point 5 units in front of the camera, whichever way the camera is facing. base.camera.getY(), or more explicitly, base.camera.getY(render), gives the Y position of the camera in render (scene) space. Point3(0,base.camera.getY(render)+5,0) is 5 units in front of the camera in render space if the camera is always at the render origin and always facing with its Y axis down the render Y axis and with its scale equal to render’s scale. Point3(0,5,0) in the camera’s coordinate space is what you actually want. There are a few ways of calculating this, but the one I usually use is just placing a new node with no visible geometry at the point I want:

carrot = NodePath("carrot onna stick")
carrot.reparentTo(base.camera) # now it moves with the camera and any future transforms are done w/r/t the camera
carrot.setPos(0,5,0) # move to (0,5,0) in the camera coordinate space

and then get its position not relative to its parent (the default behavior of getPos(), which would always return (0,5,0) in this case; can you see why?) but rather relative to the parent of your bullet, whic is probably going to be render.

toPos = carrot.getPos(render)
fromPos = base.camera.getPos(render)
moveInt = bullet.posInterval(duration=3.0, pos=toPos, startPos=fromPos)

Just… be sure to either .remove() carrot when you’re done with it, or else keep track of it and re-use it rather than creating a new carrot for every bullet. (otherwise you’ll be adding content to your scene every time you fire, which will build up and cause performance issues over time)

Ty soo much for the help, now I feel like it was wasted x.x;. My computer just took a nose dive and crash on me today, so lost most of my work XD Anyways ty again.

If you ever get back into things, a couple more notes:
Apparently intervals can be set up to automatically be with-respect-to a particular node, and independently, can have their start and end points fixed in absolute space. I didn’t know this until recently. You could probably forgo the carrot node by using (0,0,0) and (0,5,0) as your positions, forcing with-respect-to camera (I believe by passing in ‘other=base.camera’) and for safety, “baking in” your start and end points (I believe ‘bakeInStart=True’ and ‘bakeInEnd=True’ respectively) so they stay fixed regardless of where any other reference geometry goes.

Again, I’m improvising a bit here since I’ve never tried the technique myself, but if it works it will save you from things like having the bullets turn/move with the camera, which may happen if you operate heavily relative to a camera-parented node.