- Home /
Why does the object alignment only work when the object isn't rotated?
I have a script in which when the player is touching a certain box collider the player's x axis position and y axis rotation is aligned with the box; similar to if an imaginary line (white dashed line above) were drawn down the centre of the box from end to end, along which the player would travel and be aligned to (blue player above). This worked perfectly until I rotated the box (orange player above) and noticed that this threw the player's alignment. What I need is to have the player align with the box along the player's x axis and face the opposite end no matter which way the box is rotated along the box's y axis (as in the yellow player below).
I've considered adding points at either ends of the boxes and therefore if the player is facing one end using the end point for the alignment, rather than always using the centre of the box for the alignment. I'm not too sure how to implement this though and whether there's a better way altogether. How could I do this?
It isn't the rotation part that is causing the problem, it's the position part of the code.
Answer by Hamesh81 · Nov 03, 2013 at 05:01 AM
Ok so I finally worked out a simple way to solve this issue. First one needs to parent the player to the object that the player is going to be getting aligned with (box above), and then all that needs to be done is the position along the relevant axis/axes gets zeroed out. In my case the z axis was zeroed since this was the sideways position. Make sure that transform.localposition is used, otherwise the player will get sent to the zero position of the world axis. Once the player is parented it is much easier to find the "box's" center and align the player to it. Rather than trying to caluculate it each time manually it is simply a matter of zeroing out the position along the relevant axis/axes. The rotation code I kept exactly the same (see my previous question for the script), since as I suspected it was the position not the rotation code that was causing the problems. Anyway, hope this makes sense and is helpful to others with the same issue.
Answer by robertbu · Nov 01, 2013 at 06:04 AM
Your code on lines 55 - 65 is directly accessing the individual components of a Quaternion. Unless you have a deep understand of the math behind Quaternions, this is not something you want to do. As an alternate you can use Transform.eulerAngles, but in general you want to treat eulerAngles as 'write-only', and you never want to set one of the axes separately.
There are multiple ways to solve your problem. Here are three ways to calculate that rotation. Each makes a bit different assumptions:
q = Quaternion.Euler(0.0f, -90.0f, 0.0f) * box.rotation;
Another solution:
q = Quaternion.LookRotation(box.right, box.up);
And one more that does less messing with the up of the character:
q = Quaternion.FromToRotation(hero.forward, box.right);
q = q * hero.rotation;
Once you've calculated q, you can do the rotation this way:
hero.rotation = Quaternion.RotateTowards(hero.rotation, q, balanceRotateSpeed * Time.deltaTime);
Your code implies that the hero could get up on the box at either end. If so, you can make some a test. Based on the tests, you can negate a vector to get the rotation right:
if (Vector3.Angle(hero.position-box.position, box.right) < 90) {
q = Quaternion.Euler(0.0f, -90.0f, 0.0f) * box.rotation;
}
else {
q = q = Quaternion.Euler(0.0f, 90.0f, 0.0f) * box.rotation;
}
Likewise for the second and third solution, 'box.right' becomes -box.right when the angle is greater than 90.0.
Yes, lines 56-65 are a bit of a hack because I didn't know how else to make sure the x and z axis rotation stays at zero during the rotation.
Also yes you are right in assu$$anonymous$$g that the player can enter the box from either end but they can also enter it from the middle as well, so basically from any point. I will try to implement your rotation code into my script and see how that changes things, but I suspect that it isn't an issue with the rotation. If you have a look at the middle box (orange player) you'll notice that on the player's x axis (box's z axis) the player isn't in the middle of the box but more towards the bottom left corner. The player IS actually facing the centre gizmo of the box so they're rotated correctly, but their sideways position is off which is why I assume they do not move parallel to the box if that makes sense.