Security Information Portal. We write arkanoid on Unity

Antipyretics for children are prescribed by a pediatrician. But there are emergency situations for fever when the child needs to be given medicine immediately. Then the parents take responsibility and use antipyretic drugs. What is allowed to give to infants? How can you bring down the temperature in older children? What medicines are the safest?

Unity- very powerful, progressive engine with great potential. It has a lot of already built-in functions (including a physics engine Nvidia PhysX), which we, the users, do not have to manually register. :)
In this short article, I would like to discuss the physical capabilities of the engine. So, let's begin:

Rigid body

What it is?

Behind the function Rigid body Hiding Absolutely Rigid Body ( ATT). If you explain it roughly and clearly, then ATT in physics and mechanics, it is an ideal rigid body that, under the influence of force, cannot change its properties, but can (under its influence) move in 3 dimensions (down, up, forward, etc., i.e. in our X-Y-Z axes), as well as rotate in 3 dimensions (again, along the X-Y-Z axes).

AT Unity, as in other game engines (again, I call them "game" engines roughly), Rigid body used for various objects that we can interact with by pushing, kicking, etc. Such objects under our influence will continue to roll, move and collide with other objects under the influence of gravity.

What application can we find for this function?

For example, to create a car, in addition to Rigid body we need 4 Wheel Collider"and and the code (script) , which applies force to the wheels, depending on the keys pressed.

Configurable Features

  • Mass- Mass of our object in kilograms. It is recommended not to set mass values ​​100 times greater or less than the masses of other ATT.
  • Drag- How much a body is subject to air resistance when it moves under the influence of forces. With a value 0 there is no resistance, and an infinite value will instantly stop our object.
  • Angular Drag- How much the body is subject to air resistance when it rotates under the influence of forces. With a value 0 there is no resistance, and an infinite value will instantly stop the rotation of our object.
  • Gravity- When turned on, the object becomes affected by gravity.
  • Is Kinematic- When enabled, the object becomes unaffected by the physics engine and can only be modified by its function Transform. This can be useful for creating moving platforms, for example.
  • Interpolate- Applies only if the movements of your ATT seem strange or clumsy to you, etc.:
    1. None: Interpolation not applied
    2. interpolate: In comparison with the transformation of the previous frame ( frame) , the next one will be smoothed.
    3. extrapolate: The transformation of the current frame is smoothed compared to the estimated (approximate) transformation of the next one.
  • Freeze Rotation- Disables any rotation, both scripted and collision. However, the rotation can be performed by the function transform.Rotate()
  • Collision Detection- Used to prevent fast-moving objects from passing through other objects without finding collision"ov" (a special "grid" on objects that they collide with each other and with the player).
    1. discrete: The default value for our object to "notice" all other objects that it may collide with.
    2. Continuous: Use Discrete Collision with dynamic collision objects (which have ATT), a Continuous Collision for static MeshCollider"ov (without ATT). Mode Continuous Dynamic uses Continuous Collision for one particular ATT. Rest ATT will use the mode Discrete. (This will greatly affect the load of the physics engine, just leave Discrete, if there are no problems with the collision of fast objects)
    3. Continuous Dynamic: Used for objects in mode continuous or Continuous Dynamic Collision. Continuous Collision will also be used for static MeshCollider"ov (without ATT). For all others, the mode is used Discrete. Used for fast moving objects.

How can we use this feature?

Basic knowledge.

To use ATT, we need an already created game object ( GameObject), by clicking on it, we go to the menu along the following path: Components - Physics - Rigidbody . All, ATT added! :)
Now the object is subject to gravity, you can apply forces to it using scripts, but in order for the object to behave exactly as you need, you should add Collider or joint.

Code rules the world.

In the script, we will now manipulate our object using functions AddForce() and AddTorque() .
Since I'm in Unity apply JavaScript, my examples will be with it, links to other scripting examples (at C# or Boo) you will find below, in paragraph Additional information on ATT.

» Rigidbody.AddForce

// Rigidbody.AddForce uses 2 types of formulas, like many other functions related to movements in space. // 1 type: function AddForce (force: Vector3, mode: ForceMode = ForceMode.Force) : void // The force that pushes the object up, relative to the global coordinate system. function FixedUpdate () ( rigidbody.AddForce (Vector3.up * 10); ) // Using Vector3, a built-in Unity function that is basically the same as the standard coordinate system. // 2nd type: function AddForce (x: float, y: float, z: float, mode: ForceMode = ForceMode.Force) : void // Same, but used here X-Y-Z system coordinates. function FixedUpdate() ( rigidbody.AddForce(0, 10, 0); )

» Rigidbody.AddTorque

// The function spins the object around the given axis. // 1 type: function AddTorque (torque: Vector3, mode: ForceMode = ForceMode.Force) : void // Spins the ATT around the global Y axis. function FixedUpdate () ( rigidbody.AddTorque (Vector3.up * 10); ) // type 2: function AddTorque (x: float, y: float, z: float, mode: ForceMode = ForceMode.Force) : void // Does the same thing, but again in a different measurement system. function FixedUpdate() ( rigidbody.AddTorque(0, 10, 0); )

ATT interacts with objects.

For the correct operation of our ATT they need to be supplied Collider"ami (or collision"ami, as you please ^.^).
Read more about colliders below.

Size matters!

Observe the dimensions of your object, because they are much more significant even mass ATT. If your object is moving incorrectly, floating in the air, or not colliding, try adjusting its magnitude (not ATT, but the object itself). When importing a model from the 3D editor, its dimensions are preserved, so be careful during the modeling stage and respect the dimensions of all models.

Additional information on ATT

On this, describe ATT or Rigid body I'll probably finish. However, there are a couple of tips, especially for those who have read this far :)

  1. standard cube size Unity equals 1 meter, therefore, it is very convenient to check the size of your models using it. To create a cube, select from the menu GameObject - Create Other - Cube
  2. Relative indicator Mass defines how two objects will interact with each other.
  3. Mass does not affect the speed of falling from a height, for these purposes use Drag.
  4. The higher the values Drag the more the object weighs. standard values ​​vary from 0.001(solid piece of metal) to 10(feather).
  5. If you need to modify an object both with scripts and with physics, add to it ATT with parameter Kinematic.

Colliders

What it is?

In the previous section, we discussed how Rigid body and mentioned the so-called colliders. Collider for us - an auxiliary object in the form of a grid of a simple primitive or, conversely, a complex shape, which is located around our model or part of the model and interacts with other objects if they are also surrounded by colliders.
To clearly explain to the experts of the *Warcraft 3* world editor, imagine the model we imported, to which we did not assign path textures in the dudad editor - this will be our object; and the role of colliders here will be played by blockers of the path around the model. Naturally, this is a rather rough comparison, because in Unity they are much more functional. Well, let's take a closer look.

Types of colliders.

Colliders are added via the menu Component - Physics . There are several types:

  • Box Collider- in the form of a cube.
  • Sphere Collider- in the form of a sphere.
  • Capsule Collider- in the form of a capsule.
  • Mesh Collider- automatically creates a collider according to the shape of the object grid, cannot collide with other colliders of the same type. Mainly used for static objects, such as the environment of a race track.
  • Wheel Collider- used for wheels, a very useful thing.
  • Compound Collider- combinations of primitives that together act as one. To create such a complex collider, you need to add child objects to our base collider, and already bind to them by primitive. Thus, for example, simple colliders for cars are very conveniently made.

Configurable Features

In principle, all colliders are similar to each other, they are just used for objects of different shapes, however, they have several different parameters.

  • Cube
    • material- Shows how the collider interacts with other objects, while assigning a physical material, such as metal, ice, etc.
    • Is Trigger- If the parameter is enabled, then the object is affected by the script, not physics.
    • size- The size of the collider along the X-Y-Z axes.
    • Center- The position of the collider, relative to the local coordinates of the object.
  • Sphere
    • Radius- The radius of the sphere, replaces the parameter size.
    • The rest of the parameters are unchanged.
  • Capsule(parameters replace size)
    • Radius- The thickness of the capsule.
    • Height- The height of the cylindrical part of the collider (without rounded bases).
    • direction- The direction of the collider, relative to the local coordinates of the object.
  • Mesh Collider(parameters replace size)
    • mesh- Selecting the desired mesh to create a collider.
    • Smooth Sphere Collisions - Enabling this function smoothes the surface of the collider. It should be used on smooth surfaces, for example, sloping terrain without too much angularity, on which the spheres should roll.
    • Convex- When enabled, allows our collider to collide with other colliders. Convex Mesh Collider"s limited to 255 triangles.
  • Wheel Collider(parameters replace size)
  • Radius- Wheel radius.
  • Suspension Distance- Maximum distance to increase the wheel suspension. Suspension always increases down the local axis Y.
  • Suspension Spring- The suspension tries to reach the specified point using various forces.
  1. Spring:// Attempts to reach the specified point (position). The higher the setting, the faster it is reached.
  2. Damper:// Softens, slows down the speed of the suspension. The higher the value, the slower the damper moves.
  3. Target Position:// The full "path" that the suspension can "travel". 0 means a fully extended shock absorber, and 1 - fully compressed. The default value is 0, which corresponds to a normal car suspension.
  • Mass- Mass of the wheel.
  • Forward/Sideways Friction - Friction parameters for simple rolling of the wheel and for rolling sideways (this happens in skids or drifting).


I like +15 - 0

*Unity* is a very powerful, progressive engine with a lot of potential. It has many built-in functions (including the *NvidiaPhysX* physics engine) that we, the users, do not have to manually prescribe. :)
In this short article, I would like to discuss the physical capabilities of the engine. So, let's begin:

Rigid body
=
= What is this? =
Behind the *Rigidbody* function is an Absolutely Rigid Body (*ATT*). To explain roughly and clearly, *ATT* in physics and mechanics is an ideal rigid body that, under the influence of a force, cannot change its properties, but can (under its influence) move in 3 dimensions (down, up, forward, etc.). etc., i.e. in our X-Y-Z axes), as well as rotate in 3 dimensions (again, along the X-Y-Z axes).

In *Unity*, as well as in other game engines (again, I call them "game" engines roughly), *Rigidbody* is used for various objects that we can interact with by pushing, kicking, etc. Such objects under our influence will continue to roll, move and collide with other objects under the influence of gravity.

What application can we find for this function? =
For example, to create a car, in addition to *Rigidbody* we need 4 Wheel Collider"a and *code* (*script*) that applies force to the wheels, depending on the keys pressed.

  • *Mass* - The mass of our object in kilograms. It is recommended not to set mass values ​​100 times greater or less than the masses of other *ATT*.
  • *Drag* - How much the body is subject to air resistance when it moves under the influence of forces. With a value of *0* there is no resistance, and an infinite value will instantly stop our object.
  • Angular Drag- How much the body is subject to air resistance when it rotates under the influence of forces. With a value of *0* there is no resistance, and an infinite value will instantly stop the rotation of our object.
  • Gravity- When turned on, the object becomes affected by gravity.
  • Is Kinematic- When enabled, the object becomes unaffected by the physics engine and can only be modified by its *Transform* function. This can be useful for creating moving platforms, for example.
  • *Interpolate* - Applies only if your ATT movements seem strange or clumsy to you, etc.:
  1. None: Interpolation not applied
  2. interpolate: Compared to the transformation of the previous frame (*frame*), the next one will be smoothed.
  3. extrapolate: The transformation of the current frame is smoothed compared to the estimated (approximate) transformation of the next one.
  • Freeze Rotation- Disables any rotation, both scripted and collision. However, rotation can be performed by the function // transform.Rotate()
  • Collision Detection- Used to prevent fast-moving objects from passing through other objects without finding collision"ov" (a special "grid" on objects that they collide with each other and with the player).
  1. discrete: The default value for our object to "notice" all other objects that it may collide with.
  2. Continuous: Use Discrete Collision with dynamic collision objects (which have *ATT*), and Continuous Collision for static MeshCollider"s (without * ATT *). Mode Continuous Dynamic uses Continuous Collision for one specific *ATT*. The rest *ATT* will use the _Discrete_ mode. (This will greatly affect the load of the physics engine, just leave _Discrete_ if there are no problems with the collision of fast objects)
  3. Continuous Dynamic: Used for objects in _Continuous_ mode or Continuous Dynamic Collision. Continuous Collision will also be used for static MeshCollider"s (without * ATT *). For all others, the _Discrete_ mode is used. Used for fast moving objects.

How can we use this feature? =
= Basic knowledge.
To use *ATT*, we need an already created game object (*GameObject*), by clicking on it, we go to the menu along the following path: Components - Physics - Rigidbody . That's it, *ATT* added! :)
Now the object is subject to gravity, you can apply forces to it using scripts, but in order for the object to behave exactly as you need, you should add *Collider* or *Joint*.

Code rules the world.
In the script, we will now manipulate our object using functions AddForce() and AddTorque() .
Since I use *JavaScript* in *Unity*, my examples will be with it, links to other scripting examples (on C# or *Boo*) you will find below, in paragraph Additional information on ATT.

Rigidbody.AddForce

// Rigidbody.AddForce uses 2 types of formulas, like many other functions related to movements in space. // 1 type: function AddForce (force: Vector3, mode: ForceMode = ForceMode.Force) : void // The force that pushes the object up, relative to the global coordinate system. function FixedUpdate () ( rigidbody.AddForce (Vector3.up * 10); ) // Using Vector3, a built-in Unity function that is basically the same as the standard coordinate system. // 2nd type: function AddForce (x: float, y: float, z: float, mode: ForceMode = ForceMode.Force) : void // Same thing, but it uses the X-Y-Z coordinate system. function FixedUpdate() ( rigidbody.AddForce(0, 10, 0); )

Rigidbody.AddTorque

// The function spins the object around the given axis. // 1 type: function AddTorque (torque: Vector3, mode: ForceMode = ForceMode.Force) : void // Spins the ATT around the global Y axis. function FixedUpdate () ( rigidbody.AddTorque (Vector3.up * 10); ) // type 2: function AddTorque (x: float, y: float, z: float, mode: ForceMode = ForceMode.Force) : void // Does the same thing, but again in a different measurement system. function FixedUpdate() ( rigidbody.AddTorque(0, 10, 0); )

ATT interacts with objects.
For the correct operation of our * ATT * they need to be supplied with Collider"ami (or collision"ami, as you please ^.^).
Read more about colliders below.


Size matters!
Observe the dimensions of your object, because they are much more significant than even *ATT* masses. If your object is moving incorrectly, floating in the air, or not colliding, try adjusting its magnitude (not *ATT*, but the object itself). When importing a model from the 3D editor, its dimensions are preserved, so be careful during the modeling stage and respect the dimensions of all models.

Additional information on ATT =
On this, describing *ATT* or *Rigidbody*, I, perhaps, will finish. However, there are a couple of tips, especially for those who have read this far :)

  1. The standard cube size in *Unity* is 1 meter, therefore, it is very convenient to check the size of your models using it. To create a cube, select from the menu GameObject - Create Other - Cube
  2. The *Mass* relative exponent determines how two objects will interact with each other.
  3. *Mass* does not affect the speed of falling from a height, use *Drag* for this purpose.
  4. The higher the *Drag* values, the more the item weighs. standard values ​​vary from 0.001(solid piece of metal) to 10(feather).
  5. If you need to change an object both using scripts and using physics, add *ATT* to it with the *Kinematic* parameter.

You can view scripted examples of the impact of external forces on an object with the *ATT* function at the following links:
*Add Force*
*AddTorque*

To change the script example, click on the text with the name of the programming language!

Colliders
=
= What is this? =
In the previous section, we looked at how *Rigidbody* works and mentioned the so-called *colliders*. * Collider * for us is an auxiliary object in the form of a grid of a simple primitive or, conversely, a complex shape, which is located around our model or part of the model and interacts with other objects if they are also surrounded by colliders.
To clearly explain to the experts of the *Warcraft 3* world editor, imagine the model we imported, to which we did not assign path textures in the dudad editor - this will be our object; and the role of colliders here will be played by blockers of the path around the model. Naturally, this is a rather rough comparison, because in *Unity* they are much more functional. Well, let's take a closer look.

Types of colliders. =
Colliders are added via the menu Component - Physics . There are several types:

  • Box Collider- in the form of a cube.
  • Sphere Collider- in the form of a sphere.
  • Capsule Collider- in the form of a capsule.
  • Mesh Collider- automatically creates a collider according to the shape of the object grid, cannot collide with other colliders of the same type. Mainly used for static objects, such as the environment of a race track.
  • Wheel Collider- used for wheels, a very useful thing.
  • Compound Collider- combinations of primitives that together act as one. To create such a complex collider, you need to add child objects to our base collider, and already bind to them by primitive. Thus, for example, simple colliders for cars are very conveniently made.


Custom Specifications =
In principle, all colliders are similar to each other, they are just used for objects of different shapes, however, they have several different parameters.

  • *Cube*

* *Material* - Shows how the collider interacts with other objects, while assigning a physical material, such as metal, ice, etc.
* Is Trigger- If the parameter is enabled, then the object is affected by the script, not physics.
* *Size* - The size of the collider along the X-Y-Z axes.
* *Center* - The position of the collider, relative to the local coordinates of the object.

  • *Sphere*

* *Radius* - The radius of the sphere, replaces the *Size* parameter.
* Other parameters unchanged.

  • *Capsule* (parameters replace size)

* *Radius* - Capsule thickness.
* *Height* - The height of the cylindrical part of the collider (without rounded bases).
* *Direction* - The direction of the collider, relative to the object's local coordinates.


  • Mesh Collider(parameters replace size)

* *Mesh* - Select the desired mesh to create the collider.
* Smooth Sphere Collisions - Enabling this function smoothes the surface of the collider. It should be used on smooth surfaces, for example, sloping terrain without too much angularity, on which the spheres should roll.
* *Convex* - When enabled, allows our collider to collide with other colliders. Convex Mesh Collider"s limited to 255 triangles.

  • Wheel Collider(parameters replace size)

* *Radius* - Wheel radius.
* Suspension Distance- Maximum distance to increase the wheel suspension. Suspension always increases down the local *Y* axis.
* Suspension Spring- The suspension tries to reach the specified point using various forces.

  1. Spring: Attempts to reach the specified point (position). The higher the setting, the faster it is reached.
  2. Damper: Softens, slows down the speed of the suspension. The higher the value, the slower the damper moves.
  3. Target Position: The total "path" that the suspension can "travel". *0* means fully extended and *1* fully compressed. The default value is 0, which corresponds to a normal car suspension.

* *Mass* - Mass of the wheel.
* Forward/Sideways Friction - Friction parameters for simple rolling of the wheel and for rolling sideways (this happens in skids or drifting).

Viewed: 734


My strange creative path took me into game development. Thanks to an excellent student program from an IT company, whose name consists of one small Greek letter, collaborating with our university, we managed to assemble a team, give birth to documentation and set up Agile game development under the supervision of a high-class QA engineer (hello Anna!)

Without much thought, Unity was chosen as the engine. This is a wonderful engine, on which you can really quickly and easily make very bad game which, in their right mind, no one will ever play. To create good game, you still have to shovel the documentation, delve into some features and gain development experience.

Our game used the physics engine in a way it didn't expect, which caused a lot of performance issues on mobile platforms. This article, using the example of our game, describes my struggle with the physics engine and all the features of its work that were noticed on the way to a viable beta version.

The game

A few words about how it is made.
Made with Blender and a couple of python scripts. At the time of shooting, there were 16 squares in the corner of the screen, the color of which encoded 32 bits of a floating point number - the rotation of the phone at a given time. R, G - data, B - parity. 0 - 0, 255 - 1. The video shot on the computer was split into frames using ffmpeg, each render frame was assigned a decoded angle. This format made it possible to survive any compression during the shooting process and overcame the fact that all programs have slightly different ideas about the passage of time. In reality, the game plays the same way as on the render.


The plane flies through an endless and unpredictable cave, in which there are bonuses, all sorts of coins and enemies that you can shoot with homing missiles. Crashed into the wall - immediately lost.
A distinctive feature of the game is that the level is nailed to the horizon and the control in it is gyroscopic, moreover, absolute. Tilt the phone 45 degrees - the plane flew at an angle of 45 degrees. You need to make a dead loop - you have to twist the tablet. There is no sensitivity, only hardcore.
Let's single out two main and obvious problems for the developer:
Problem 1: Infinity
Unity stores and processes object coordinates as normal 32-bit floats with a precision of somewhere up to 6 decimal places. The problem is that we have an endless game and if we fly long enough, all sorts of insane bugs will begin, up to teleportation through walls. There are several approaches to solving this problem:
  • Ignoring. In Minecraft, for example, rounding errors only made the game more interesting by spawning .

  • Teleportation to (0;0;0) when the airplane is too far from the origin.

  • Change of reference point. It is not the plane that moves, but the level around it.
  • In our case, the only acceptable option is the third one, which was implemented. About the implementation - a little later.
    The first - ignoring - is absolutely unacceptable. Creating a robot that can play our game forever is an interesting (and quite simple) task that someone will solve. And ordinary Korean players should not be underestimated - the airplane is fast, the level is generated unpredictably. And if you fly and fly before passing through the walls, then much more accurate shooting will obviously begin to glitch after 5 minutes of flight.
    The second - teleportation of the player and the whole world - brings mobile devices to their knees, in some cases - for about half a second. This is very noticeable, and therefore - unacceptable. But this is a perfectly acceptable option for simple endless PC games.

    Problem 2: Level Generation

    There are several basic approaches to building endless runners:
  • Using ready-made level segments that fit randomly. This is done, for example, in Subway Surfers. It's easy to implement, but the player quickly gets used to it and knows what to prepare for, which is boring.

  • The level is just a straight line on which obstacles are randomly placed. This is how it is done in Joypack Joyride and Temple Run. In our case, this would greatly limit the number of maneuvers.

  • Everything is randomly generated. The most difficult, unpredictable and interesting option for the player.
  • Of course, we chose the most difficult option. At its heart is a very complex state machine that performs random transitions on them. But within the framework of this article, it is not the mechanism that is interesting, but the process of generating the level and its organization, taking into account the chosen starting point.

    Level Structure

    We are flying in a cave, it has a floor and a ceiling - a couple of blocks, elementary building units. Blocks are combined into segments that seamlessly join each other. The segments, as a whole, rotate around the aircraft and move along its velocity vector, creating the illusion of flight. If a segment leaves the camera's field of view, it is cleared of blocks, docked to the last segment of the level and filled with new blocks, according to the instructions of the generator. The totality of such segments is the level.
    Experienced Unity developers could justifiably wince, having estimated the amount of work and all the possible pitfalls. But in words, everything is simple, but I had no development experience ...

    Basic Laws of Physics in Unity

    In a month of developing, experimenting, and reading documentation, I've identified three basic laws of physics in Unity. They can be violated, but the price for violation is performance. The engine will not warn you about the error in any way, and without a profiler you may never know about them. Failure to follow these laws can slow down your game in tens once. As I understand it, violation of any law leads to the fact that the physics engine marks the offending collider as incorrect and recreates it on the object, followed by recalculation of physics:
    1. Colliders should not move, rotate, turn on/off and change size.
    Once you have added a collider to an object, forget about any impact on it or the objects it contains. An ordinary collider is an exclusively static object. A tree, for example, can be with one collider. If the tree can fall on the player - the tree will fall along with the performance. If this tree grows from a magical nutrient cloud that does not have a collider, but can move, this will be accompanied by a performance drop.
    2. If the object is moving or rotating - it must be a solid body i.e. have a Rigidbody component.
    About it it is written in the documentation, yes. Which is not necessary to read thoughtfully to start making a game, because Unity is very simple and intuitive.
    Rigidbody change the relationship of the physics engine to the object. External forces begin to act on it, it can have linear and angular velocities, and most importantly, a rigid body can move and rotate by means of a physics engine without causing a complete recalculation of physics.
    There are two types of solids - conventional and kinematic. Ordinary bodies interact with each other and with ordinary colliders - one body cannot pass through another. Kinematic bodies follow simplified simulation rules - they are not affected by any external forces, including gravity. They are free to go through anything.
    If it is not a pity to give objects under the control of the physical engine - use ordinary rigid bodies. For example, if you need to beautifully roll stones off a cliff. If your scripts or animators control the object directly - use kinematic bodies, so you don't have to constantly deal with the engine and random object collisions. For example, if you have an animated character or a guided missile that explodes on contact with something.
    3. If the object is a rigid body, it must move and rotate through the rigid body methods.
    Forget about directly calling Transform "on an object immediately after adding a collider to it. From now on and forever, Transform is your enemy and performance killer. Before you write transform.position = ... or transform.eulerAngles = ..., say the phrase " I now absolutely clearly understand what I'm doing, I'm satisfied with the brakes that will be caused by this line.” Do not forget about hierarchical relationships: if you suddenly move an object containing rigid bodies, the physics will be recalculated.
    There are three levels of rigid body control:
    - The highest and therefore natural level is through forces. These are the AddForce and AddTorque methods. The physics engine will take into account the mass of the body and correctly calculate the resulting speed. All interactions of bodies occur at this level.
    - Average level - change of speeds. These are the velocity and angularVelocity properties. Based on them, the forces that affect the bodies during their interaction are calculated, as well as, obviously, their positions at the next moment of time. If a rigid body has a very low speed, it "falls asleep" to save resources.
    - The lowest level - directly the coordinates of the object and its orientation in space. These are the MovePosition and MoveRotation methods. At the next iteration of the physics calculation (this is important, since each subsequent method call within one frame replaces the call of the previous one), they teleport the object to a new position, after which it lives as before. In our game, this level is used, and only it, because it provides full control over the object.

    What is left behind? Turn the object on/off and zoom. I don't know if there is a way to resize an object without confusing the engine. It is quite possible not. Turning off the object is painless, and turning it on ... yes, causes a recalculation of physics in the vicinity of the turned on object. Therefore, try not to include too many objects at the same time, stretch this process in time so that the user does not notice.

    There is a law that does not affect performance, but affects performance: a rigid body cannot be part of a rigid body. The parent object will dominate, so the child will either stand still relative to the parent, or behave unpredictably and incorrectly.

    There's another non-physics feature of Unity that's worth mentioning: dynamically creating and deleting objects via Instantiate/Destroy methods is CRAZY slow. I'm afraid to even imagine what's going on under the hood during the creation of the object. If you need to create and delete something dynamically - use factories and fill them with the necessary objects during game loading. Instantiate should be called as a last resort - if the factory suddenly runs out of free objects, and forget about Destroy forever - everything created should be reused.

    Application of laws in practice

    (this section contains the course of reasoning when creating the game and its features)

    The level obviously needs to rotate and move.
    Let's make our life easier forever by placing the axis of rotation of the level - the airplane - at the origin of coordinates. Now we can calculate the distance from a point to it by calculating the length of the point's coordinate vector. A trifle, but nice.
    Cooperative movement of objects is easily implemented through the object hierarchy in Unity because the children are part of the parent. For example, the described level structure is logically implemented as follows:
    - Axis of rotation
    - - Level
    - - - Segment 1
    - - - - Block 1 (Collider)
    - - - - ...
    - - - - Block N
    - - - Segment 2 ...
    - - - Segment 3 ...
    - - - Segment 4 ...
    (You can even do without the level object)

    The script on the axis receives data from the gyroscope and sets the appropriate angle for it ... And it immediately violates many rules, because the rotation will be transferred through the hierarchy to the colliders, which will drive the physics engine crazy. You will have to make the axis a rigid body and rotate it through the appropriate method. But what about level movement? Obviously, the axis of rotation and the level object will not move, each segment must be moved individually, otherwise we are faced with the problem of infinity. This means that segments must be rigid bodies. But we already have a rigid body higher in the hierarchy and a rigid body cannot be part of a rigid body. A logical and elegant hierarchy does not fit, everything will have to be done by hand - both rotation and translation, without using an object for the axis of rotation. Be prepared for this if you have unique gameplay features.

    If you would have to move the segments directly anyway, then you will have to rotate them. The main difficulty is that in the Unity physics engine there is no “rotate an object around an arbitrary point” method (Transform has it, but don’t be tempted). There is only "rotate around its center." This is logical, because rotation around an arbitrary axis is both rotation and movement at the same time, and these are two different operations. But it can be imitated. First, we rotate the segment around its own axis, then we rotate the coordinates of “own axis” around the aircraft. Due to the fact that we have the plane at the origin, you don’t even have to remember school geometry and go to Wikipedia, Unity already has everything. It is enough to convert the angle of rotation to a quaternion and multiply it by the coordinates of the point. By the way, I found out about this right at the time of writing the article, before that a rotation matrix was used.

    We have enemies who push the plane into the wall, hoping to kill. There is a shield that repels the plane from the walls, helping to survive. This is implemented trivially - there is an offset vector, which is added to the coordinates of each segment every frame and reset after that. Anyone who wants to kick the airplane, through a special method, can leave the vector of his kick, which will be added to this displacement vector.

    Ultimately, the real coordinates of the segment, each frame, are calculated by the level's motion control center something like this:
    Vector3 position = segment.CachedRigidbody.position; Vector3 deltaPos = Time.deltaTime * Vector3.left * settings.Speed; segment.truePosition = Quaternion.Euler(0, 0, deltaAngle) * (position + deltaPos + movementOffset);
    After all the calculations and crutches needed to work with the exact docking of the segments during regeneration, segment.truePosition is sent to the MovePosition method of the rigid body of the segment.

    conclusions

    How fast does it all work? On the old flagships - Nexus 5 and LG G2 - the game flies at 60 FPS, with a barely noticeable drawdown when new colliders are turned on during segment generation (this is inevitable and cannot be avoided in any way) and pushing worms out of the ground (you can pile up some kind of hell, to get around it, but now there is a deliberate violation of the third law). 40 stable FPS gives out any device with a gyroscope that we came across. Without knowing and taking into account all the laws, the performance was, to put it mildly, unsatisfactory and the phones overheated. So much so that I thought of writing my own simple specialized engine for 2d physics. Fortunately, the physics in Unity turned out to be flexible enough that all problems could be bypassed and created unique game, it was enough just a couple of weeks of experiments.

    Now, knowing all the main pitfalls of the Unity physics engine, you can quickly clone our game, destroying the dreams, lives and faith of three poor students in humanity. I hope this article will save you a lot of time in the future and will help you to find not quite obvious violations of the laws of productive physics in your projects.

    Read the documentation and experiment, even if you use simple and intuitive tools.



    Support the project - share the link, thanks!
    Read also
    cockfight game rules cockfight game rules Mod for minecraft 1.7 10 watch recipes.  Recipes for crafting items in Minecraft.  Weapons in Minecraft Mod for minecraft 1.7 10 watch recipes. Recipes for crafting items in Minecraft. Weapons in Minecraft Shilling and sterling - the origin of words Shilling and sterling - the origin of words