- Home /
Correcting hit.normal when hit.transform is rotated
I am placing a number of planks/boards onto each other.
I place them using a raycast, and get them to stick to the surface the raycast hits.
The ghost prefab (a simple Unity box) used has its localTransform adjusted to align with the surface that the cross-hairs are pointed at.
It works fine as long as the what I am placing onto is rotated 0 or 90 degrees so that my if's catch the normals.
Can anyone help me with better code for the rotations.
The following code is inside a raycast:
//sizeX,sizeY,sizeZ are the renderer dimensions for the object placed.
ghostMaterials[ selectedMaterial ].transform.position = hit.point;
ghostMaterials[ selectedMaterial ].transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
if(hit.normal == Vector3(1.0,0,0) ){
ghostMaterials[ selectedMaterial ].transform.localPosition.x += (sizeX / 2 ) ;
} else if( hit.normal == Vector3(-1.0,0,0) ) {
ghostMaterials[ selectedMaterial ].transform.localPosition.x -= (sizeX / 2 ) ;
} else if( hit.normal == Vector3(0,0,1.0) ) {
ghostMaterials[ selectedMaterial ].transform.localPosition.z += (sizeZ / 2 ) ;
} else if( hit.normal == Vector3(0,0,-1.0) ) {
ghostMaterials[ selectedMaterial ].transform.localPosition.z -= (sizeZ / 2 ) ;
} else if( hit.normal == Vector3(0,-1.0,0) ) {
ghostMaterials[ selectedMaterial ].transform.localPosition.y -= (sizeY / 2 ) ;
} else if( hit.normal == Vector3(0,1.0,0) ) {
ghostMaterials[ selectedMaterial ].transform.localPosition.y += (sizeY / 2 ) ;
}
Answer by Jamora · Aug 13, 2013 at 05:53 PM
You need to use local axes instead of the world axes.
Check if the normal is parallel to any of the local axes, then decide if it's front or back.
//up
if( hit.normal == hit.transform.up ) {
ghostMaterials[ selectedMaterial ].transform.localPosition.y += (sizeY / 2 ) ;
}
//down
if( hit.normal == -1*hit.transform.up ) {
ghostMaterials[ selectedMaterial ].transform.localPosition.y -= (sizeY / 2 ) ;
}
For a more general situation, (or if you just want to get rid of the ifs) you should rotate the object-to-be-placed so that its up-vector is equal to the hit.normal, then modify the position with transform.localPosition.y += (sizeY / 2 ) ;
.
I fail to understand. Been trying numerous combination of things, the correct one must be the only one left. It still only works if the hit.transform side has no rotation.
Can you/or anyone please explain how I get my ghost object to have same up as the hit.normal?
Can you/or anyone please explain how I get my ghost object to have same up as the hit.normal?
Pseudo code:
ghost.rotation = Quaternion.FromToRotation(ghost.up, hit.normal) * ghost.rotation;
I mean you do this, or something similar in your Raycast
transform.up = hit.normal;
transform.position = hit.point;
transform.position += transform.up*collider.bounds.extents.y;
Your answer
![](https://koobas.hobune.stream/wayback/20220613112112im_/https://answers.unity.com/themes/thub/images/avi.jpg)