Hello, i am new with unity3d, i was wondering how to start to create an enviroment like xcom (with destructable walls and terrain in blocks)
for small maps, just doing individual objects per walls could work for example 2 buildings 20x20x3 will be 400 floor cells + 80 walls per floor, but this will hit hard on performance on bigger maps. I was reading about mesh modification in runtime, but i dont know where to start.
For example lets say i want a wall (using a cube) with this size: ( 5, 1, 0.1) and when someone hit between x=3 and x=4 to break in 2 walls (2,1,0.1) with a space between them. so for a 25 meter wall i will only need 8 vertexs.
is this the best way to do it? is the worse? for floors 25x25 if i hit in the point 12,15 how i modifi it?
It probably won’t hit performance hard. Xcom is a heavy hitter for performance as it is. The perspective will cull most of them out, and the maps really aren’t very large. Just use objects.
Not all of those are visible at one time. In fact a quarter of your numbers would be visible, maybe less.
10,000 draw calls on screen at once? Bear in mind this isn’t close to what xcom has on screen. Your game is obviously much more ambitious, so you will need to re-think what you’re doing.
Do you even have pathfinding worked out for this on a dynamic basis? think about the big picture and consider scaling back just how much is doable. Not all of xcom’s environment is destructable. Floors generally aren’t, and parts that are tend to be very specific.
recently i was playing again xcom Apocalypse and i found that the terrain was totally destructible, i mean with a gun u can create a cave on a mountain like minecraft. The difference is that xcom work with floors, so when you are in the floor 2 u are only watching what is on that floor and under it if visible (for example on floor 3 of a building u can see the street, but not the floors up. But probably the trick is too on the isometric camera, not able to look other angles. or to watch more map that predefined by the static camera distance.
Please also consider that xcom (if we are talking about the newest, Enemy Unknown/Enemy Within), does not randomly generate the content of its cells.
This gives the advantage of not having a draw call per cell, as much of the geometry can be batched at both design and runtime.
The cells are there virtually in code(mostly just to represent the location/states of enemies), and represented by overlays, but the geometry is just like most other games.
Every level is pre-designed which has many performance advantages. (It is worth noting that you can get the same advantages from randomised levels, but it will take a lot more technical know-how)
If you want randomisation of cells, you have to think about how you are going to combat the geometry side of things for performance, and the navigation and destruction side of things mechanically.
I play xcom every night and have seen no such thing. I was playing xcom: enemy within and unknown, I guess apocalypse is a different game, so disregard my thoughts.
so lets imagine i store all the cubes info in a 3 dimension array, i put an isometric camera with locked distance so can only be moved in X and Z, and then update the scene based on camera position to only draw the cubes who are visible (Maths between camera angle and X,Z position and distance could give me a square of representation in the scene and limit the draws there.
So if my camera can watch lets say 15x15 to avoid rendering all the other blocks (probably some code to see whats visible on underfloors)
Don’t optimise too early - you could make performance worse. Just try it out, create a basic game - you’ll soon know where the bottlenecks are.
Then worry about optimising.
i have a prefab box (1,0.5,1) as floor terrain per each cell
i have a prefab box (1,2.5,0.1) as walls
i put an empty gameobject in the scene and i plan to initialize the map on the Awake function of his script.
read xml (floor → row → cell)
create an empty GameObject if that cell contain a floor or a wall.
instantiate the floor from the prefab, apply a material to the box and change HP value in his script based on xml type property.
instatiate each wall and change his position over the floor based on pos property, and his material and HP value based on type property.
attach floor and walls to the Empty GameObject “cell”
set this “cell” object position based on the xml data.
my doubt right now is: if i have a prefab wall or floor stored on my “Resources” folder with the script already attached, once i instantiate it with (GameObject)Instantiate(Resources.Load(“name”)); how can i access this instantiated object parameters stored on his script?
Great - looks like you’re off to a good start. Might be worth a couple of hours creating a simple builder using Winforms/WPF? I’ve done it myself for a couple of projects - if only I knew some way to “attach” them to Unity
yep probably is a good idea, the only concern is that it take 2-3 seconds when i press the start button to draw all, probably reading the xml and xml nodes :s i will put here my code, maybe someone can tell me if xml is not a good idea or the way i read it is wrong.
maybe taking lists of nodes is slow and i should try linq to xml?
It’s hard to say, but I’d probably lean toward blaming the actual object instantiation itself for the slow speed - it can get quite slow if you dynamically add hundreds/thousands of objects at once.
Do you need it to generate at runtime? It’s possible to modify it to load an XML document and run the script/set up the scene from within the editor before you even click the Play button.
As minionnz suggested, it’s more likely the instantiating that’s causing the slow start rather than the XML, but if you want to be sure, use Debug.Log to throw out some timestamped data (using the Time class) at various parts of your loading/building process. Better to be sure what’s going on before you start breaking working code
TOTAL TIME: 70.1222
UnityEngine.MonoBehaviour:print(Object)
so 70 miliseconds is not bad for instancing right now:
7x20 first level floors
33 walls first floor
7x10 second level floors
34 walls
so is 270 instances in 70 miliseconds. thats 0.25 miliseconds per item, if it scale lineal for example for a map 100x100 will be 10.000 on first floor, and lets say another 100k more in buildings, placeables, etc, 110k *0.25 is 27,5 seconds loading… thats too much maybe.
I will test it with more instances to see if it go lineal, but i am thinking that maybe in a future is posible to compress the map.xml in a way that the exact same blocks are together with their position so clonning them instead creating a new one maybe is faster.
i will post the time soon with more than 1000 items.
well, i was working today on a map editor in wpf ^^ and i did it. Now i have to edit all to can choose the texture and type too (wall types for doors, single windows or multiple wall windows and floor type for things like stairs.
i have advanced a a lot (for me :p) but now i am looking for a way to work with levels. i mean after placing all the items in the escene, i want that by choosing a number (level) only items on that level and below to render (to can see inside houses for example.)
I was thinking to create a scrip attached to every object checking a global int variable and if the object Y position/3 (each object is Y=3 height.) is more than the global var, to put the object like:
void Update ()
{
if (gameObject.transform.localPosition.y / 3 > Globals.Level)
renderer.enabled = false;
else
renderer.enabled = true;
}
public static class Globals
{
public static int Level = 1;
}
but this way, the renderer have to run over all the items anyway. Is there a way to split items between diferent renderers or something like that to enable and disable a group instead each item?