Elevator to Switch Scenes

Hi, I have a floor of a building with an elevator in one scene of an FPS. What I’d like to accomplish is that when you go in the elevator, the doors close and after a time, unseen to the player, it switches to another scene and opens the doors again. The Scene actuator could be used by the elevator’s logic, however the inside of the elevator itself, as well as the player/camera therein, would have to persist from one scene to the next, preserving its state and animations so that there’s not a jolt when the new scene is loaded.

Is there a way to have an object persist across multiple scenes, maintaining its position and state, or is there some other practical way to do this with layers or object groups?

No, you need to a duplicate of the objects in each scene. (You can do that by linking objects through multiple scenes)

Store the state of the objects of the scene you leave.
Restore this values to the object in the scene you enter.

Which is part of a save load system.

Using scenes won’t work very well if you want it to be unseen. There will be a slight lag when switching (lag depending on amount of data needing to be loaded in the next scene). I would have the same scene, but remove every object in the previous level (almost like LOD). You can use scenes. It shouldn’t be THAT much of a lag. Maybe for just a split-second or so…

It works quite well check my saveLoaderDemo

Kudos for the answers guys, and Monster for making the SaveLoader demo.

For posterity, after a couple days of tinkering I got it working, as you said, by linking the player object and then its child camera to the new scene (is there a quicker way to include all of an object’s children when linking?). I then had the elevator execute this after its appointed lifting time:


    player=bge.logic.getCurrentScene().objects["Player"]
    bge.logic.globalDict['pos']=list(player.worldPosition)
    bge.logic.globalDict['ori']=list(player.worldOrientation[0]),list(player.worldOrientation[1]),list(player.worldOrientation[2])
    for act in cont.actuators:
        cont.activate(act) #there's just one activator, that switches the scene.

It uses globalDict as you do, Monster. I tried then adding the following lines after to the above, to restore the player’s position:


player=bge.logic.getCurrentScene().objects["Player"]
player.worldPosition=tuple(bge.logic.globalDict['pos'])
player.worldOrientation=tuple(bge.logic.globalDict['ori'])

They assigned it alright, but in the new scene the player’s position kept getting reset some time afterwards to its original position. You’d think that since the object is linked between scenes, it would preserve its position by itself, but apparently not.

Thus, I had the player execute this module once as an init script:


def load(cont):
    own=cont.owner
    if not "pos" in bge.logic.globalDict:
        return
    own.worldPosition=tuple(bge.logic.globalDict["pos"])
    own.worldOrientation=tuple(bge.logic.globalDict["ori"])

That did it.

The link is just a “data share” between the scenes within the blend file. When starting the scenes you get an own independent instance of the object.

When starting the scene the object is placed at the initial position. When you set the new position it takes one frame for update. There fore it is a good idea to cover the camera with a black plane at the beginning. You can enable wire display that you can look through the plane in Blender.

If your object is set to another place after you restored the position from global dict, you should check if there is something else performing that. The loading was done and has no influence anymore.

Please check for an action. They like to reset positions too.

There’s nothing else moving the player but his own keyboard controls. What I presume to be happening (docs are shabby) is that the scene-setting actuator does not do all the loading then and there, but rather sets a flag for it to occur at the end of the frame. Thus, whatever manipulations you do of any objects after that line in code will be reset at the end of the frame when the actual scene loading occurs.

You’re right about it taking one frame for update; it’s flashing a frame of his original position for an instant after loading the scene, before my first-frame repositioning script kicks in. Sticking a black plane in front of his face all the time that goes invis for all but the first frame of a scene sounds a little crude of a hack; isn’t there a way to just turn off rendering or something for that frame?

What if I wanted Just one scene to have you going up/down?? then scene 1/3 is the top/bottom? (scene 1 is the ground, scene 3 is the top part [Is the control room of an Evil guy…])