I'm using Unity3D for a networked multiplayer online game where I have a very large complex 3D terrain scene like a forest, with trees, cliff, hills, mountains, bounders, etc.
Players can also build structures sort of like minecraft, and put them anywhere in the scene, or even move them around anytime.
Aside from the human controlled players, there are automated AI players and objects like animals roaming around the scene following a path.
The problem is how to make these automated AI players and animals, able to navigate around the static and dynamic player created structures, because the path they follow can easily get blocked by player created structures, or even by other players and other AI objects, cliffs etc. So they have to find away around them or get themselves back on track if they tumble down off a high cliff for example.
So I made a navMesh and used NavAgents, but that just takes care of the static, non moving objects, but how do I make the AI players navigate around each other and also the dynamic structures created by the players which can number in the hundreds?
I thought of adding a NavMeshObstacle to everything, but this would result in it being attached to hundreds of objects since the user created structures are built using little pieces like blocks or little tiles to create a larger object.
Here are my questions:
Would attaching a NavMeshObstacle to hundreds of little objects slow down the game?
Is there another way to navigate of dynamic objects other than using NavMeshObstable without slowing down the networked game?
Thanks
Based on the documentation for NavMeshObstacle, one could reasonably assume that if carving (an obstacle "carving" a piece out of the nav mesh) is disabled, obstacles will only affect agent performance when they are in the agent's way. They won't affect pathfinding. The agent will just go around them when it's close. Note that this will not work for you if there are so many dynamic obstacles that the agents need a very different path. You can also set them to re-carve a piece out of the nav mesh only when they've moved a certain amount. You should test the performance, but that sounds like it might work well for you.
http://docs.unity3d.com/ScriptReference/NavMeshObstacle.html
If you don't want to spend much time on making your own "sensor and navigation" system extending unity's navigation then I think your way is through NavMeshObstacles. If you build your obstacles with blocks like minecraft to avoid add NavMeshObstacle on each block you have a huge range of choices on how to limit/approach on your building system.
There is also good AI systems free as RAIN, for example, that implements some extensible and consistent way to do what you want, take a look on unity market if anything there fits your needs.
Related
For my exam project in coding class I have to recreate a game in Unity where I can also show off my OOP knowledge. Some of the requirements of the project are encapsylation, inheritance and polymorphism.
What are some good ideas for a game that can show all these things? The ideas I had was Candy Crush, Street Fighter, Hearthstone or some tower defense, though I'm not sure if I'll be able to make good use of OOP in these games.
All games you're listing aren't really fit for an exam project. I don't know how much time you have to finish this project, but I'd go with something a lot easier, especially if you're going to do it youself. If the main objective is to use your OOP knowledge, any simple game with maybe different kind of enemies or items will do.
For instance, asteorid, but with other kind of objects and weapons beside the asteroids and the main gun themeselves. Asteorids, bombs, fire balls, you name them. All of them must have some degree of common behavior and that's where OOP can be used. Weapons too. Rayguns, double barrels, radial shots, shockwaves...
This is just an idea. You can do something different like Pac-Man and implement diver kinds of ghosts, for instance. Or different main characters with different abilities.
Although, be aware that Unity (and most other game engines) although built on topo of OO languages prefer a Component-driven approach and true OOP is used in very little quantities in very specific parts of the game. Usually data structures more than game objects.
I had a client ask me to build a Tamagotchi type of game and characters are a place where you can use a lot of inheritance to build some base character types then branch off into specific character types. The classic base "animal" and then "bear"/"wolf" etc or biped/quadruped etc some lay eggs, others are mammals you could come up with some good inheritance trees.
In Unity, the different types would need to implement their different ways of triggering animations via the Animator controllers possibly. Most of the systems in Unity won't need any inheritance though, your plain C# classes would implement these and I don't recommend that you build off of Monobehavior. Instead, you have a ScriptableObject and it will instantiance the necessary C# class possibly based on an enum you have that represents all the different types.
Basically it was a 3D Unity Project (nothing used 2D components) and had a simple plane as the ground, and then the camera was above - pointing down at the "ground". The character had 2D art that was perpendicular to the overhead camera, but they were correctly upright with the normal Z world direction so their "feet" were on the ground plane and normal physics/rigidbody can be turned on. This way you can add a Navmesh to the ground and Nav Agents to your characters making movement really simple. They move around like normal, but their art is facing upwards towards the camera. You can give them colliders and rigidbodies. Setting this up took barely any time and saves you from having to work in pure 2D mode with all the problems it comes with for implementing your own movement and control systems, collision detection, etc. If you go pure 2D you lose a lot of systems and it's not necessary. This way you can just use simple 2D art assets.
Your tower defense is also not a bad idea because towers can have inheritance too. Again, design your own classes and you shouldn't be inheriting from Monobehavior in your base class. You aren't expanding on Monobehavior, you are building your own classes.
I'm currently making a 2d platformer game with unity. I'm going to build game world with rooms (like in Hollow Knight and many other metroidvania games). So, my first idea is to have each room as a separate prefab with virtual camera and exits linked to other rooms on scene. And to have several scenes (smth like each scene contains a set of "thematic" rooms).
I have another idea but i'm not sure if it gonna work properly in terms of perfomance. The idea is simple - to have single game scene and instantiate\destroy game rooms dynamically and seamless. So the game will have current room and all adjacent rooms loaded (with some depth maybe, i.e. all adjacent rooms with depth R), when player changes room - some new rooms are instanciated and others destroyed. This feels like a good idea, cause after creating dynamic room system you can just concentrate on creating and linking rooms. But i'm afraid it can lead to some perfomance problems (i.e. game freezes when player moves from one room to another if there is a big enough room nearby). And i guess there can be a lot more unexpected problems.
So it's kind of open-type question. What do you think about this "dynamic" approach? Is it worth trying? If you have expirience building similar games, what design approach did you use?
Typically, creating and destroying objects in-game is a no due to performance issues.
From my high school game dev teacher, a better way to do it is to preload everything outside the camera, and just move needed resources into view as needed for a randomly generated scene.
If you're looking for a static scene, I would just preload everything that I need for that specific scene.
Feel free to close this question if it is deemed too subjective. I realize that it might very well be, as it may focus heavily on best practices, which, if not an industry standard, may be subjective.
The Problem & Idea:
I'm using the tilemap system in unity (2D), and its been working great, but I have a few concerns regarding my particular usage. What I'd like to have is multiple "battle maps" that will get instantiated when the battle scene is switched to. My current idea is to just make each type of battle map a prefab (prefab on the grid, since the tilemaps are just layers), and then instantiate the grid when the scene loads in.
Is this best practice or is there any better way? Does having 10 maps vs 200 maps make a difference?
Other Things I've Considered:
Would it be a better idea to make one huge tilemap with all of the battle maps drawn a distance away from each other and just restrict the camera to moving only within the "current" battle map? The absolute max size I could see a map being is, let's say 30x20 tops, probably closer to half that though.
An earlier idea was to use small pixel map images to render the maps in. This was before I found out about Unity's tilemap system, which, admittedly, I'd rather use because it is so much simpler to visualize, and less work to develop.
The Scenario:
For simplicity's sake, let us assume the game has 2 scenes, the main menu, and a battle scene. Basically, the idea is to enter the battle scene and have a random battle map to be spawned out of what's available. The character(s) get placed, and any additionals also get placed, say, items, or what have you.
Is what I proposed above best practice? And should I consider any other other two systems I've also described? Or is there something I'm not thinking of that would be even better?
I don't believe that any of the above ways wouldn't work, I'm just curious if any of them is the best way to go about doing this.
Your consideration to have all of your battle maps drawn on a single tilemap and restricting the camera to only the region of the current map is an instant red-flag.
In my experience with unity, if I want to have a large level drawn on a grid I will have to break it up into chunks (each chunk is a separate tilemap) for performance reasons in the editor and in the game, so I would not recommend doing that.
If your goal is fast load times, then instancing a prefab as you suggested is not a terrible idea as long as the respective tilemap is fairly small (less than 10000 tiles), otherwise you would almost difinitely notice the map getting loaded in. If you are trying to load large tilemaps seemlessly, it may help to load the tilemap asynchronously before the actual switch occurs.
I would keep only the current map and next map loaded in the scene to ensure a seamless transition and optimal resource usage. Unity's tilemaps are not light.
Imagine a large free-roam game in Unity,
The yellow size indicates about the largest you can make a typical Terrain in Unity.
Art dept. will completely build, meter by meter, the entire scene.
Please note, this has absolutely no connection to repeating scenery (as in runners) or procedural scenery (as in say some race games).
Really, what is the correct and good way to do this in Unity?
use say 50 or so terrains, each perhaps 100m x 100m ?
can you even have or use that many terrains?
or what?
For anyone googling here.
The correct solution is indeed
Terrain stitching
that's it.
In practice you must use one of the tools available to do this (eg, TerrainFormer) or, your team will write from scratch a terrain stitcher.
Yes, you just use "many terrains".
The best approach to the exact problem posed,
is in fact to just:
"use lots of Terrains".
It seems to be perfectly viable in Unity to have many (dozens) of Terrain units, basically "sitting next to each other".
In practice, you'll need TerrainFormer
https://assetstore.unity.com/packages/tools/terrain/terrain-former-20052
or one of the similar tools.
(Or, I suppose, from scratch write your own tool to stitch terrains, and allow you manipulate them all at once, join the edge-heights perfectly, etc etc.)
It's not realistically possible to just perfectly sit many Terrains together (by hand), matching all the edges, etc etc. So you're going to need a "stitcher" package for putting many Terrain squares together.
So, this huge area ..
has about 12 Terrain.
So that's the answer, you can indeed have "many, many" Terrain in a Unity project, you do indeed essentially just "sit them next to each other". In practice it's not achievable unless you use one of the editor tools such as TerrainFormer.
The proper way to do this would have been with procedural mesh generation with MeshFilter and Mesh API but you mentioned that this not at all random or generative so that one is eliminated.
It's just simply a very long, thin, hand-made environment
The best way in this case would be a Modular Level Design. You need to create Modular Assets. With this you can have a long road in pieces which can be tileable. A good modeling artist should be able to create and texture modular assets with 3D modeling packages like Blender, Maya or 3ds Max.
All the programmer has to do is make each asset a prefab then use the Instantiate function to instantiate them to create any distance of environment. You can also create a static environment in the scene from the Editor. Almost anything can be made into a modular Asset especially buildings and roads.
After assembling them in Unity, you can do static batch on all the instantiated modular parts with Unity's StaticBatchingUtility.Combine to improve performance of the game since they are not being moved.
Below is an example of a modular road asset that can be used to create almost any amount of road:
You already answered your question
in this case would it be better to not bother with Unity's otherwise excellent Terrain, and the modellers would just outright build the long course/scenery? (Obviously you'd have to chunk it so it all occludes fine)
I think it's the way to go. If the performance is an issue, try putting each chunk in different scenes and then have a master scene to load them async and additively. And of course you want to unload each scene as it becomes invisible in the camera.
I personally go with your own solution which is letting the Unity Occlusion Culling system to take care of the hiding and showing chunks. I only go with the separate scenes approach if I'm not getting enough performance this way.
I recently had the same problem. We build a tilebased infinite runner with road crossings. The camera was positioned behind and over the car looking down on the street and the player car. So the setup is quite comparable.
We used Curvy from the Asset store to create paths for moving the player and also for creating the geometry of the streets and the surroundings among the streets.
https://assetstore.unity.com/packages/tools/level-design/curvy-splines-7038
It is also easy to spawn tiles with curvy paths and combine them at runtime. So you can separate long distances into smaller segments and spawn them randomly.
We also used QuickBrush from ProCore to quickly paint environment detail to the geometry like trees, bushes or stones. I think procore tools are now implemented in the new Unity 2018 version.
Worked quite well.
Firstly, I'm new to Unity and I'm currently learning c#, please be gentle!
As a project, I'd like to create a simple 3d platform game. The idea being the player starts on a square tile, which is the game platform playing area. They explore different elements on this tile by moving around.
The perspective is 3rd person, so the player is looking down on the action. As they approach the edge of the tile Unity recognises this and adds another tile to the existing one, basically doubling the playing area.
As the player moves around further to the tiles edge, other tiles are added, increasing the discovered areas each time.
My thinking to achieve this would be to have 5 tile game objects, that have different elements like trees already built on them. The question is what is the best way to achieve this.
Would it be to build the complete level with all tiles and then using code restrict how far ahead the player can see, basically to the width and length of the tiles.
Or would it be better to trigger a new tile to appear as the player approaches the edge of the current tile.
Thought, links to example code that I could recycle would be very handy.
Thank you.
The question is primarily opinion based, but here is some advise:
There is no right way to make a game in unity. The correctness is mainly focused on performance; memory and processing.
There are two approaches here:
condition: Your world is endless (or very large) and player moves very slowly over time (say each tile takes more than a second to traverse).
solution: Do not instantiate everything at start, instead when player reaches the edge of a tile look for the next tile in your level structure to retrieve its data and then instantiate its objects.
condition: Your world is not very large (say it has less than overall 10K objects) OR player can move fast (as in Age of Empires game).
solution: Instantiate everything in loading phase and deactivate the game objects as they are being instantiated so that nothing is getting processed at the start of the game. In this case the level structure is a collection of game objects where you activate or deactivate them.
Hints:
Pooling is a good practice when it comes to repetitive objects. Pool is basically an empty game object with a script, and many many deactivated children.
e.g. If you have 1K trees of the same kind you better have a tree pool. Create a game object named tree pool, add a pool script to it and make that script generate 1K deactivated tree game objects in the loading phase. Then whenever your level generator needs a new tree just fetch a tree from tree pool and activate and reposition it. Make sure you clean up the pool after the game ends to prevent memory leak.
you can implement the pool as you like to provide object variations for a specific pool.
Instantiation in run-time is costly especially in mobile devices. Whenever you need to instantiate several game objects at once consider using a coroutine to prevent lag or freeze (this applies to loading phase too).
e.g.
IEnumerable CreateObjects(Data[] data)
{
foreach(var e in data)
{
Instantiate(e);//instantiate here and then wait
yield return null;//this line prevents lag
}
}
//...
StartCoroutine(CreateObjects(data));
//...
Having many active game objects is also costly especially in mobile devices. If many active game object have heavy scripts, the update methods will ruin performance. If many active game objects have rigidbodies or colliders the physics engine processing gets heavy.
Activating game objects is costly but less than instantiation, since it only runs Start method on its script if any, and also causes the physics engine to re-evaluate its structure if it has static collider or rigidbody.
Rendering is costly if only the rendered visuals are (fully or partially) visible to the cameras.
Create an editor project where you can design your levels. in this project you will make use of unity's editor classes to generate some kind of data (JsonObject) which represents your whole world. (collection of levels, tiles in each level and objects in each tile). Moreover you can have other data such as objectives and stuff each stored in a different JsonObject. Then use this data in your game by reading it and storing its structure in memory.
The reason I recommend JsonObject to store data is its size, portability, flexibility, accessibility and simplicity to work with. JsonObject is a dictionary stored as a plain text. and since it's a text you can encrypt it as you like