63

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: ...


45

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

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 ...


14

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 ...


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 ...


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

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

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

Normally I store all objects as 4x4 Matrices (you could do 3x3 but easier for me just to have 1 class) instead of translating back and forth between a 4x4 and 3 sets of vector3s (Translation, Rotation, Scale). Euler angles are notoriously difficult to deal with in certain scenarios so I would recommend using Quaternions if you really want to store the ...


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

You are simply copying the main camera's rotation in your code snippet, try this method: GameObject _go = (GameObject)Instantiate(_hitPrefab, collision.gameObject.transform.position, Quaternion.identity); _go.transform.LookAt(Camera.main.transform); http://docs.unity3d.com/Documentation/ScriptReference/Transform.LookAt.html You should also have a ...


6

Mathematically, the quantity you're asking about is called the operator norm. Unfortunately, there's no simple formula for it. If it's a fully general affine transformation - for instance, if it could have an arbitrary combination of rotations and nonuniform scales, in any order - then I'm afraid there's nothing for it but to use singular value ...


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

If you want to rotate an object around.Center must be at the point(0,0,0) To achieve that simply Translate the object to point(0,0,0) Rotate and Translate back example: Translate(0,0,-1) Rotate(90) Translate(0,0,1)


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

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

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

What you are looking for is the LookAt algorithm. OpenGL already has that in a nice function: gluLookAt, although it multiplies the current matrix instead of returning it to you so you may need some push/pop trickery to get at it. If you want to do it yourself, there are two ways; by constructing a transformation matrix, or by using quaternions. Here's the ...


4

OpenGL is a state-machine, it has a current matrix. There are several functions to manipulate the current matrix: glLoadIdentity, glLoadMatrix overwrite the current matrix. glTranslate, glScale, glRotate, glMultMatrix multiply the current matrix with the appropriate matrix generated by these functions from the right. Now, whenever you draw something it is ...


4

The best way to gain intuition about how a matrix behaves is by determining its effect on the standard basis vectors: 1 0 0 e1 = 0 e2 = 1 e3 = 0 0 0 1 Since any 3D vector can be written as a combination of a*e1 + b*e2 + c*e3, if we know how a matrix changes these three vectors, we know how a matrix changes any ...


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

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 ...


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