Methods of loading in panda3d? (Solved)

Hey, it has been sometime, but I have developed my game to a point where one scene is not going to cut it, first, I want my game to feature multiple playable characters that you can play as at different points of the game, so I was wondering how would I implement this?

I have looked around in the forums for while and came up with a method, this method involves taking a variable and assigning it to a variable assigned as a node, example.

model = Actor("folder/model.egg)
self.node = model

it worked at first, but then when I want to assign the node to a variable that is of a different model using the equal sign, panda3d gets glitchy, did I do something wrong? is this a good method? I was also thinking of using empty collision node with a simple collision sphere and just reparent the models to that node when I want to use them as a alternative but it has it’s problems.

I wanted to ask if I did anything wrong or there is a better way to load in new content or reload old content, this is also important as I want my game to feature multiple levels/scenes, I know that panda uses a empty cartesian space, so adding in or removing models would be the way, but I need to do this while the game is running.

I researched that panda3d featured “toon town” a game disney made, and though I never played it, from a few videos, it feature loading of different areas, so I know this is possible in panda3d, I’m just wondering if I,m doing it wrong or if there is a proper way to do this.

As far as it goes, that should work, I believe.

Are you perhaps not cleaning up any Actors, or not removing models (whether Actors or otherwise) from the scene?

If you are cleaning up and removing your models/Actors, could you elaborate on what you mean by Panda becoming “glitchy”?

In general, storing the various elements of a scene–characters, scenery, interactive objects, and so on–in an appropriate set of variables seems like a good way to go about it. This allows you to keep track of the components of your scene, work with them as called for (such as moving a character, or opening a door), and then clean them up and remove them once the scene is done.

Depending on the complexity of your game, I might suggest encapsulating the various logical parts of a level–starting with the level itself–into an appropriate set of classes. That might help you to organise them, and to keep a clearer idea of how they relate to each other.

Clean up? do you mean with the “cleanup()” function right?, if so, I tired calling it first before assigning to a new object, and the problem persists, sorry I should have elaborate what I meant by “Glitchy” what happens is the camera turns completely to the sky.

Not only that, but the character refuses to move (aside from a slight turns) and judging from the tests the model never changes, because the setup I have is, I have blank copy (no animations) of the model I’m using that is assigned first to a global variable then that variable is assigned to the “character variable” first in the class itself as I need to define the self.actor object first for the upcoming functions.

Then the actual model (with the animations) is assigned to another global variable in a special function that I created to handle character changes, the function is setup to change the assignment immediately upon the program starting, but I know it is the blank copy because the model is in the default position and never animates, anyway thanks for responding.

The response is my pleasure. :slight_smile:

I’m a little tired as a write this, so please forgive me if I miss something. ^^;

That’s good. However, did you also remove the model from the scene (via “removeNode”)? If not, it may still be there, even if you add another.

At a guess, is the camera parented below the model? If so, then you’re presumably leaving it attached to a non-functional (i.e. cleaned up) Actor. I’m not quite sure of what it might do in that case!

I recommend detaching the camera (using “detachNode”) before cleaning up and removing the old model, and then and re-parenting it to the new one.

Hmm… That’s odd. I’m not sure of quite why that’s happening. I would imagine that it’s most likely a bug in somewhere in your code, however.

That seems… awfully complicated for the purposes of loading a character-model.

Why do you use global variables for this? Why not just load the model directly into the instance variable, and do that when the object is created, or just after?

And if a temporary “blank node” is really called for, why not just use a temporary NodePath holding a simple PandaNode?

While I confessedly speak without knowing your game, I feel like you may have over-complicated your system. ^^;

so I have to removed the node too? okay, I try that, the thing about the camera is it not so far removed from it’s “roaming ralph” counterpart, so the camera is looking at a empty node called “cam target” which is parented to the actor’s node, I could try a wrtReparent to render.

The movement is a custom version of the roaming ralph movement, so pushing in negative Y moves the character forward in whatever direction it’s facing, so a theory of mine is the movement issue may be due to the position of the camera, but I need to test this today.

The blank model is in place because the tasks run immediately upon starting the program and will return a error if left empty, I was reading on these forums yesterday, and someone on another thread suggested maybe using a empty node as a avatar and just parenting the models to that avatar, I,m thinking of a empty collision node, which I,m going to try today.

Well, I tired normal variables vary early on, but for some strange reason they never worked, the main reason was, I assumed that because panda tasks always repeat, so if I tired to assigned a variable in it, upon it’s repeat, it would redefine itself as that form again thus undoing any changes, and it would stay fixed on that form due it’s repeating nature.

There are also less common reasons like getting reports of variables getting called on before assignment due to my coding style (I,m not experienced at programming), so global variables always worked for me, so I stuck with them.

Regarding the camera and the node that it’s looking at, the fact that the “cam target” is parented to the character is likely an issue, too. You may want to stop the camera from looking at it until the new character has been loaded, or–as you suggest–“wrtReparentTo” the “cam target” to “render”.

Regarding the movement, I think that you’re likely right: I imagine that the character is being moved in the horizontal direction in which the camera is facing–that is, along the horizontal component of its “forward” vector. Since the camera is facing upwards, the horizontal part of its “forward” vector is tiny, and so the character only moves a little, if at all.

Regarding the “empty node”, what errors are you seeing?

Regarding the tasks, why not start them after you’ve loaded the scene and characters? When loading a new scene, you could remove the tasks, and then create them anew once you’ve finished loading (see this page for how to remove a task).

Alternatively, you could have some logic in your task that checks the state of the level, and only runs the code that applies to these nodes if the level is ready.

Regarding global variables, fair enough! If they work for you, then by all means stick with them. (Although I’ll warn you that I fear that they can result in a bit of a mess as the project grows, and you have more and more things to keep track of.) In that case, why not stick to global variables, and drop the instance variables?

That said, when you feel ready, I do encourage you to branch out to a more object-oriented approach: I think that it can really help to keep things organised, and prevent your code from accumulating a huge number of global variables to keep track of.

Okay then I’ll try the reparent method, as for the empty node error, I forgot, I’ll rerun some tests and come back to you on that one. in terms of tasks, are you suggesting maybe a “if” statement to control weather the task runs logic or not, if so that actually sounds like a good idea, thanks, I’ll try it.

On the variables, to be fair, I was hesitant of using global variables because it reminded me of stories when I was researching game engines and languages about beginner programmers using global goto statements to create “spaghetti code” so i,m aware of the issue and it’s dangers.

However, I,am still what you would call “on the fence” phase of creating a game, so I need to first prove to myself by creating working game demo before I really invest into this, right now, I,m doing whatever means necessary to create this demo, and taking the steps needed to push the project forward.

Once the demo is created, I’ll look into a udamy course to learn proper programming ethics, and do a clean up on my code.

EDIT: okay, I just remembered, the empty node glitch more of a issue I had rather then a glitch, because I tired it first with a panda node at first and it give a error when I tried to attach a collision sphere to it, I already figured that out, so I changed to a collision node.

My issue was with the “pusher.addCollider” as it asks for the actor and collision node, but with a blank collision node I only have 1 argument, the collision node, so I don’t know if I can get the pusher to work, I’ll try without the “pusher.addCollider” though, to see if it works without it.

Well things take a interesting turn, it seems after hours of testing, finally got the camera and controls to work using my swimming mechanics, the problem lies with the reparenting process, and it makes sense, panda3d reparents to my object, but because my object equaled to a actor object, the reparent went to the actor object that was referenced instead.

So the fix was simply reparenting to the object again just after that object equaled to a different actor object, I,m still having problems with collision so I had to use my swimming mechanics as it is unaffected by my gravity code to test this out, now it is just collision and the model itself not changing.

Sadly I attempted this solution with the collision but no results, can you reparent collision nodes?

That’s fair enough, I think. Good luck with your demo–I hope that you succeed at it! :slight_smile:

If I’m not much mistaken, it doesn’t ask for an Actor, just a NodePath. (Alongside the collider, of course.) It should work perfectly well if you give it an “empty” NodePath (i.e. one created with just a simple PandaNode inside it).

That said, I again feel that your underlying issue may be with the order in which you’re doing things: why not call “addCollider” only after you’ve finished setting up your character, and thus have both the collider and model ready to pass into “addCollider”?

I think so, yes.

Hum. At this point, perhaps it might be easier to help you if I saw some of your code. Would you be willing to put together a short, simplified program that demonstrates the problems that you’re seeing? Strip out anything not part of the issues (as far as is feasible), and replace references to your own models and animations with references to the default Panda models and animations.

This might make it easier for me to spot quite where you’re stumbling.

I’ll give it a try, the assets are much bigger than before though, so let me get back to you on this one, give me a while.
Edit: okay, here you go:
nfccdemo.zip (2.0 MB)
The gravity turns on instantly, so you won’t be able to move around much, to fix this, turn on the swim mechanics to explore the area, swimming can be turned on by flipping the global boolean called “swimming” to true on line 65.

The swimming controls: “J” projects forward, while left and right turns those directions, down turns up and up turns down (the camera is fixed/scripted for swimming so ignore controlling it).

Well, I finally got the character to appear, it was the same problem as the camera, the object needs to be reparented, but this time to render again, as it changes it’s actor reference, it becomes that reference and in my case that reference was never parented to the render so I got invisibility instead.

Still trying to figure out why collisions don’t work though, I think the problem I had was I thought everything was going to be applied to the label only, not the reference objects (actors) themselves, but I guess that is not the case, heh, the more you know I always say.

Oh, Thaumaturge, I forgot to give thanks for wishing luck on my demo, thank you.

Edit: finally I got collision to work, it was the same issue, but because I used the pusher handler, need to call “pusher.addCollider” again. Thanks for the help Thaumaturge, if it was not for you I would not have ever looked into panda3d’s node attach and detach methods and found out the true nature of the reparent command. big thanks, this thread is pretty much solved.

Ah, I’m glad that you’ve managed to solve your problems! Well done! :slight_smile:

Good luck with the rest of development then. It sounds like you might be starting to come to grips with the engine. :slight_smile:

Thanks, yeah, there are some bumps here and there, but progress is being made thanks to determination and a vary helpful community.

Hey, I just wanted say I changed the main(1st) post to include a fallow up on this topic, don’t worry, the original topic is solved, but I had another question that is similar to this that I did not want to spam the section with another thread that looked the same, so I updated this one. once again thanks to anyone who wants to help.

You should either post your follow-up question as a reply to the same thread or open a new thread. If you modify your original post to contain a different question, that makes the thread very difficult to follow.

Oh? uh, so should I change everything back and make a new thread? I dd not change anything on the original post, just added to it. sorry I did not intend to confuse anyone.

Edit: rdb, I,m going to fallow your advice then, and make a new thread, I reverted everything back to the way it was before I made the fallow-up, sorry for any trouble this may have caused.