Aligning actor to ImpactNormal

Hi all,

I have a thread open on the AnswerHub here also: https://answers.unrealengine.com/questions/217700/aligning-actor-to-impactnormal.html - I haven’t been getting any responses so far so I thought I’d see if the great people of the forums could help me out.

I’m having an issue aligning my actor correctly to another actor. I’ve had this issue for a while now but have been putting it off. So here are some screenshots of my alignment issue:

At certain angles the actor doesn’t align as it should:

This is good:

And this is bad:

My code:




SpawnedBlueCubeGhost->SetActorTransform(HitResult.GetActor()->GetTransform());
                                         
 FVector TempLocation = HitResultLocation;
 TempLocation += HitResult.ImpactNormal.Rotation().Vector() * 100.0;
 SpawnedBlueCubeGhost->SetActorLocation(TempLocation);
 
 FRotator TempRotation = HitResult.ImpactNormal.Rotation();
 TempRotation.Pitch = TempRotation.Pitch + 90.f;
 SpawnedBlueCubeGhost->SetActorRotation(TempRotation);


I have tried getting the rotation of the HitResult and manipulating that too but no joy, maybe there’s more I need to add?

Any help would be great. What am I doing wrong? Am I missing something?

Thanks, Jon

Dear ZeJudge,

Hi again!

I think the fundamental problem is that when a rotator is converted to a vector, or vice versa, you lose roll information.



FRotator TempRotation = HitResult.ImpactNormal.Rotation();


For what you are trying to do, you really need all 3 axis, pitch yaw and roll, but with impact normals you are only ever getting pitch and yaw axis.

That’s why it sometimes works and sometimes doesnt!

If the ImpactNormal can be expressed by only pitch and yaw values, your code works, but as soon as roll gets involved it stops working because roll is getting zeroed out by converting Vector to Rotator.


**Solution**

So I'd recommend you  get the rotation of the hit actor, and match that instead :)



```


AActor* HitActor = HitResult.GetActor();
if(HitActor)
{
   SpawnedBlueCubeGhost->SetActorRotation(HitActor->GetActorRotation());
}


```



The point is, you can't rely on hit normal converted to a rotator for accurate rotations due to the lack of Roll, so you must do the rotation analysis of the hit actor yourself, which may sometimes require adjustments, but you can write an if / else series to handle any special cases within your game.

Enjoy!

♥

Rama

Technically, the code isn’t doing anything wrong since it’s still aligning the the impact normal. The thing is, the impact normal is just a vector pointing in a given direction. It will give you the direction something is facing but it won’t give you the rotation around that direction. To do that you’ll need to generate some more vectors to work out the orthogonality of the normal, and create a rotation from two vectors.

My suggestion would be to look at using Cross Products to generate that second vector. I think cross product of the normal plus a world-space vector might do it but I can’t currently picture it in my mind… would have to give it a go. If you manage to get the right vectors, you can create a rotator using FRotationMatrix::MakeFromXY (or similar), which creates a rotation based on two vectors. That’s the current solution that comes to mind.

Thing is I’m not sure if that’ll work in all cases. If you know the actor you’ll always be hovering over is a cube like in the images above, you could simple get the actor’s rotation, apply it to you object and add an offset based on the pivot locations and the impact point.

Tl;dr: The surface normal isn’t enough data to work from.

EDIT: Ninja’d by Rama :wink:

Hee hee!

I really liked what you had to say though TheJamsh! Cross product is a great idea!

@ZeJudge

I just realized the code I sent you wont really work because the actor you are aligning to is only rotating on pitch probably.

After you try TheJamsh’s wonderful suggestion of cross product I have a completely different algorithm for you to try:


**New Algorithm To Try**

1. duplicate the target mesh
2. resize the mesh to be same dimensions as your rectangle that you are wanting to attach, by resizing along the axis that aligns with the surface that was hit.
3. Move the duplicated resized mesh so that it is flush with its surface that was hit.

The only hard part of this algorithm is picking which axis to resize along

 This is easier though because now you can stay in the rotation space of the target mesh and use its rotation exactly, cause you are duplicating the mesh

Then you resize along appropriate axis.

This assumes that your target actors will always be cubes so you can just resize them into your surface-aligned rectangle.

However knowing the nature and name of your game I think its a safe assumption that your actors will be qubes I mean cubes :)

Rama

Ohh just thinking aloud, I wonder if you could use the normal as an Axis, and get the objects rotation around that axis… that might work too. I’d follow the above suggestions first though :slight_smile:

I appreciate you guys responding to this.
I don’t think I understand how to work this out to be honest with you. I’m not the greatest with maths.

The blue cube will always be hovering over the white cubes but the white cubes could have any rotation so I’m not sure if that affects how to resolve this? Also each white cube is a component of a master actor. I’m unsure if that makes a difference though.

Another little nudge in the right direction would help me big time. I’m not sure duplicating and resizing the target mesh will be a great solution and may end up being more of a pain.

Since everything in your game is probably a cube, if I were doing it, I would duplicate the mesh and then just determine which axis to resize along, but this is making the big assumption that the new actor you want to attach is always a rectangle/cube shape :slight_smile:

Maybe the Jamsh or someone else has some additional ideas, the above is what I would try first if I were doing it

:slight_smile:

Rama

Ah I see, well the blue mesh has various attribute tied to it which cause it to resize when used, the same goes for other coloured meshes in the project. So do you mean resize the blue mesh or the white cube?

Jon

Hey all,

So i’m still trying to correct this issue. I’m not sure what to do about this but it seems the rotation is now not updating when doing a continual trace from one side of the cube to the other but when I take my finger off the mouse and hit the other face/normal then it’s fine and acts normally. It’s just not updating the rotation in the Tick now.

Any ideas how I could solve this? I’ve tried a whole bunch of things, worked on this for a long time.

a442563495054b345dd844b5e0772a8f929cb499.jpeg
f3bf952eaefc6838029276473ea98a3509283799.jpeg

Cheers,
Jon