Most of you may know that moving object diagonally is faster than moving object horizontally or vertically. You can watch a short youtube tutorial here. If an object is set at (0,0) then using this code.transformation.postition += new Vector3(x, y, 0f).Assume moving object on 2D plane. When looking the object position at 2D grid(cartesian plane), for value x=1, y=0, it move one position right, for value x=0, y=1, it move one position up and for value x=1, y=1 it move one right and one up. When look at the following image, the line drawing diagonally is obviously longer than others. I read about vector, the magnitude of vector, Pythagorean theorem. Assume an object move one unit every frame. Then after 1 frame passed all objects will be moved 1 unit exactly. But when calculate in magnitude[length] of vector the units are different. I mean 1 in X or Y and around 1.4 in diagonal. Aren't object moving from point to point? Does Unity move object in vector's magnitude value and set the point on X and Y plane? How do object actually move?
Unity is a frame-based engine. So Unity calculates the positions where objects are in a frame, and when it comes to calculating the next frame, the positions are calculated there as well. One could assume that the object has moved between these frames and conclude that, for example, a projectile must have hit a thin object between the two frames.
If you want to move an object consistently in any direction, first clamp the direction with normalized and then add a custom magnitude.
Related
I'm still making the game about tower building using Unity and now I have problem that have haunted me for about week now.
Game mechanic for losing is that there is line which goes up at a certain speed and when it goes above the tower, game should end. I'm wondering is there any way of checking highest objects highest point(because of rotated objects and irregularly stacked objects)?
There's a few ways to achieve this:
1) You can shoot a bunch of rays down from high up in the sky. Find all the hit.point positions and then loop through the points and store which building is the highest.
2) Another would be for each block of your building that is added - keep it as a child of an Empty Building gameObject. Then all you need to do is see which Building gameObject has the most children and you know it's the tallest. This assumes all blocks are the same size in Y and then you can easily calculate the height with highestChildCount * blockSizeY
3) Another way to do it would be to use the point in the line that is traveling up. Shoot a ray out of that point to the left and right. If it is hitting a building then the game continues. If it doesn't hit anything the game is over. This is the simpliest as it doesn't require calculation of any heights and your buildings can be made any way you like as long as they have colliders on it for the ray to hit. <--- This is likely the best method for what I'm hearing you asking.
(Note. I might have some spelling mistakes in the naming of methods so proofread before copy-pasting)
Since your are using a line, you might want to find the bounding box of an object. I have never tried the bounding box method so it might not work. The second method uses a little bit of math. If your line is vertical, then finding the highest point is easy. All you need to do is find the y position of the object and add half the y-scale to find the highest point. Note it will only work if the transform origin of the object is at the center. If the origin is at the bottom of the line you will have to add the full y-scale value. If its one third the way up, then only 2 thirds the y-scale value. I think you get the idea. This rule apples for the next condition too. If your line is at an angle, this is where it gets a little bit more complicated. We need to find the absolute value of the rotation in which the line is rotated at. Make sure the line is rotated at less than a 90 degree angle from being vertical. After this, we need to know the length of the line. Imagine a right triangle that the line itself is the hypotenuse, the base is the distance between the farthest left point of the line to the farthest right on the line(or other way around), and the distance from the lowest point of the line to the highest point of the line being the actual height of the triangle. Since we know the angle the line is rotated at and the length of the line, we need to figure out the ratio between the side opposite to the angle that represents the rotation the the hypotenuse(aka the length of the line) and the hypotenuse. This always stays the same if the rotation is the same for all right triangles. Because of this why use mathf.sin(), the rotation of the line. Remember to convert the rotation value(which is stored in degrees) to radians. This can be done by multiplying the rotation value by mathf.deg2rad. Once we know the sin, we multiply the length by the sin value that is outputted. Now we know how long the distance from the bottom to the top of the line is. Again, if the origin is the middle we add the y-position to half the value we get from the previous calculations. If it is in the bottom then the y-position plus the whole value we get from the previous calculations. Same rule as before. I am also quite new to Unity, only a little over a year of experience so there may be fallacies in my answer. Hope it helps. :)
I want to change the floor's vertex normals' direction as the ball is rolling on the floor. I just need some direction on how to achieve this.
So far this is the direction that I'm heading:
Make a copy of all the vertex normals of the floor on start.
On collision get the contact point and raycast/spherecast/boxcast to get the affected vertices. (Set variable offset to control how much vertices I want to be affected by the casting)
Find normals related to the vertices.
Rotate the affected normals parrallel to the ball's closest surface point.
As ball moves away from affected's floor's vertices, slowly return the floor normals back to original direction. (Set a variable to control the movement speed of the normal's rotating back to original direction)
I just need help figuring out which type of casting to use and how to rotate the normals parallel to the ball's surface. This is for a mobile platform so performance is a must.
Thanks in advance.
Here's how you'd go about modifying the normals:
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
You'd want to use the vertices list to figure out which indexes to modify (presumably also needing to convert from local space to world space). You could then raycast from the worldspace coordinate to the ball's center,1 and use the raycasthit.normal to figure out what the angle to the ball is.
Some clever vector math from there to figure out the new normal for your plane:
Find the vector perpendicular between hit.normal and Vector3.Up: this vector will be parallel to the plane. If the two vectors are parallel, dump out: your normal is unchanged (or should be returned to its original value, which will be the same vector as the raycast to find the sphere).
Find the vector perpendicular to that vector and hit.normal: this vector will be your new normal.
1 Actually, you'll want to know how far down from the ball's center you should target, otherwise, you'll get the most extreme offsets as the ball moves farther away from the plane. So you want the ball's position on X and Z, but a fixed offset up from the plane for Y. This won't be too difficult to calculate.
I would try something like:
Create a texture for the normals. Each pixel is a normal of a vertex(like a grid). Calculate the correspoding coord between the 3d ball and the position of the normal in the texture and draw a ball/circle/sprite on it (like a sprite) each frame. Then you could use a compute shader to revert them slowy to the default up vector.
I have a plane whose scale is set to 1,1,1. I am willing to get its start position and end position. That what is the position at start of the object in world space and what is the end position.
One easy way to do this job is to place object in start and end of the plane and get object positions but i want to do it through the floor Only.
I just tried this code but its not bringin position in world space.
Debug.Log(floor.GetComponent<MeshRenderer>().bounds.min);
Debug.Log(floor.GetComponent<MeshRenderer>().bounds.max);
Debug.Log(floor.GetComponent<MeshRenderer>().bounds.center);
Debug.Log(floor.GetComponent<MeshRenderer>().bounds.extents);
Renderer.bounds will only match size of the plane if plane transform is aligned with the world. In other world it will only work if there isn't any rotation.
Another approach to get corners of the plane would be to look into the mesh vertices directly. This would require finding vertices on the corners first. Forget that.
Create 2 new game objects and place them on the corners of your plane
Parent two corner objects to plane object
Each corners transform.position will now give you world space position regardless of position, rotation or scale of the parent plane object.
I am continuing to build upon a voxel-based game engine made in OpenTK (a .NET/Mono binding of OpenGL). In this engine, there is a basic class called Volume which possesses traits such as position, rotation and scale, as well as rules to edit these values for animation.
How would I go about providing a function to rotate one point about another point?
I could quite easily rotate an object about its center (by changing its rotation property), but what if I need the object to rotate about origin or a random point in space? This would be useful for grouping blocks together, as I could therefore rotate objects as if they were stuck together - rather than them rotating individually.
I heard I would need to dive in at the deep end and learn about rotation matrices, but honestly it went over my head. The closest resource I have been able to find so far was this link, however it details rotating around an axis. Could somebody adapt these instructions: or even better, give me basic pseudocode for a function that rotates from a position and point of rotation?
EDIT:
The following solution doesn't seem to work. My code is as simple as:
void RotateAboutPoint(Vector3 point, Vector3 amount)
{
v.Translate(point);
v.Rotate(amount);
v.Translate(-point);
}
Should this work, and if not, could anyone help further now that the situation is explained properly?
As far as I can tell, this may as well just be:
void RotateAboutPoint(Vector3 point, Vector3 amount)
{
v.Rotate(amount);
}
Which defeats the object of performing this around a point.
These co-ordinates are not in relation to the object... Sorry if my poor explanation made this unclear before!
I answered a similar question here: Rotating around a point different from origin
in the link you provided author put the steps of rotation :
(1) Translate space so that the rotation axis passes through the origin.
(2) Rotate space about the z axis so that the rotation axis lies in the xz plane.
(3) Rotate space about the y axis so that the rotation axis lies along the z axis.
(4) Perform the desired rotation by θ about the z axis.
(5) Apply the inverse of step (3).
(6) Apply the inverse of step (2).
(7) Apply the inverse of step (1).
Actually in this process (2),(3),(5),(6) are unnecessary if you need to rotate about a point. These steps are the case if you need to rotate your object around a line.
In your case : lets say you want to rotate your object around (a,b)
GL.pushmatrix();
translate your object by (a,b);
rotate your object;
translate your object by (-a,-b);
GL.popmatrix();
EDIT:
Sorry I forgot to add encapsulation of your rotation process.(It was on the post I gave the link though)
Further info:
What is this encapsulation? why do we need this? Answer is simple. OpenGL stores a 4x4 matrice which is initially an identity matrice. When you perform a translate or rotate operation, opengl updates your matrice and at the final state opengl multiply each vertice with that matrice. (And if you do not perform any operation, vertices multiply with identity matrice give you the same vertice coordinates)
The problem in your code is when you don't apply an encapsulation to your rotation/translate block, The final matrice will be same for all your objects in the scene. With encapsulation we guaranteed that the updated matrice will be used only inside that block.
I have a screen filled with circles. One circle is the player, one is the enemy, and the others are obstacles. I want the enemy to be able to calculate if there is an obstacle in the path of a straight line from the player to the enemy, so it can adjust accordingly (it is taking place in space, so it is a straight line for jumping from asteroid to asteroid).
Right now, I just turn a random direction when the AI is stuck on an asteroid.
A simple solution could be find the Vector2 between player and enemy (using Vector2.Subtract), and then divide it into smaller vectors or reduce it to a delta that you choose. This can be done normalizing the distance vector and multipling it by a fixed number.
Then simply add that delta to the enemy position and check if the new position collides with an objects (maybe using Rectangle.Contains method), and do this until you reach the player.