66

No this isn't an engine bug or an artifact of a particular rotation representation (those can happen too, but this effect applies to every system that represents rotations, quaternions included). You've discovered a real fact about how rotation works in three-dimensional space, and it departs from our intuition about other transformations like translation: ...


46

Animations in which the character translates away from the origin are said to contain "Root Motion" - because the root bone moves. This allows the animator to directly author subtle non-uniformities in the movement speed, in a "what you see is what you get" fashion. Say the character slows down slightly as their foot makes contact with ...


24

Multiplication At least in terms of Unity's implementation of Quaternions, the multiplication order described in the question is not correct. This is important because 3D rotation is not commutative. So, if I want to rotate an object by rotationChange starting from its currentOrientation I'd write it like this: Quaternion newOrientation = rotationChange * ...


15

Because if you only divide [x, y, z] by z you get [x/z, y/z, 1] and you lost the actual value of z, which is actually useful if you want to do near/far plane clipping or fill a Z-buffer. The best way to keep some information about z, at least on the GPU, is therefore to use 4 components instead of 3. In practice, what is actually in the last two vector ...


15

Where's the dot product used? In Unity, one of the most common users of the dot product is whenever you check if two quaternions are equal via == or !=. Unity computes the dot product to check similarity rather than directly comparing the internal x,y,z,w values. It's worth keeping this one in mind as it makes the call more expensive than you might expect it ...


12

There's a great writeup on this process by Mike Day: https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2012/07/euler-angles1.pdf It is also now implemented in glm, as of version 0.9.7.0, 02/08/2015. Check out the implementation. To understand the math, you should look at the values that are in your rotation matrix. In addition, you have to know ...


12

How is Matrix Multiplication a Transformation? A matrix is just a big grid of numbers with rules that define how we can multiply it with other grids or lists of numbers. In games, we usually want to construct a matrix so that, when multiplied with a list of numbers representing a source position (say, the position of a vertex in a mesh) we get a list of ...


11

Yes, the Update loop is ideal for this. There are no special plug-ins required and you can do this with the free version. Basically you move the objects a tiny bit towards their destination each frame. When all those frames run one right after the other, it gives the appearance of smooth movement. A self contained script would look like the one I've created ...


11

Think about it logically: What is your goal when you render something? To display it on the screen! What are the constraints? The model must be visible to the camera (i.e. in the view frustum, not occluded by other objects, etc.) What are the inputs? A collection of vertices in a coordinate system local to the model's origin. A transformation matrix that ...


10

Because of the linearity (aka distributive property) of vector addition and matrix multiplication, it doesn't matter! Yay! Transform(Sum(v_i)) = Transform(v_0 + v_1 + ... + v_n) = Transform(v_0) + Transform(v_1) + ... + Transform(v_n) = Sum(Transform(v_i)) EDIT: However, transformations are not commutative, so these ...


9

I hope I am understanding your question correctly -- if not let me know. I believe the following is where you are unprojecting the coordinates: @Override public boolean mouseMoved(int screenX, int screenY) { worldCoordinates = camera.unproject(new Vector3(screenX, screenY, 0)); return true; } Because you are using a viewport, you must add the ...


8

Yes, transform.Find(name) will only look in the direct children of the current transform. But if you want to get a child deeper in the hierarchy, you can use slashes to describe the complete path. So transform.Find("Weapon/metarig/upper_arm.R/forearm.L.001/hand.L.001/weapon.L.001/AttackDetection") should work. An alternative might be to use ...


7

The simplest way this can happen is if you shrink an object until its local scale in one or more axes is 0 (flattening it to a plane, line, or point). You can avoid this by disallowing scales below a certain magnitude on any axis. (If your system allows hierarchical nesting of transforms, you'll also have to watch out that no chain of parented matrices ...


6

In short - it is better to do the transformation on the GPU. Firstly, the GPU is designed to support huge amounts of parallelisation. Your CPU on the other hand is not nearly as capable. The NVIDIA GTX 980, for example, has 2048 CUDA cores to process those vertices with in comparison to the 2-16 threads/cores a processor might support. So from a number ...


6

To get a transformation matrix equivalent to the one you have, but reflected across a major axis you can compose it (multiply it by) a reflection matrix. That is, if you have your input matrix M and you multiply by a matrix N that has the reflection. To create the reflection matrix based on the major axis, you take the identity matrix and flip signs ...


6

Because the Y position is never EXACTLY 0. Its for example 5.5 next frame: 4.3 next frame: 3.1 next frame: 1.9 next frame: 0.7 next frame: -0.5 change the if to if (inst.transform.position.y <= 0) Then add: inst.transform.position = new Vector3(inst.transform.position.x, 0, inst.transform.position.z); next to: speed = 0;


5

You can check if cross(up, zaxis) is too close to zero (use an epsilon like 1e-4 or something like that), and switch to an alternative up-vector if so. For instance, if your usual up-vector is (0, 1, 0), you could switch to (1, 0, 0).


5

Pretty sure the easiest way to do rotation like this is to actually hard-code a simple rotation of the underlying array representing the isometric world. Say you have a small array representing tiles, something like this (9 tiles total): [0 2 0] [1 0 4] [1 0 1] Rotate 90 degrees clockwise could be done by swapping the numbers in the array around: [1 1 0] ...


5

When you instantiate using the default constructor for Instantiate, the position is set to (0,0,0). You can use the alternative constructor for Instantiate, and supply a position and rotation. If you want the child object to be position at zero relative to the parent, you can supply the parent position as the position to instantiate to. GameObject child = ...


4

There is a different way. Instead of: child.transform.parent = parent.transform; Use: child.transform.SetParent(parent.transform, false) The false argument specifies to not perform the relative adjustment you are talking about. I'm guessing the reason it doesn't do this by default is because the code is most typically called from the editor, in which ...


4

Local versus world is just a matter of the order in which you compose transforms. For instance, when using row-vector math, multiplying the current local-to-world transform by a new transform on the left will perform the new transform in local space, since it will be equivalent to doing the new transform followed by the old local-to-world transform. ...


4

the problem was in my images size , i set the viewport to be 800x480 but the images size was 800x420 , i just changed the image size to 800x480 and in setSize() i changed it like the following : sprite.setSize(1f, 1f * sprite.getHeight() / sprite.getWidth() ); and its work perfectly now.


4

You're looking for a change of basis. The way to do it is to find the coordinates of the new basis in the old one. For simplicity, we'll say that the FloorClipPlane represents the equation Ax+By+Cz+D=0 Let's do the rotation first, and then we can translate it to the floor. We'll find the coordinate of the Y axis, which happens to be the normal of the ...


4

The value is for Homogeneous Coordinates. Using homogeneous coordinates makes it possible to use things like quaternions and projection matrices. The last entire row is actually for dealing with homogeneous coordinates. Essentially, the coordinates transformed by a 4x4 matrix will be a 4x1 vector, with (X,Y,Z,W) components. The final values of (X,Y,Z) are ...


4

A homogenous transformation matrix (aka a "World matrix") is a 4x4 matrix that defines the translation and rotation of one coordinate system with respect to another. It looks like this: H = [xx, xy, xz, tx; yx, yy, yz, ty; zx, zy, zz, tz; 0, 0, 0, 1]; (Note on notation: This just lays out the matrix row by row. Each row is separated by a ...


4

I'm assuming your question is about the scale change that occurs at the moment you parent one object to another with a net scale other than (1, 1, 1). This can be avoided, as described below. Any subsequent changes to the parent's scale will still cascade down to affect all children however, so if you want the object to retain its scale regardless of what ...


4

NOTE: Edited because it was likely too verbose (source). A rotation matrix actually always defines an orthonormal basis. What this means is each column defines one of your original axes in its rotated state. For example, consider a simple rotation matrix around the z-axis (more on rotation matrices here). Let's say we plug in Pi / 2, in other words, we ...


4

ally = (GameObject) ...is a syntax error. You need to comment this line just like you did the one below it. The problem is on that line, but because it's so malformed (no semicolon at the end), the compiler doesn't recognise it and assumes the problem is on the next line, transform.position = new Vector3(transform.position.x, transform.position.y - -5, ...


Only top voted, non community-wiki answers of a minimum length are eligible