# How to align an instance of an object to a collision normal?

Attention Topic was automatically imported from the old Question2Answer platform.

When shooting a raycast from the center of the screen and creating and object in the hit position, how to correctly align your object or particle with the hit normal? Here’s my code:

``````var from = camera.global_transform.origin
var to = from + -camera.global_transform.basis.z * ray_length
var space_state = get_world().direct_space_state
var result = space_state.intersect_ray(from, to, [self])
if not result.empty():
var impact_fx = scn_impact_fx.instance()
impact_fx.translation = result.position
impact_fx.rotation = result.normal # HERE
impact_fx.emitting = true
``````

I’am just trying to rotate it based on a normal, I know I’m doing it wrong. Please help!

I’ve also tried this:

``````imapct_fx.global_transform.basis = Basis(result.normal)
``````

Here’s a screenshot:

I am using Godot 3.1. Thank you!

try:
`impact_fx.global_transform=impact_fx.global_transform.looking_at(camera.global_transform.basis.z+result.normal, camera.global_transform.basis.z)`

Explanation:
looking_at returns a copy of the transform where -z is pointing at the target coordinate. Which i calculated as its own position + the normal.
You also need an up vector. I chose to select the opposite ray direction. (

wombatstampede | 2019-03-18 21:00

Doesn’t work, sorry

wowzzers | 2019-03-19 06:54

You set the rotation (radian angles) of the Scene with the normal vector (coordinates). Obviously that didn’t work.

try:
`impact_fx.look_at(impact_fx.global_transform.origin+normal,camera.global_transform.basis.z)`
I did a “typo”. (While the explanation described it hopefully correctly)

wombatstampede | 2019-03-19 10:09

``````impact_fx.look_at(impact_fx.global_transform.origin + result.normal, camera.global_transform.basis.z)
``````

Tried this, same result

wowzzers | 2019-03-19 12:45

I tried it out:

``````global_transform.origin=result.position
look_at(result.position+result.normal,\$"../Camera".global_transform.basis.z)
``````

As test, I assigned this to a spatial which has its “forward” in direction -z.
The “upside” of the spatial shows afterwards to the camera and -z toward the normal of the hit collision face.
You can also pass Vector(0,1,0) instead of camera.global_transform.basis.z if you want the “upside” of the scene to look upward (+y).

If this doesn’t work then I’d say, you check if your impact_fx doesn’t emit into -z direction.

wombatstampede | 2019-03-19 15:08

Unfortunately it doesn’t align. Here are the results: Video

I’m using this code:

``````result.collider.add_child(wound_fx)
wound_fx.global_transform.origin = result.position
wound_fx.look_at(result.position + result.normal, camera.global_transform.basis.z)
``````

Impact effect (wound_fx) scene in it’s original object is facing upwards.

wowzzers | 2019-03-19 16:25

I guess that you want to align your y-axis with the result normal of the raycast. look_at only aligns the -z-axis but i looked at the code and (hopefully) adapted the function to align the y-axis instead:

``````global_transform.origin=result.position
global_transform=look_at_with_y(global_transform,result.normal,\$\"../Camera\".global_transform.basis.y)

func look_at_with_y(trans,new_y,v_up):
#Y vector
trans.basis.y=new_y.normalized()
trans.basis.z=v_up*-1
trans.basis.x = trans.basis.z.cross(trans.basis.y).normalized();
#Recompute z = y cross X
trans.basis.z = trans.basis.y.cross(trans.basis.x).normalized();
trans.basis = trans.basis.orthonormalized() # make sure it is valid
return trans
``````

(Sorry for the late answer, I thought that I posted it yesterday but somehow it seems that I never clicked the send button.)

Thank you for the answer! It seems to work but it has a weird glitch effect, inverted normals? Here’s the video.

wowzzers | 2019-03-21 12:29

``````func look_at_with_y(trans,new_y,v_up):
#Y vector
trans.basis.y=new_y.normalized()
trans.basis.z=v_up*-1
trans.basis.x = trans.basis.z.cross(trans.basis.y).normalized();
#Recompute z = y cross X
trans.basis.z = trans.basis.y.cross(trans.basis.x).normalized();
trans.basis.x = trans.basis.x * -1   # <======= ADDED THIS LINE
trans.basis = trans.basis.orthonormalized() # make sure it is valid
return trans
``````

The basis.x was pointing in the wrong direction. Interesting what a messed up Basis can do.

Honestly, I don’t know why this is so (didn’t spend the time to look further into it), but it seems to work fine that way.
There surely is a nicer solution but perhaps you can live with a “working” solution.

wombatstampede | 2019-03-21 16:12

It did work! Thank you, wombatstampede!!!

wowzzers | 2019-03-21 20:19