How to set up smartphones and PCs. Informational portal
  • home
  • Iron
  • Unreal vs Unity: What's the Best for Mobile Game Development? Benchmarking results. Frame rate

Unreal vs Unity: What's the Best for Mobile Game Development? Benchmarking results. Frame rate

In previous lessons, we modeled and textured terrain, buildings and exteriors. How now to combine all these objects in one scene and arrange them in the right places? Where to find the missing objects - cars, trees, bushes, flowers? We will learn about this in this lesson.

In this tutorial, we will insert objects into the scene using the command Merge(Combine), and arrange these objects with controllers Position List(Position controller on the list), Path Constraint(Restriction along the way), tool Snapshot(Object type) by plugin MultiScatter and its module MultiPainter, and also learn how to translate objects into Proxy objects.

1. Inserting objects from other files.

1. Let's open the file with the landscape. It is in this file that we will insert all the other objects and arrange them over the painted landscape.

2. Let's insert buildings. To do this, go to the menu File(File)> click on the arrow next to the button Import(Import)> Merge(Combine) (Fig. 1).

Rice. 1. Using the Merge command

3. In the window that opens, select the desired file and click Open(Open) (Fig. 2).


Rice. 2. Selecting the desired file

4. A window appeared Merge(Combine), which lists the names of all objects from the attached file. We only need buildings. To select only the objects we need, click on them while holding down the key Ctrl... Push OK(Fig. 3).


Rice. 3. Selecting the required objects

The selected objects are inserted into the landscape scene (Fig. 4).


Rice. 4. Inserting objects

Exercise 1

Insert all exterior items into the same file yourself (Fig. 5).


Rice. 5. Inserting exterior items

Note: if you placed all the objects on your layers, then when you paste these objects into another file, the layers will also be copied. Therefore, if you conscientiously created layers as described in the lessons, then now you have Manage layers(Layer manager) there must be layers as in Fig. 6.


Rice. 6. Layer manager view

2. Inserting objects from libraries of ready-made models

In the previous lessons, we learned how to model many of the objects we need. But there are such objects, the modeling of which will take a very long time, or to create them you need very deep knowledge of the program, or there is simply no point in modeling them, because they already exist and you can simply download them. These objects include cars, trees, bushes, flowers, etc.

There are many sites from where you can download similar models, for example:

  • http://www.3dklad.com/ etc.

Also, some ready-made models can be downloaded from the "Library" section of this site.

Such libraries of ready-made models tempt novice visualizers to assemble a scene quickly and easily, inserting more or less suitable models from the collection into it. But be very careful, because there may be a problem of insufficient hardware resources at the final stage of work. This is due to the fact that downloaded models can have a huge number of polygons.

    First, when searching for models, make sure the model materials match the renderer you are working in (VRay).

    Secondly, after downloading, do not insert the model immediately into your scene, but open it in a separate scene and save the model from all unnecessary things that will not be clearly visible. It makes sense to remove or re-model some elements altogether, because modelers rarely care about minimizing their product.

Only after that you can safely insert the model into your scene without fear of overloading it.

Assignment 2

Download, check and paste ( Import> Merge) into our scene models of trees, bushes, flowers, stones, cars and further at your discretion (Fig. 7).


Rice. 7. Inserting finished models

Be sure to create layers for these objects and place them each on its own layer (Fig. 8).


Rice. 8. Layer manager view

3. "Manual" arrangement of objects

For more accurate and fine tuning of the scene, it is very convenient to use the manual method of object placement. Therefore, we will arrange buildings, benches, urns, road signs, flowers and stones for flower beds, cars in the most usual way - "manually", simply by dragging them with the mouse using the tool Select and Move(Select and Move). We get the missing objects by copying with the key pressed. Shift... Select the copy type Instance(Sample) (Fig. 9).


Rice. 9. Copy missing objects

As a result, we should get the scene as in Fig. 10, Fig. eleven.


Rice. 10. View of the scene after "manual" placement of objects


Rice. 11. Arranged objects

4. "Automatic" placement of objects using controllers, translation to Proxy and Snapshot tool

There are objects that need to be arranged with some regularity, for example, lanterns, trellises, bushes in beautifully "cut" patterns. Therefore, we will consider a way to automate the process of placing objects.

1. Select an object, for example a lantern.

2. Let's translate the flashlight into Proxy object... The proxy object becomes, as it were, a reference to an object that itself is located elsewhere. This will help reduce the heavy load on the program and the video card, and reduce the requirement for the allocation of RAM. This will make it possible to use millions and even billions of polygons in the scene on ordinary computers, which is the best fit for solving our task of creating a city.

We will formulate the prerequisites for transferring an object to Proxy object.

    If an object consists of several component parts, then they must be combined using the command Attach into one object.

    All textures should already be applied to the object.

Only after these conditions are met, the object can be transferred to Proxy... To do this, right-click on the object and select the command V-Ray mesh export(Export to V-Ray surface) (Fig. 12).


Rice. 12. Transferring an object to Proxy

In the opened window in the field Folder(Folder) specify the path to save the Proxy object (it is advisable to create a folder for Proxy objects in the project folder so that Proxy objects are not lost when working on your project on another computer). In field File(File) set a name for the proxy object or leave it as default. Be sure to check the box Automatically create proxies(Create Proxy Automatically) and click OK(Fig. 13).


Rice. 13. Parameters for transferring an object to a proxy

The object will change its appearance. This is another feature of Proxy objects to ease the load. The object may look like a box, like an obscure mesh, or in general like a point, etc. - depending on the selected viewing parameters in the parameters of the Proxy-object - but after rendering it will take its real form (Fig. 14).


Rice. 14. Simplified object display and visualization

3. Check if you have Pivot point(Anchor point, object pivot and scaling point) at the base of the object. Now, by default, the point is in the middle of the lantern. It needs to be moved to its base. To do this, go to the tab Hierarhy(Hierarchy) and select Affect Pivot Only(Influence on anchor point). Now using Select and Move(Select and Move) and Snaps 3 we can move the anchor point (Fig. 15). After that, let's not forget to exit the edit mode.


Rice. 15. Moving Pivot Point

4. Let's create in advance a path along which the lanterns will be evenly spaced. In our case, just create Circle around the park, as in Fig. sixteen.


Rice. 16. Creating a path

5. Assign a lantern controllers... This concept refers to animation in 3Ds Max. With the help of controllers, the developer of three-dimensional graphics can flexibly control the change of the animated parameter of objects. Animation controllers are preset constraints, according to which parameters can be changed. In this tutorial, we will not be using controllers for animation, but for positioning objects.

Select the lantern and go to the tab Motion(Motion). Let's open the scroll Assign Controller(Assign a controller), select one line Position: Position XYZ(Position: XYZ position) and click on the controller assign button. From the list that opens, select Position List(List position controller). This controller allows you to combine several independent controllers at once to create a general animation, and this will be useful to us in the future.


Rice. 17. Purpose of the Position List controller

After applying this controller in the lists Position: Position List> Position XYZ: Position XYZ a line will appear Available(Available), allowing you to add new controllers to the list. Select this line and press the button again Assign Controller... In the dialog box that opens, this time select Path Constraint(Restriction along the way). This controller constrains the movement of the object along the path, which is the specified spline. This controller is used to animate objects along complex paths (for example, the movement of a car on the road). Press OK(Fig. 18).


Rice. 18. Purpose of the Path Constraint controller

Now lower, in a scroll Position List highlight Path Constraint and click on the button Set Active(Make active). In a scroll Path Parameters(Path parameters) click on the button Add Path(Assign path) and select the previously created path. Be sure to check the box next to Follow(Follow), select the desired axis, if necessary, we will reflect using Flip(Flip). The lantern will move to the beginning of the path (Fig. 19).


Rice. 19. Path assignment

6. If you start the animation now, the lantern will move exactly along the path. But all these actions with the assignment of controllers now were not for the sake of animation, but so that the object clearly follows the path we need. Now you will understand why we needed it.

From the main menu Tools(Tools) select a tool Snapshot(Object type) (Fig. 20). It is designed to create an array of objects along the path of animation of the original object (in our case, animation of the lantern along the way).


Rice. 20. Location of the Snapshot tool

In the window that opens, check the box opposite Range(Along the trajectory), we leave the values ​​from 0 to 100, Copies(Number of copies) set at our discretion. Select the copy method Instance(Sample) and click OK... We will immediately see how the lanterns are automatically placed along the trajectory we have drawn (Fig. 21).


Rice. 21. Using the Snapshot Tool

There is one important point left. It is necessary to remove that original lantern with animation, otherwise it will move in a circle on our presentation video. It is very simple to do this: it is currently selected, therefore, without removing the selection, press the button Delete on keyboard.

If any lantern is in the wrong place, you can always move it "manually". As a result, we will have a scene similar to Fig. 22.


Rice. 22. The final view after placing the lights

7. Place lanterns throughout the rest of the city. Where it is not very convenient to use the "automatic" placement of lights - do it manually (Fig. 23).


Rice. 23. Arranged lights

Assignment 3

Place small trellises around the park yourself in exactly the same way (Fig.).

1. Select the small lattice and translate it into Proxy object.

2. Move Pivot point into the base of the object (Fig. 24).


Rice. 24. Pivot Point at the base of the object

3. Draw a path for arranging the lattice - Circle a little more than before.

4. Assign controllers in sequence Position List and Path Constraint... Make the controller active Path Constraint by pressing the button Set Active... Assign the previously created path by clicking on the button Add Path... The lattice moved to the beginning of the path and stood perpendicular to it (Fig. 25).


Rice. 25. Lattice located perpendicular to the path

This needs to be fixed by checking the box next to Follow(To follow). You can select the desired axis if you want to mirror with Flip(Flip) (Fig. 26).


Rice. 26. Lattice located along the following path

5. From the main menu Tools choose a tool Snapshot... In the window that opens, check the box opposite Range(Along the trajectory), leave the values 0 to 100, Copies(Number of copies) we set at our discretion, the main thing is that the grilles fit perfectly with each other. Select the copy method Instance, press OK(Fig. 27). The grids are automatically arranged along the path we have drawn.


Rice. 27. Using the Snapshot Tool

Remove the original animated lattice by pressing the key Delete on keyboard.

If a lattice is in the wrong place, for example, right on the track, you can always move it "manually" or completely remove it. As a result, we will have a scene similar to Fig. 28.


Rice. 28. The final view after placing small lattices

Assignment 4

Place large trellises around your homes and school yourself. Somewhere you will have to place them manually (for example, where there are gates), somewhere this process can be automated. As a result, it should look something like Fig. 29, Fig. thirty.


Rice. 29. The final view after placing large lattices


Rice. 30. The final view after placing large lattices

Assignment 5

Arrange the bushes by the automatic method along the drawn paths (Fig. 31, Fig. 32).


Rice. 31. Arranged bushes


Rice. 32. Arranged bushes

5. "Automatic" placement of objects using the plugin MultiScatter - MultiPainter

We have already considered several ways of placing objects in the scene: "manually" and "automatically" along the trajectory. But what if we need to arrange literally millions of copies of an object, such as grass or forest? The methods already familiar to us will not help here.

You've probably already heard of MultiScatter... This is a plugin for 3Ds max, with which you can easily and easily create scenes with millions of objects. The new version of MultiScatter includes a new and very useful module MultiPainter... It allows you to "paint" objects across a surface using a virtual brush. Drawing can take place both on one surface, and on several at once. You can draw with several different objects at once. Therefore, MultiPainter is ideally suited for our tasks.

1. Download and install the plugin MultiScatter.2. Highlight tufts of grass and translate them Proxy objects (right click> VRay mesh export)... In the dialog box that opens, set the name and folder, put a check mark Automatically create proxies... Push OK.

3. Check that Pivot point was at the base of the tufts of grass.

4. Now we can arrange these objects using MultiScatter - MultiPainter... To do this, on the tab Create choose Geometry and from the drop-down list select MultiScatter, press the button MultiPainter.

After that, be sure to put its designation directly into the scene - to do this, hold down the left mouse button and drag the cursor in any direction (Fig. 33).


Rice. 33. MultiPainter notation

5. After that, go to the tab Modify... Here we see the parameters of the newly installed MultiPainter.

In a scroll Paint Objects(Drawing objects) under Scatter Objects(Objects for placement) it is necessary to indicate the objects with which we will draw. Click on the button + kettle and select our objects in the scene. Button + list allows you to select objects from a list rather than from a scene. Choose objects in the way that suits you best. Button -kettle responsible for removing objects for drawing.

After you specify the objects to draw, two parameters will become available - Probability(Probability, density) and Collision rate(Collision meaning). It is them that will need to be configured. For now, let's set the value for the green beam Probability 200, Collision Rate 5, and for a yellowed bundle Probability 10, Collision Rate 5.

In chapter Brush options(Brush options) can be adjusted Radius(Radius), Softness(Edge softness) and Intensity(Intensity, pressure) of the brush. Let's put Radius 100, Softness 1, Intensity 80... The most important buttons are also located here. Paint(Draw) and Erase(Erase).

In a scroll Surfaces(Surfaces) you must specify the surface (s) on which to draw. The buttons are already familiar to you, their action is similar to the previous ones. We indicate here the surface of our lawn.

In a scroll Rotate(Rotation) you can specify how many degrees objects can be rotated while drawing. We put on the axis Z rotation value 360 degrees to make the tufts of grass appear different and not repetitive.

In a scroll Scale(Scaling) you can specify how much the objects will differ in scale from each other. Let's put the value From(From) 90 , To(Before) 100 .

In a scroll Preview(Preview) you can select the mode of displaying objects in the viewport. Box - each object will be in the form of a parallelepiped, Cross - in the form of a cross, Points, Count - in the form of a set of points, None - will not be displayed in any way in the viewport, which can be very helpful in a heavy scene.

All necessary settings are shown in Fig. 34.


Rice. 34. MultiPainter settings

6. So, we have installed all the parameters and settings we need. Now let's select both beams in the section Scatter Objects and press the button Paint(Draw). We paint with a brush directly on our lawn (Fig. 35).


Rice. 35. Drawing with a brush

How successful the set parameters are for the scene can be seen only after preliminary rendering. Let's look at the result by rendering a picture (Fig. 36). If required, change the required parameters.


Rice. 36. Tufts of grass placed in the scene

Assignment 6

Place tufts of grass throughout the city, using the same method to arrange trees in the city (Fig. 37) and outside (Fig. 38).


Rice. 37. Grass and trees in the city


Rice. 38. Grass and trees scattered outside the city

Note: to save computer resources, you can place objects only where the camera will fly.

It is interesting!

Not so long ago, we came across an interesting article about mobile game development using Unity (dated August 12, 2015); however, the key advantage of the article is that it compares this tool with its main competitor: Unreal Engine.

It is with this remarkable study that we invite you to meet on Friday night. In the comments, we will be glad to see recommendations for publishing books about UE, and also hope for a fruitful discussion.

The article has been translated with small abbreviations.

We (OnlineFussballManager GmbH) are currently starting the development of a new project for mobile devices. We're going to create an addictive and unique combination of turn based strategy and soccer manager game.

Players will be able to plan and create their own club grounds and sports facilities, train the team and work on its tactics. Team players will not be just units in numbered shirts, but realistic personalities with their own features and even facial expressions. Everything will take place in an isometric view of various rooms and areas of the club, where animated buildings will be located in a specially defined grid.

So, the moment of truth came when we started developing the visual presentation.
Considering the requirements set before us and the fact that we have to develop this game for both iOS and Android - how to implement this project technically?

One of the first questions that had to be decided was whether to create your own engine or use an existing one. Of course, the first option is optimal if you want to completely control everything that happens in your source code, toolchain, and also have a good idea of ​​what your income from this game will be. The disadvantage of this approach is that such a development will require a lot of effort - due to which the terms of the entire project will increase, and it will significantly rise in price. We quickly abandoned this idea, as we wanted to keep the cost and timing of the project within reasonable limits.

Of course, you can make a lot of arguments about which engine is better and for what purposes. How many people - so many opinions. I must admit that at some point we also felt such subjectivity. The team has actively supported the Unreal Engine. However, no matter how much we looked closely at the UE, no one could characterize it objectively, without appealing to personal opinion.

So, we decided not to be distracted from the facts and began to explore other, more famous tools.
GameMaker was soon rejected as it is more geared towards newcomers just starting to develop games. So it's pretty easy to learn, but GameMaker's capabilities were clearly not up to the mark.

Then came the turn of Cocos2D, which at first glance seemed promising. As the name suggests, Cocos2D is optimized for 2D game development. So the question was whether we wanted to create our isometric grid of buildings in true 2D or in actual 3D with a fixed viewpoint. After some additional research, we opted for a 3D implementation. In this case, Cocos2D obviously did not suit us.

We turned to Marmalade. After all, with the help of Marmalade such famous games as Plants vs. Zombies and Godus. But, although we found many advantages in this engine, problems remained that forced us to turn to other options. One of the most significant drawbacks was that the Marmalade community is quite small.

So, of the major alternatives, only Unreal and Unity remained. But even at this point, we could not confidently choose one of the two without assistance.

Fortunately, the GDC San Francisco gaming conference was approaching, so we took the chance to fly there and consult with colleagues.

We met with the guys from Epic, got to know Unreal Engine closely, tried Paper 2D, their tool for viewing previews of mobile applications and asked what we could use: their engine or Unity?

The guys made us happy, saying something like the following: “Unreal is cool, but Unity is not bad either. Try both. "

Then we went to the Unity developers and took a closer look at Unity 5 - how it improves performance on iOS. In the end, they asked them the same question and got a similar answer.

At this stage, we decided on a thorough technical study. We designed a prototype that closely resembles our project to test on different mobile devices how the build process will go and what the performance will be. At the same time, we also wanted to find out what pitfalls and problems may lie in wait for us when developing on the first and second engines.

Since all of our programmers were busy on current projects, we entrusted the work on the prototype to specialists from the Bit Baron company.

Engine research by Bit Baron

The Online Fußball Manager (OFM) was planning to create a mobile game. We have been asked for help to better determine which engine is best for their project. Until then, we were exclusively engaged in the development of browser games, but we decided that we could cope with the task. It was suggested to compare two options: Unity and Unreal. Currently, these are two "locomotives" in the world of game programming. There are many reports that detail the subtle differences between the two. But the peculiarity of our work was that we wrote for comparison two almost identical test applications and characterized their performance in accordance with the system of checkpoints (benchmarking).

By writing two similar applications, we were able to test both on a flat playing field, tell OFM which version worked better, and highlight additional issues.

Test case

We wanted to create a benchmark that would provide OFM with information directly related to the type of game they are creating. The customers indicated that the prototype should have several animated buildings and trees. Therefore, we created a 3D scene where the user was asked to independently arrange these objects on the map. The grid was 11x16 and accommodated up to 176 buildings. Each grid square supported up to 6 trees, so there could be over 1000 trees in a scene. We added a simple user interface where you could add a specified number of trees and buildings to the scene. We also added the function of adding buildings in specific places - for this you had to click on the map at the desired point. As for the organization of the program, we built a grid on a plane, and viewed the scene through a camera located "above the user's head". We've also added dedicated camera functionality to allow the user to zoom and pan the scene. Since this prototype was created to determine the engine for development, we did our best to make the scene look almost the same in both versions. Otherwise, it would be impossible to compare the visual quality of the first and second options. I had to tinker with it, as some things are handled differently in Unreal and Unity. We ended up with two very similar scenes.

To unify performance testing, we wanted to apply identical tree and building models to both systems. For trees, a mobile SpeedTree model was used, which included just about 1000 polygons and made it possible to well estimate how small increments in the displayed triangles affect the frame rate. For animated buildings, we couldn't find a model for them that would work with both engines, so we used two different models. Both were sized for just over 16,000 polygons each and had nearly identical material settings. We turned off levels of detail (LOD) completely so that in both options the same number of triangles are displayed at any distance from the camera. The benchmark was designed not only to reflect the performance differences between the two engines, but also to show the difference in rendering quality. I also had to keep a close eye on the standard Unreal Engine shaders. Noticing that Unreal was clearly looking better, we found that there were a number of shaders in the camera that were expensive in terms of performance. After turning them off, the scene visually remained almost unchanged. Lighting was a very different problem, so it took us a while to get it right.

The customers were interested not only in rendering tests, but also in what the impressions of development on the first and second engines would be like. After all, what's the point of performance if you don't have time to write the game on time. To capture these impressions, we compared factors such as build time, available documentation, the complexity of deploying in a mobile environment, and the complexity of iterating over the code. We believed that it was precisely on these indicators that Unity would be stronger (as a flagship in the field of mobile game development).

Unity project

Prototype in Unity. There are 200 trees on the map

Good

  • The core elements of Unity are Objects ("GameObject") and Components ("MonoBehaviour"). Once you have mastered this concept, you can already work with Unity. If used correctly, this system can significantly improve the organization of a project.
  • Unity includes many components that provide you with everything you need to create a game - apart from the game logic itself. As stated above, a component can be as small as the Plane (not available in Unreal), which we used to generate the mesh. The latest additions to the engine are the "UI" and "Layout" components, which provide powerful and scalable graphical user interfaces.
  • The editor can be extended with your own scripts, in addition, the Asset Store has tons of resources for all occasions. The Asset Store also contains many useful scripts, material models, and more. These will be especially useful for prototyping - you can simply load everything you need as temporary resources and use it as a handy simulation model.
  • Unity was one of the first open source engines to support mobile development. Therefore, it is very convenient when deploying in a mobile environment, it looks and acts there in much the same way as in the editor. The system is constantly being improved and the deployment is proceeding very smoothly. This was a significant factor in our decision to make a mobile prototype.
  • Unity is arguably the largest community of any game engine, so if you have a question, chances are there is an answer. While Unity supports many scripting languages, the documentation for each is very solid. Moreover, even if you find an answer concerning another language, the logic of this answer will nevertheless be clear to you, and you can adapt it to solve your problem.
  • Unity has done a tremendous amount of work to optimize rendering for many objects of the same type. To achieve comparable performance in Unreal, you would have to use Instanced Rendering, and this mechanism is usually less flexible than rendering in Unity.

Bad

  • The engine is closed source. If you are talking to Unity about the price of source code, then you have to live with it. Therefore, problems are possible if one or another feature that you rely on fails - you will have to wait for the update.
  • The new UI system is pretty good. It lacks a special editor, all changes are made directly in the scene - and the scene is very large. When you open a scene and want to edit the UI, you first have to scale up the area of ​​interest pretty much.

This is a picture from the Unity editor. We are very lucky that we were able to complement it with our own scripts.

Horrible

  • There are two problems with the new UI system in Unity. When you press your finger on the touchscreen, you will not be able to determine if a particular graphic has been pressed. Let's say the user wants to pan the screen using a slider. But if we inherit from the GraphicsRaycaster class, then we can open any desired data that can be made public. If you replace the GraphicsRaycaster in the canvas object, you can check if the UI element was clicked.
  • The second issue with Unity's user interface has to do with scaling to different display sizes. Basically the canvas object has scaling options with some parameters. But organizing their preview was very difficult, we had to deploy the application to the device several times until we found a normal configuration.
  • Also, we were very confused by the Unity statistics panel. Having implemented an in-game frame rate counter, we compared its value with what was displayed in the statistics panel of the Unity editor. These values ​​were different. After searching the Internet for other implementation options, we found the answer: the statistical panel gives an estimate of how many frames the game would skip if it worked autonomously, and not in the editor. Therefore, the logic of our frame counter was perfectly correct.

The frame rate values ​​are 37 versus 32. In the statistics panel of Unity, we see estimates for the stand-alone application, which do not match the real ones

Unreal project

This is how the project looks in the Unreal editor. There are many specialized nested editors here, some of which are comparable in functionality to entire programs.

In UE, the same screenshot was taken as in Unity (see above), with the mobile settings left by default, without lighting the trees

When the settings were adjusted, the trees turned out better, but still not as good as in Unity.

Good

  • The Unreal trial is completely free. Here you get a fully functional editor. Unity also has a free version, but going to Pro will cost you a pretty penny.
  • Unreal has a powerful editor containing several highly specialized editors. If you are familiar with these "nested" editors, then they will greatly help you with development, and often provide information that you will not see in Unity. There are editors that can even serve as a complete replacement for some programs. The interplay of all these subsystems is a masterpiece.
  • The engine comes with all source code. Therefore, you can delve into it and understand how the individual parts function. Moreover, you can even fix bugs in the engine or supplement its functionality yourself.
  • The visualization in the editor is great. It's just that the eyes run up from the abundance of rendering options (related, for example, to lighting or to the complexity of shaders). Here you will find tons of cutting edge shaders that also come with the engine. Basically, Unreal offers the best rendering engine on the market. You can create amazingly beautiful scenes.
  • Blueprints are handy for quickly creating something simple and implementing basic game logic. They integrate perfectly with C ++, and this decision was made for a reason: it not only opens up tremendous opportunities for both beginners and experienced developers, but also allows them to interact with each other.
  • The overall integration with C ++ is great. As well as a hot reboot.

Drawings are excellent for simple tasks, and their integration with C ++ is fantastic. But if more complex logic is involved, they quickly become cluttered and difficult to deal with.

Bad

  • It's hard to pick up the pace when developing with the Unreal Engine. Even if you know C ++ well, it will take a long time to learn the various macros and functions of UE4. This can be very difficult for someone who is learning C ++ at the same time.
  • Drawings can get confused very quickly. When the logic includes dozens of nodes, each of which contains a blueprint, it can sometimes be simplified to a couple of lines of code written in plain C ++. Usually this is not a problem, since it is quite possible to work with C ++, but with some things, for example, "UMG" (UI system) it is necessary to use blueprints, so it can be confusing.
  • The mobile simulator turned out to be very inconsistent. It gave warnings when we tried to use shader functions that are not used in the mobile environment, but even if the shader passed validation, it might not work. Basically, this simulator is a good thing, but its visual qualities leave a lot to be desired.
  • Although Unreal has a large developer community, we rarely got questions answered there. In addition, almost all of the support we received was in the blueprints. Unreal Engine 4 is actively expanding the community, it is already doing well, it seems that specialists are eager to develop and help. But the Unity community is still better.

Horrible

  • C ++ documentation is seriously lacking. The online reference material for C ++ classes is awkward. In addition, due to constant updates, many features quickly become obsolete. Be careful while watching the help videos, as they may describe an outdated version of the engine and functions that are no longer used.
  • Working with the GUI, we used the innovative "UMG" system. It is based on blueprints and can be very helpful. With a little work, we managed to inherit the C ++ class and clean up a little order with the drawings. However, the system is still crude, lacking some controls like toggle buttons. In addition, there is practically no corresponding C ++ documentation. The editor fell off several times while we were developing the UI. Unexpected failures can cost hours of work and are quite unnerving. The development of this system continues, but so far it is far from perfect.
  • Mobile development with Unreal is slow. The program takes a very long time to deploy to the device. Android had some visual issues like blurry outlines and unlit trees. On iOS, the problems were much more serious. UE4 only supports building for an iOS device if your application consists of only blueprints. This is Apple's fault, but we went all the way through importing development keys (you can imagine) before we ran into this issue. In iOS, textures of trees built on the basis of SpeedTree were not displayed, the trees were gray and bare, without leaves. So, Unity's support for mobile development is a huge improvement over Unreal.

Benchmarking results. Frame rate

Surprisingly, when testing the frame rate (FPS) on different devices, we got very different results. On some devices, Unity wins with any configuration. In other cases, Unreal beat Unity in tests where there were many buildings. In principle, Unreal won, but at a high cost. The image quality and consistency were significantly better in Unity. Unreal textures on some devices looked blurry, trees turned out much worse. The difference in quality was partly due to what is displayed on the one hand in the Unreal editor and mobile preview, and on the other hand on a real mobile phone. This problem was especially evident when it comes to stage lighting. It was very difficult to choose the settings so as to properly adjust the light, the entire setting on mobile devices often looked darkened. In this regard, Unity was much more consistent, the image on any smartphones was the same as in the preview in the editor.

The results for both engines turned out to be much better than we expected (as you remember, in our test models there were about 10 times more triangles than in regular mobile games).

On iOS, both engines rendered animated models with approximately equal success. However, tests with trees on this device were unsuccessful, as Unreal did not display any textures on the tree models. We tried to find the cause of this pattern, but could not resolve it. In addition, it should be noted that when deploying using these engines, you should have an Apple computer on hand. This is very inconvenient, but Apple itself is to blame for this situation. Customers also asked us to benchmark on Windows Phone. Unfortunately, Unreal does not yet support deployments to Windows phone, so Unity won out here by definition. Since Windows Phone still has a very small market share, developing Unreal in this direction is not considered a priority.

Ultimately, benchmark testing only showed that the two engines were nearly equal in strength. Therefore, it is especially important to pay attention to the specific advantages and disadvantages of each of them. In the end, if the performance is so close, then the convenience and speed of development for each of these engines come to the fore.

Other control parameters

Here are some more interesting results that we managed to find out during our tests:

  • Both engines hardly differed in memory consumption. On Android devices, Unity outperformed, on iOS devices, Unreal.
  • The Unity project is significantly smaller (Android: 42 MB / iOS: 100 MB) than the Unreal project (Android: 101 MB / iOS: 173 MB).
  • Unity is about three times faster to deploy to a device. In addition, Unity compiles code much faster.
  • Unreal used up the battery significantly more economically. After two hours of working with 150 animated models on the screen, Unreal managed to drain the battery of Android by 42 percent and iOS by 36 percent. Unity consumed roughly 72 percent on Android and 47 percent on iOS with the same setup and runtime.

conclusions

Based on the research results, we liked a lot about both engines. In addition, we found many areas where these tools can be improved to make the programmer more comfortable to work with. Neither engine had a significant edge over the other given how quickly their capabilities and support changed. Rendering tests have shown that both products squeeze the maximum out of the device and, in principle, are quite comparable. Again, this is where usability and design intuition come to the fore. Considering everything we learned about these engines, and what problems we faced during development, we faced a difficult choice, but in the end we opted for Unity.

Despite the fact that initially we were betting on the victory of Unreal Engine, currently Unity is still a more winning option, at least when it comes to mobile game development.

Here are the main reasons for our decision:

  • Unity is visually more consistent across all devices and quickly deploys with one click on any platform.
  • Unity takes up much less space on the device and has less impact on the end-user experience. Compact size is especially important in the Google Play Store, where the APK has to be split up if the file is larger than 50mb.
  • Unity is much easier to learn and understand. Armed with Unity, inexperienced users can get up and running faster and build products backed by a large community of experts.
  • The iteration time in Unity is much shorter (deployment and compilation of source code is faster, shaders are compiled almost instantly)

We would like to emphasize that our results should be considered in the context of the prototype made. What works for one company doesn't work for another. In addition, there are many more game engines, some of which may be better suited to your specific task. In some companies with sufficient time and resources, it may even be more expedient to write their own engine. There is no one-size-fits-all solution in game development. Do yourself a favor and experiment well. Moreover, many of them become cheaper or even shareware like Unreal. We wouldn't be surprised if Unity also follows Unreal's lead and liberalizes its pricing model.

Conclusion

It is interesting to note that the guys from Bit Barons advised us to take Unreal Engine for our project before prototyping. Considering that we at OFM also initially preferred Unreal Engine, perhaps the final solution turned out to be suboptimal.

Of course, it's not easy to design, write and test a prototype, especially if you just need to decide on the engine for the project. But the issue of such a choice is critically important.

Finally, we took into account a few more factors that could change our opinion. Namely: how easy is it to find experienced talent for each engine nowadays, and what are the business models at your disposal?

On the personnel issue, we consulted with experienced recruiters to find out more or less real numbers. There are currently roughly four Unity Professionals for every Unreal Specialist. As far as the business model is concerned, Unreal does not provide for an initial flat fee, but requires licensing fees. In Unity, the opposite is true. Both of these factors were important to us, and as a result we ended up settling on Unity.

So, building a base in strategy. The parameters that are involved in this process can be very different. Maybe gold or minerals, energy availability, and so on. Each project may have something individual, however, common to all is the construction itself, that is, the arrangement of objects in a certain area. What do we need to do? First, we have a set of icons, each representing a building. When you click on the icon, we get a building blank, which can be moved along the XZ plane. Secondly, you need to make sure that new buildings cannot be created where there is already a building and where it is forbidden to build anything.


This option is suitable only for 3D; for a two-dimensional project, you need to redo the raycast and the plane of motion of objects.

Training. Creation of the buildings themselves, building models. How they will be animated and so on is not important, the main model should be under the collider, this is necessary not only for construction, but also for creating a navigation map of bots. For instance:

The collider must cover the entire object.

After creating the main structure, we make a copy of it and replace the material. That is, the task is to create a preview of the future building. In any strategy, we first drag and drop the layout of the buildings, usually making them semi-transparent. Since this is a layout, then on it we remove the animation if any and select the appearance, for example:


Likewise, the object must be closed by the collider, but in the mode Is Trigger... In this case, the layout collider can be made slightly larger than the original, for example +0.1, this will increase the sensitivity and ensure that it is impossible to create one object on top of another. All layouts must have the Ignore Raycast layer installed! Additionally, we hang on the model Rigidbody and turn off gravity. Plus, we hang up a small script MaskControl:

Using UnityEngine; using System.Collections; public class MaskControl: MonoBehaviour (public string respawnTag = "Respawn"; void Start () (DragAndDrop.isOn = true;) void OnTriggerStay (Collider coll) (if (coll.tag! = respawnTag) (DragAndDrop.isOn = false;) ) void OnTriggerExit (Collider coll) (if (coll.tag! = respawnTag) (DragAndDrop.isOn = true;)))
The purpose of this script is to determine where the object can be installed and where not. In a variable respawnTag we specify a tag that allows installation. For example, if you make a plane with a tag, then a building can be built only in this area, and if an object stumbles upon other buildings, it will be automatically blocked. In general, everything is the same as a conventional strategy.

Next, the names of the buildings. The original building prefabs are named like this id_xxx, that is - number, underscore, name. Layout prefabs, named exactly the same, original and layout numbers - must match, and the names may vary.

Now we hang the script on an empty object DragAndDrop:

Using UnityEngine; using System.Collections; using System; public class DragAndDrop: MonoBehaviour (public Transform original; public Transform mask; public float shift = 0.01f; public string respawnTag = "Respawn"; public static bool isOn; private Transform original_tmp; private Transform mask_tmp; private Vector3 curPos; void Start () (isOn = false;) public void SetMask (int id) (foreach (Transform obj in original) (string name = obj.name.Split (new char ("_"), StringSplitOptions.RemoveEmptyEntries); if (id.ToString ( ) == name) (original_tmp = Instantiate (obj); original_tmp.gameObject.SetActive (false);)) foreach (Transform obj in mask) (string name = obj.name.Split (new char ("_"), StringSplitOptions .RemoveEmptyEntries); if (id.ToString () == name) (mask_tmp = Instantiate (obj);))) void Update () (RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition); if ( Physics.Raycast (ray, out hit)) (curPos = hit.point + hit.normal * shift;) if (mask_tmp) (mask_tmp.position = curPos; if (Input.GetAxis ("Mouse ScrollWheel")> 0) (mask_tmp.localEulerAngles + = new Vector3 (0, 45, 0); ) if (Input.GetAxis ("Mouse ScrollWheel")< 0) { mask_tmp.localEulerAngles -= new Vector3(0, 45, 0); } if(Input.GetMouseButtonDown(0) && isOn) { original_tmp.gameObject.SetActive(true); original_tmp.position = mask_tmp.position; original_tmp.localEulerAngles = mask_tmp.localEulerAngles; original_tmp = null; isOn = false; Destroy(mask_tmp.gameObject); } else if(Input.GetMouseButtonDown(1)) { Destroy(original_tmp.gameObject); Destroy(mask_tmp.gameObject); } } } }
original- an array of all prefabs with original building models.

mask- an array of all layout prefabs.

shift- shift along the axis Y for the model.

respawnTag- tag of the plane on which construction is allowed.

You need to add a few to the scene. UI elements, more precisely icons, GameObject> UI> Image. We create the required number of icons and place them as needed. Then, for each icon you need to add a component Event Trigger, select the function Pointer Click and then drag the script object DragAndDrop into the active field and select the script function from the menu - SetMask and indicate the number of the layout. For instance:


That is, the point is that each icon corresponds to a specific model, so we assign numbers. In the game, click on the icon - send the number to the script - it finds the corresponding model. This is how it works.

LMB on the icon - get a building layout. Repeated LMB - install the building. RMB - cancel. Mouse wheel - rotate.

Top related articles