0
\$\begingroup\$

I'm currently building an Elevator Bank simulator in Unity3d and I'm stuck on how to reduce the amount of objects it's going to generate when it's done. The simulator will consist of one player (for now) walking into a building, calling an elevator, picking a floor, going up/down and getting out of the elevator again.

To illustrate the problem, I'll sketch 2 scenario's. One where there's no problem whatsoever. One where I simply scale upwards and create a mess. But first, a list of what's inside the simulator (excluding the player).

  • One hull of elevator shafts (3D .obj model).

  • One elevator car per shaft (3D .obj model).

  • One group of hall buttons per shaft per floor (one button for the top & bottom floor, two for the rest).

  • One group of control buttons per elevator car (door open, door closed, etc.). At least 3 buttons.

  • One floor call button per elevator car per floor.

  • Two doors per elevator car.

  • Two doors per shaft per floor.

A simple set-up of 3 shafts and 4 floors will already create 75 objects of which 30 are moving. Take 20 floors, 2 rows of elevators, 3 cars per row and I'm over 600 objects already.

Now. The Empire State building has 102 floors and 73 elevators. Which means multiple banks, a whole lot of floors, a whole lot of buttons and a whole lot of cars. Scaling my current set-up to support that will create a mess at best and simply won't work at worst.

Since this is an elevator simulator, the whole point of it is to make sure every elevator is active from starting the scene to ending the scene. So no tricks like only spawning what's in range of a camera, hibernating objects, object pooling and what not are out.

Now, objects in the same elevator car are static relative to each other. If the car moves up, everything moves up the same amount. So I hope I can move them as a group. Except I have no clue how to do such a thing in Unity. Prefabs may be part of the solution, but that still won't link their movements together. I've considered linking them together like a Snake game, but the amount of objects involved is orders of magnitude more. Luckily, all moving objects (except for the player) will only move on one axis. Doors only slide open/closed, elevator cars and their buttons go up and down. All rotations are fixed.

How do I move so many objects around in a single scene without creating a mess of variables in a performance-wise good way?

\$\endgroup\$
  • \$\begingroup\$ I'm not sure I understand your issue correctly, are you afraid the logic will be too much to handle, or keeping track of the 3D models? in case your issue is where i believe it is, you should consider separating logic from the rendering and indeed only render what's in view, that doesn't mean you completely forget about your other objects though, their logic would keep running, after all positions are just X,Y,Z coordinates, which can be stored in each instance... \$\endgroup\$ – Brian H. Sep 6 '18 at 9:54
  • \$\begingroup\$ @BrianH. I'm not too worried about the actual rendering. I can lower the frequency of physics updates quite far without it becoming a problem, I think. If I understand your idea about decoupling correctly, that would make sense. Only render what you need while keeping track of everything. But that hasn't fix the core issue of 'everything' being a whole lot to keep track of. Having to update the position of all buttons in a car individually doesn't make sense. With a non-game non-realtime calculation, I'd simply iterate over them. I think I'm looking for something to make them all at once. \$\endgroup\$ – Mast Sep 6 '18 at 10:02
  • \$\begingroup\$ Does that make it clearer? You could say may main concern is how to properly scale the solution so the developer (me) doesn't drown (keep maintainability high) while at the same time making sure the engine (Unity) doesn't drown. \$\endgroup\$ – Mast Sep 6 '18 at 10:03
  • \$\begingroup\$ isn't the button's position just the elevator's position +offset? you only need to know the position of your elevator and have the offset stored in your button instance \$\endgroup\$ – Brian H. Sep 6 '18 at 10:09
  • \$\begingroup\$ @BrianH. Right. So I'm fixing the wrong problem and should look into coupling my elevator with it's buttons in a more useful way instead? \$\endgroup\$ – Mast Sep 6 '18 at 10:14
2
\$\begingroup\$

The way this is typically solved is with a transform hierarchy.

Compound objects which need to be multiple separate pieces for a variety of reasons but move together as a unit (eg. the trigger colliders for each elevator button) are grouped under a common "parent" object (the elevator).

Only the outermost moving object (the elevator car) needs a Rigidbody, and the physics engine can simulate the whole assembly as one object. Any travel by the parent object is automatically inherited by all of its child objects. (So you don't need to manually compute the movement of each button on the panel individually)

In Unity, you can set up your transform hierarchy by dragging one object into another one in the Hierarchy window, creating a nested folder structure, or by using the transform.parent property or transform.SetParent() methods in code.

Layers of hierarchy are reasonably cheap to process, especially when they're not moving, so you can use a few otherwise empty GameObjects as folders this way to help you organize your scene.

When you have a temporary attachment between two otherwise separate & independent physics bodies (eg a passenger stepping onto an elevator), rather than re-parenting them, it can be better to create a Joint between them. That way their relationship is visible to the physics engine, and it can reduce jitter that can arise from the two objects trying to move independently, interpenetrating, and correcting.

\$\endgroup\$
  • \$\begingroup\$ That looks a whole lot like what I need, but it will take me some time to make sure. \$\endgroup\$ – Mast Sep 6 '18 at 11:45

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.