Hey folks, long time no see,
so I’m developing some kind of “story” game where the player is walking down a semi-randomly generated path through different landscapes (kinda tile-generated path). Along the path different events (animations, interactions, etc.) are happening.
There are different “tiles” (left, right, forward, upwards, downwards) for each different “biome”. The question I have now is: what would be the best way to handle the different landscape-tile-assets within the code (as each tile is an own gltf-file and therefore its own scene?). Should every tile be its own scene (-> multi-scene-solution) or should there only be one giant file containing all tiles as asset containers? Or is there a way to add a whole file/tile to an exisiting scene (as a kind of “container”) so I can instantiate the different tiles and place them right at the end of the path when the user would reach the next tile (-> single scene solution, instantiating tiles to reduce draw calls).
Thanks ya all!
@Brewcrew-MJ, the way to approach this may depend on your team and/or your versioning method. If you are working on this solo, you may have different constraints on how your assets are authored than if you are working with a team. For example, if you have multiple people making tile assets, you want each asset to be within its own file so that multiple people can be working on them at once. If there is one mesh file, it would need to be checked out to make changes and checked back in to allow others to work on it so no one is stomping changes.
If you are working on this solo, the danger of stomping changes disappears, but you then start to run into questions of versioning and updates. One large file of all mesh tiles will grow to be a massive binary. Even small changes to one of the meshes in a collection file would mean that the entire binary needs to be updated in your source control and this will also bloat the history since you will be updating one large binary often. In this sense, I would avoid one large collection file of meshes as it could make cloning the repo very slow.
Another concern would be loading the file. If you have multiple levels where some tiles are used and others aren’t, you may not want to take the hit for loading one large file when the game starts, but rather spread out the loading or load needed tiles on demand. This would spread load time around the game rather than loading at the front. You could also be asynchronously loading tiles in the background for the next area while the user plays in this area.
Instancing tiles would certainly reduce draw calls if you are reusing the same tile in multiple places. You can use custom buffers on your instances to make your instanced tiles seem unique like in this demo of wooden sphere instances that use custom buffers to offset UVs. As you can see in the image below, there are nine spheres each with a seemingly different texture, but only one draw call.
You could also make use of Asset Containers to keep tiles no longer needed for later use and not need to reload them.
Even how you load your files could be used for optimization. If you have tiles that share textures, load those textures independently of your meshes and build your material separately. This way you don’t need to load textures multiple times for each file that uses them. You can also use SceneLoader.ImportMesh to import specific meshes from a file, or just to make sure you import only meshes and not other nodes like lights.
I hope some of these suggestions help your planning, but feel free to ping back with more questions.
Thx for the fast response! Definitely helped me
But the question was also aiming towards how to import/setup everything. As every landscape tile is its own file (randomly generated pathway, so some tiles might not be used) should I use one scene for each tile? Or only on scene with all the tile-assets being loaded into? But what is the best way to manage all those assets within the code as every tile brings his own camera, lights, etc… Some more detail: the “player” automatically moves along the given path, each tile having its own camera animated along the tiles path-part. So I would have to switch the activeCamera of the scene the moment the player reaches the end of one tile and would start the the next tile.
I imagined something like having only one scene and importing all necessary tile-files as own “container” which I can then place in the scene whenever it is needed.
@Brewcrew-MJ, I think I misunderstood your intended scale. If you mean a tile that is the equivalent of a large chunk of land that the user moves through in 1st person, I can see an argument for different scenes per tile. If you mean the tile is small and the user will see several at once on camera at any given time, I would opt for one scene.
However, even in the event of large tiles, I don’t know that I would want to manage multiple scenes. You certainly won’t get cross contamination between tiles for things like lights if you use separate scenes. However, you can manage that explicitly with
Light.includeOnlyMeshes so you could keep the tiles quite separate from one another.
Part of this is that I don’t know exactly what the structure of your tiles are and what the visuals might look like. If you have visual blockers to allow you to switch between scenes without needing to render mesh from the next tile, multiple scenes may be a nice way to handle it. But I doubt you want to create one scene for every tile in the game at the start. It seems to me that you would want to manage only a couple of scenes at once and load in the needed content for the previous/current/next tile in the path.
This isn’t much different than using one scene and loading in the tiles as needed to the scene. There is one thing you can do here to help streamline this process. Rather than each tile containing their own cameras, it would make sense to have an abstract mesh on the tile that animates for the camera. This could be a locator in Maya or a Null in Blender. Basically a transform that can hold translation, rotation, and scale. When your character gets to the end of one tile, you change the parent of the active camera to the new abstract mesh to continue animating along the path. This prevents the need to manage multiple cameras and streamlines the code a bit. You could also do this with lights in your scene where you have an abstract mesh for the location of the light and create one light for each parent. This would allow you to also set the
Light.includeOnlyMeshes step when creating the light.
I would assume for a lot of the light in the scene, you would be baking it to your meshes through lightmaps or directly in the diffuse texture to save on so many light calculations on static meshes.
There are a lot of ways to solve for your design. It is worth just doing some quick prototyping of multiple approaches so you can see what pain points you run into with each. Just simple grey box prototyping should give you a lot to go on. You may even stumble on an approach that you haven’t thought of through the prototyping that could impact your entire pipeline for the better. I hope this helps.
Thanks a lot for the detailed answers. Helped a lot