📜 ⬆️ ⬇️

Unity3d, to help beginners


This article is intended for those unity3d users who are already familiar with the engine itself, but do not yet have a sufficient knowledge base of their own to write without additional surfing on the Internet, in order to search for sometimes emerging fundamental issues. In order to reduce some time on the cross section, I’ll tell you a few important pieces that every unity programmer needs to know. If you have any questions: how to make sure that you do not slow down on something weaker than iPad 3, or you do not know how to work with sprites, how to make the music not interrupt when loading, or how to bypass the maximum allowable size for android (50 megabytes ) and so on, you may find the answer in this article.

The article addresses only the problems of mobile development (iOS, Android). All examples are only in C #.

The author of the article does not claim absolute categorical and correctness of the proposed solutions.
')


Basics of the basics


1) Be sure to read the recommendations from the Unity developers how to write optimal scripts in terms of performance.

2) It is best to create a class, a direct heir from MonoBehaviour, which implements caching transform and other similar properties of MonoBehavior, all the main scripts inherit from it:
Code with an example of caching
public class Qwant : MonoBehaviour { private Transform _qwantTransform = null; public Transform qwantTransform { get { if (_qwantTransform == null) { _qwantTransform = transform; } return _qwantTransform; } protected set { _qwantTransform = value; } } } 


3) Use a static class with static methods and fields to store global parameters of your game (unless data should be saved when you close the game, then use PlayerPrefs), but such an object should be only one, do not get carried away. Keep in it only such global things as the current state of the game (play paused; we are in the menu; a list of available perheys with their prices, obtained from the server, etc.)

4) Always use (even if your game is all in 2D) two cameras one for game objects, another for GUI, specify the necessary layer for the GUI elements (camera GUI layer and you will be happy) Of course this does not apply to the menu, where one plenty of cameras.
Screenshot with GUI camera


5) If you want your iPad GUI to look non-blurry and the same on all devices, you do not want to resize it depending on the screen size, make the camera GUI size 1.59. Quietly make everything up to the size of iPad2, on other devices everything will be scaled by itself.

6) If you need to drag several objects to the list of another object, and you do not want to drag them one by one, you can fix the object displayed in the inspector by clicking on the lock in the upper right corner (you can see it in the previous picture too).

Work with 2d sprites (tk2d plugin)


In Unity3d, there are almost no tools for working with 2d sprites. You cannot create a texture map without the use of plug-ins, and you will have to write sprite animation yourself (in 4 unity this case was slightly corrected). To work with sprites it is best to use the tk2d plugin. The plugin at the time of this writing was worth $ 65, and, in my opinion, it fulfills them 100%. The plugin allows you to:

For quite a long and dense use of the plugin, not a single bug was noticed.

In conclusion, I want to attach the script code, which stretches the tk2d sprite to the whole screen without distortion, perhaps at first glance it’s difficult for the problem to be solved, but it always works.

Example: PlaneResizer.cs

Graphic text


What kind of game without a beautiful font? To create a beautiful graphic text is best to use Glyph Designer , works only on a Mac, paid, but convenient. There are at least two free counterparts working under Windows, but you will not get a truly beautiful text in them.

Programs for creating graphic fonts will create an xml and texture map, use them in tk2d or in the free EZ GUI.

Pool of objects


One of the problems that can be encountered when writing a game is the high cost of the object creation operation, that is, the high cost of the Instantiate operation. To solve this problem, to begin with, you can use CoRoutine, but if on the mobile device even the creation of a single object slows down, then you need to use the generating design pattern of the Object Pool .

This way you can get rid of lags when creating objects, and all of them can be instantiated when loading a level. The desired object is very convenient to search and get through the name field.

This is the only way to deal with lags when writing a game with a dynamically generated level, for example, when writing a runner.

Quality levels


Mobile devices are very different in resolution, but you always want to ensure that the game works with good performance on all devices. It is absolutely optional to prepare several different builds for different devices (4 apk for android and 2 builds for iOS).

First, properly set the Quality levels in the game (Edit-> Project settings-> Quality):

Quality Settings Screenshot


In unity3d there is a great opportunity to switch Quality right at the stage of application launch.

Thus: it is necessary to create the Quality Levels we need, and to write a small script that can be hung on the pre boot scene. This script will switch the quality, in accordance with any of our conditions.

For example, you can change the quality of textures from Full Res to Quarter Res. Of all the functions and properties we may need, only:

An example of such a script: CorrectQuality.cs

DontDestroyOnLoad objects and endless music


If you want the main theme of the application to play continuously, even when reloading from one scene to another, you must use DontDestroyOnLoad (gameObject);

That is, the object with our music is never removed. It is important to take into account that there are several such objects that we cannot remove. For this, it is advisable to use the Singleton programming pattern.

In the same way, and other non-removable objects.

An example of such a script: Music.cs

TouchDispatcher


Touch events is a shared resource. For convenient use, you need to write a controller that will distribute received events between the objects processing them.

In my personal opinion it is very conveniently organized in cocos2d / x , the concept proposed by this game engine was taken as a basis:

1) there is an interface containing the handling of 4 standard touch event functions: TouchBegan, TouchMoved, TouchCancelled, TouchEnd. If an object catches touch events, it implements this interface.
2) There is a class TouchDispatcher - a class that manages and delegates events.

For ease of testing, it is necessary that there is no difference between the mouse and the finger, after all, compiling for a device is a long time. Also consider the following:
  1. the ability to use multitouch
  2. captures (swallow) a touch object an event or not
  3. priority of objects
  4. add object to delegate list
  5. removing an object from the list of delegates

After writing such a simple class, working with touch becomes very convenient, simple and clear. The resulting script is hung on GameObject, which is placed in the root of the scene, for example, under the name SharedTouchDispatcher. The script implements the delegate interface, looks for our TouchDispatcher through GameObject.Find (“/ SharedTouchDispatcher”) .

Example: TouchDispatcher.cs , TouchTargetedDelegate.cs

AccelerometerDispatcher


All that is written above for TouchDispather is also true for an accelerometer, with one exception: there is only one accelerometer for the device, which means that the code for the implementing controller is a bit simpler.

There is only one feature that you should not forget about when working with an accelerometer: if the device is turned upside down: PortraitUpsideDown or LandscapeRight, we must not forget that the values ​​along the x or y axis change, respectively. We will get backward-oriented management without taking this into account.

Example: AccelerometerDispatcher.cs , AccelerometerTargetedDelegate.cs

Check if a point hits a concave polygon


One of the most common tasks of computer graphics. In short: the point is inside a non-convex polygon, if the beam directed in either direction crosses the edges of the polygon an odd number of times.

The algorithm itself can be easily found on the Internet.

I consider this task now in the context of hitting a touch into a GUI object (Of course, you can do everything by checking whether the beam hits the collider , but, in my opinion, for 2D objects it is better to use the method proposed below).
For simple buttons, you can use regular rectangles and touchZone.Contains (position); . But if objects are of complex shape and overlap each other, this will not be enough.

The coordinates of the stroke - the polygon of our conditional button can be taken from VertexHelper , unfortunately, I don’t know anything better and nothing for windows.

As a result, we get the coordinates relative to the center of our 2D object, which is what we need.

The resulting string is easy to drive into our processing script, and parse into an array of points:

Code with an example of parsing a string into an array of points
 private void ParsePath(){ //   char []separator={',','\n'}; string []numbers=pathTouch.Split(separator); Path= new Vector2[numbers.Length/2]; for (int i=0;i+1<numbers.Length;i+=2){ Path[i/2]=new Vector2(float.Parse(numbers[i],NumberStyles.Currency),float.Parse(numbers[i+1],NumberStyles.Currency)); } } 


Thus, it remains only to implement the algorithm for finding the intersection of straight lines.

Implementation Example: Crossing.cs

Also included is a class layout that implements the delegate interface for touch events, and checks for hitting a finger in a stroke.

Example: SpriteTouch.cs

Additional levels from the Internet WWW


If you need to download some of the levels from the Internet after installing the game, then WWW.LoadFromCacheOrDownload is your best friend. But it only works in Unity Pro.

You can upload only specially prepared scenes, you can create them using
BuildPipeline.BuildStreamedSceneAssetBundle . Honestly speaking, under Unity 3.5.2 it worked quite smoothly under IOS, but I think it has been fixed since then.

The Unity documentation details and fully describes the entire process of organizing the loading of layers from the network.

Conclusion


I hope someone proposed article will be useful, and help save some time.

Almost all of the above has been used here :

Source: https://habr.com/ru/post/167541/


All Articles