Cursor location in World Space, LookAt rotation and Gimble lock.

Hey guys,

I am running into the Gimbal lock issue.

A bit of background info, I am currently getting the cursor location in the world space (Find LookAt rotation End) and LookAt rotation Begin is the Actor Location.

This value then goes into a Rinterp which then goes into a SetActorRotation.

For the most part it works until I ran into the typical Gimbal Lock issue where the ship start spinning out of control when reaching 90 and - 90 Pitch.

I tried a bunch of solutions and none work. Any help or advice would be appreciated.

As it turns out, it seems using SetActorRotation is the offender. If I use AddActorRotation, the Gimble Lock is a non problem. However adding the Mouse world location with lookat rotation totally spazes everything out so either way it’s still broken.

Any suggestions?

The look at rotation you are finding is in world space, you would have to transform it to local units to apply it locally.

or, maybe, just find the look at rotation between the mouse and the Local position of the object.
technically that should give you a value that is already in the correct range.

Another thing. Maybe it’s not spazzing out, maybe the rotation of the mouse click has a different orientation then the local rotation of the object…

If you do need to solve the gimbal lock problem, here’s the solution I use in my projects. Since the problem keeps coming up and it may help others…
The macro below is to be used to find the rotator to add to your current rotator to make it from its current forward vector to a new forward vector bypassing the gimbal lock.

This is with SetActorRotation

This is AddActorRotation (spazzing)

This is AddActorRotation but with LookAt values transformed from World to Local

So, it definitly did something, but really just put me back to the initial scenario with Gimble Lock.

because you are dealing with a flying vehicle, I would suggest just using the quaternion C++ library. It’s much easier to implement too, since it’s pre-packed and allows you to set the local rotation via a quaternion calculation instead.

You don’t necessarily need to purchase it on the marketplace either, there’s a free one floating around on this forum that I have shared before…

ha, here’s a link
https://forums.unrealengine.com/development-discussion/blueprint-visual-scripting/1641801-is-this-a-local-rotation-bug?p=1644046#post1644046

Hey, thanks for actually taking the time to help me out, I really do appreciate it.

Funnily enough, I found that post of yours while trying to use Quaternion (It was the first thing I thought off to bypass the typical Euler Gimble Lock issue). I succesfully tried with basic input to set the rotation (and of course there was no Gimble lock problems) but I think it all goes to ■■■■ when I use the LookAt function to set the rotation.

LookAt does work, but with limitations but I think one of my logic is flawed or how I applied my rotations must not make sense. Using LookAt with Quats is even worse in my case.

The BP_Cursor is just a blueprint that casts to what’s under the cursor, this works as demonstrated previously. Following the the previous advice, I translate from world space to local the LookAt return Value and turn it into a Quat, which is then adds to the Local Rotation (Quat). I wonder if it had a set rotation ( quat ) would it have the result I want.

Anyways, yeah, it still doesn’t work this way, I think it’s probably lost when transforming to local then to quat? even without transforming its the same result (ship spazes out).
I am not sure I mentioned, but what I try to achieve is essentially the ship follows the cursor.

Any insight to help me get better logic would be appreciated.

No further advice unless I actually go and do it I’m afraid.
I think the issue is how you are getting the cursor position.

Why not simplify it and just add +1 if the mouse is the the left, -1 if to the right. etc. ?
You could even end up driving this by the distance of the cursor on the screen - so the further it is, the faster the turn rate
to do that
cursor location x / screen size x = - the screen position in 0 to 1 range.
From the 0 to 1 range just set up a set of >= .25, .5, .75 - and instead of just a +1 you +1, +5, +15…

if done correctly it should work fine on both axis - and the object axis you want to affect are probably Z for left to right, and X for up and down.

This wouldn’t really be following the cursor though I think. A simple way of actually going around this and not using the cursor or mouse and simply having WS for Up/Down And AD for Left/Right.

I was trying specifically to get that freelancer feeling but I think your idea is actually a pretty clever work around. I got started on it and I am effectively reading the cursor position from a 0 to 1 range, will come back with update when I can.

Thanks for not giving me the solution, it’s actually helpful understanding logic and getting better.

As an update, this is currently what I have:


and I directly feed the X and Y mouse axis value to both the X and Y Speed. This works, however, it is not what I wanted but I’ll take small victories. I think I will do the cursor being farther away thing as well tho.

Any suggestions of a better implementation?

Sure. I assume the Mouse Movement event is called on click?

If you create Axis events for the mouse - it pretty much works OnTick without being an OnTick function.

Mouse constantly moves.
As such, you can get the X or Y direction from the respective Axis value.

Which brings to yet another way to implement it - simply add the axis value scaled (multiply) but a custom speed variable into the rotation.

Personally, I branch at the start and if axis is == 0 I stop the execution. But you may actually want to re-apply whatever the latest value was instead, don’t know.
It would make you pan back to the center when you stop moving the mouse.

Maybe it’s closer to what you want that way.

Yeah it was mostly to test, it has it’s own independant event now.

As for the axis branch, I actually use that for other inputs to avoid needless ticks.