- Home /
Aligning a transform according to two different positions and directions
I, unfortunately, am quite bad with vector math and have been dealing with this for some time now. I will attempt to explain in hopes of getting an explanation:
I have 5 different rooms in my AR game that the player can navigate into. Each room has an empty gameobject as a child to it, that represents the player's spawn point when they arrive into the room. The 5 different rooms are all game objects I enable and disable depending on the room the player moves into.
Every time the player (the camera in this case) moves to a room, I want the player to appear directly over the spawn point specified in the room. This is achieved by the following code:
Vector3 spawnPoint = thisRoom.RoomSpawnPoint;
Vector3 point = new Vector3(_camera.transform.position.x, _roomWorldPosition.y, _camera.transform.position.z);
_currentEnvironment.transform.Translate(point - spawnPoint);
where _roomWorldPosition.y is set by a detected plane's y value.
My next task is to make sure the room is rotated properly so that the room's spawn point forward vector is aligned with the camera's forward vector. However, the below code sample does not work as expected:
Vector3 cameraFlatForward = new Vector3(_camera.transform.forward.x, 0f, _camera.transform.forward.z);
_currentEnvironment.transform.rotation =
Quaternion.Euler(new Vector3(0f, Vector3.Angle(cameraFlatForward, spawnPoint)));
The rooms are rotated in random angles and seem to spawn further and further away. For clarification, first I apply the rotation and then the translation. Any help appreciated.
EDIT: Using the Translate function I am able to always transport the room to the place I want it to, so it always appears beneath the camera and gives the feeling of the player spawning on the right point.
_currentEnvironment.transform.Translate(point - thisRoom.RoomSpawnPoint);
Using Quaternion.FromToRotation (without translating the room) the room always looks towards the direction the camera is looking, so the spawn point's forward vector is aligned with the camera's flat forward vector.
_currentEnvironment.transform.rotation = Quaternion.FromToRotation(thisRoom.RoomSpawnPointForward.normalized, cameraFlatForward.normalized);
However, applying these at the same time never works the way I want it. The room keeps appearing in wrong places and wrong rotations. I also make sure the position and rotation of my room gameobjects are reset every time the player moves from room to room.
Answer by Namey5 · Jun 23, 2019 at 02:06 PM
If you want to align a rotation with a vector, you can use the LookRotation function. To align a transform with another, you can take the angle between them and use it as an offset to the rotation. Unity's Vector3.Angle function is unsigned, meaning it simply finds the smallest angle between the two vectors and throws away any details about direction. This means that the angle it returns may not be for the direction you are rotating, hence the need to apply it 1-3 times.
Vector3 cameraFlatForward = new Vector3 (_camera.transform.forward.x, 0f, _camera.transform.forward.z);
Vector3 angle = Quaternion.LookRotation (cameraFlatForward).eulerAngles;
Vector3 off = thisRoom.RoomSpawnPoint.rotation.eulerAngles - _currentEnvironment.transform.rotation.eulerAngles;
//If the rotation still appears incorrect, switch the '+ off' to '- off'
_currentEnvironment.transform.rotation = Quaternion.Euler (angle + off);
Hey, thanks for the answer. Turns out this doesn't work as I wanted it to... The room still spins to wrong directions.
In what sense are they pointing in wrong directions? The above code should align the transform with the camera, but if the mesh is aligned differently to the transform, then it won't point in the right direction and you'll need to make some adjustments to either the mesh, object or alignment vector.
It's hard to say in what sense they are pointing wrongly. The rotation appears random. The mesh is aligned differently with the transform. After all it's an entire environment with lots of different props around. That is why I use a spawn point gameobject as the required position and orientation the camera should have (if the camera could move at all). What baffles me is that the Quaternion.RotateAround function should do what I want, as I can make the environment rotate around the spawn point after I translate the room to the camera. However, I again get random rotations.