📜 ⬆️ ⬇️

Object movement to a point in Unity3D

Introduction


Suppose we have an object that must move to a point. The problem is simple, use interpolation, for example. But what if our object can turn at a random angle? How then to set the point for interpolation? After all, surely our conventional trolley should move only in the direction of its wheels. Accordingly, either the back or front side. Vector algebra will help us to cope with this task.

Theory


We accepted the fact that with the help of vector algebra this problem is solvable. So we need to do something with vectors. But what? To begin with, we project the concept of a vector onto our task. By the condition of the problem, we need to specify a point for interpolation. That is, a point relative to the global / local coordinate system to which the object will subsequently move. So the segment between the point of the object, which we have adopted for the task of movement, and the final desired point will be a vector.

Now we know that we have a vector and we need to find the coordinates of its end. To uniquely solve this problem, a set of parameters is needed:


Suppose we know all this. Then the problem reduces to the simplest formulas of the sine theorem.
')
$ inline $ x / sin (α) = a / sin (90) $ inline $
$ inline $ x = a * sin (α) $ inline $
$ inline $ y / sin (90 - α) = a / sin (90) $ inline $
$ inline $ y = a * sin (90 - α) $ inline $

where a is the length of the vector, α is the angle of inclination to the coordinate axis

Actually, this knowledge is enough for us to solve the problem in practice.

Practice


So, we know:


Almost all the information we have, but according to our case, we numerically know the angle of rotation of the object, but it is not known with respect to which axis it turned. Additional data required. Then we introduce the concept of a quarter. It's no secret that in the two-dimensional Cartesian coordinate system there are 4 quarters, from 1 to 4, respectively. In each quarter, the axes have different signs.



And in unity, it also works. First, we need to define the quarters in the scene. Create a cube at the origin, move it and see which coordinates are negative and which are positive. In the example you can see that both coordinates are negative, so the cube is in the third quarter.



Now you can proceed directly to the script. At the entrance we accept the Transform of the original object after the rotation and the Transform dummy, to which we will subsequently move. The dummy initially has the coordinates of the object. Next, we define the quarter in which the front of the object is located. Since the trigonometric circle is limited from 0 to 360 degrees, this is not labor. Having determined the quarter, we calculate the angles of inclination for each coordinate. Then we check that our corners have the correct sign. After that, we send the angles of inclination to the final formula for calculating the coordinates. And finally, we set the new coordinates to the dummy to which we will interpolate.

void ChekingQuarterUp(Transform vectorAngle, ref Transform empty) { float zangle = 0; float xangle= 0; float zcoord = 0.0f; float xcoord = 0.0f; int normangle = Mathf.RoundToInt (vectorAngle.eulerAngles.y); if (normangle >= 0 && normangle <= 90) // 1-  { zangle = 90 - normangle; xangle = 0 - normangle; xangle = (xangle < 0) ? xangle * -1 : xangle; zangle = (zangle < 0) ? zangle * -1 : zangle; } if (normangle > 270 && normangle <= 360) // 2-  { xangle = 360 - normangle; zangle = 270 - normangle; xangle = (xangle > 0) ? xangle * -1 : xangle; zangle = (zangle < 0) ? zangle * -1 : zangle; } if (normangle > 180 && normangle <= 270) // 3-  { xangle = 180 - normangle; zangle = 270 - normangle; xangle = (xangle > 0) ? xangle * -1 : xangle; zangle = (zangle > 0) ? zangle * -1 : zangle; } if (normangle > 90 && normangle <= 180) // 4-  { zangle = 90 - normangle; xangle = 180 - normangle; zangle = (zangle > 0) ? zangle * -1 : zangle; xangle = (xangle < 0) ? xangle * -1 : xangle; } zcoord = path * Mathf.Sin (zangle *Mathf.PI/180); xcoord = path * Mathf.Sin (xangle * Mathf.PI/180); float newpathx = empty.position.x + xcoord; float newpathz = empty.position.z + zcoord; empty.position = new Vector3 (newpathx, empty.transform.position.y, newpathz); } 

Conclusion


As you can see, the solution is quite simple. Before using this method, check whether you have enough data, otherwise the task becomes unambiguously unique. For example, removing the angle of inclination to the axes, the circle with an infinite set of points becomes the area of ​​the solution.

For movement "backwards" you only need to diametrically change the signs of the coordinates according to the quarters. If you decide to define a point in three-dimensional space, then keep in mind that there will be more "quarters" there.

An example of the implementation of the method can be found here .

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


All Articles