Hi guys, I have spring arm that is fixed to cube and I am trying to set relative rotation of this component. If I use function setRelativeRotation on the spring arm with P=90.000000 Y=90 R=90 then I get RelativeRotation P=90.000000 Y=-35.264389 R=-35.264404. Here is the blueprint:
LogBlueprintUserMessages: [BP_Player_C_17] P=90.000000 Y=-35.264389 R=-35.264404
Can somebody explain me why? I am new in UE4, thank you.
Which one do you want to hear first? The short version or the long version?
Short version: gimbal lock.
Long version: read this thread Rotation values are messed up. - Feedback for Unreal Engine team - Unreal Engine Forums
Summary: prepare for extra headache if your project heavily involve with object rotation. And yes, i have been there, and yes, i have lost a bunch of hair over this rotation and that rotation. And no thank you, i really don’t want to fix that rotation bug in my project.
Thank you for quick answer. So is it possible to learn Euler angles and work with that? Or it does not change the fact that is useless rotation system.
I won’t say it is useless rotation system. It rather work well, just that it is pretty complicate and take too much time to properly understand for a problem of it’s size. Anyway, you only need basic knowledge to learn how to use UE rotation and work rather well with it, but to master it and manage to apply delicate and complicate rotate function is another story.
Thank you, so can you advice me how to deal with the problem above? I have Axis degrees (as Viewport uses I hope) and wanna set relative rotation and after that I ask for its value then get Axis degrees again instead of Eulers angles.
Well, based on my expericence, instead of trying to set 3 axis at the same time, do it 1 axis at a time usually work, but better yet, instead of use SetRelativeRotation, use AddRelativeRotation and let the UE4 do the magic. You may consider create a Vector3 variable to hold your Axis degrees, and update it each time you rotate your component .Not a pretty solution and i doubt it is a clean one, but meh, it worked on my old project, unless some guy try to mess around with object rotation too much.
Maybe there is a simplier solution for my project. I have cube as a player inside 3D labyrint. You can move cube forward, backward left and right. If there is a wall inside your movement than the whole world will rotate to get that wall as a floor (actually just the camera rotates). So I have cube with spring arm and camera. So if I want to “rotate the world” then I rotate the spring arm. The spring arm can be in one of the 24 rotation states (6 cube sides * 4 direction on one cube side). I have table with rotations of the spring arm and corresponding rotation state (for example rotation P=0 Y=0 R=0 and P=180 Y=180 R=180 corresponding to rotation state 8 because they are same). At the start I ask spring arm for its rotation and get its rotation state then based on player input I calculate new rotation state (where i want to go) and if there is a wall I have to rotate from actutal rotation state to new one. Because for both rotation states can be more then one rotations I have to find pair where their difference (delta of this rotations) has just one axis equals to 90 degrees and other axis equal to zero to rotate nicely straight to the wall. Then I use SetRelativeRotation to set spring arm the rotation from the choosen pair and in for cycle AddRelativeRotation to get to the new rotation state. And there is the fail. It works in 9 from 10 cases but I need 100%.
Sorry for too long message and thank you If you read this but I hope there is a better solution than hack it.
After reading through your message, correct me if i am wrong but based on your project requirement, even though you need to rotate your spring arm a lot, but you have a limited set of rotation value, 24 if i am correct. So instead of going the smart way, i think we can go the not-so-smart way, and that is going through each and every rotation state, you rotate your spring arm in the editor, then get that spring arm’s relative rotation, store it into a list. Then base on user input and current state, you can calculate the next state, and base on that state, simply get the value from the list and SetRelativeRotation.
This still neither smart nor clean, it is rather filthy and take extra time and effort, but meh, at the very least it may give you the freedom of choice.
Thank you for quick answer. You are right that I need to rotate the spring arm a lot but they are 24 rotation states not rotation value - I took the spring arm in the Viewport and rotated it from [0,0,0],[0,0,90],[0,0,180] to [270, 270, 270] (to have spring arm in the center of one cube side). Than I saw, there are some rotations they equal = rotation state (24). So I made table with rotation states(24) with corresponding rotation values(64 = its 4x 4y 4y). So I do what you advice me but there is still problem such that when I calculate next state I have to set the rotation of spring arm to have effect in the game but it set different rotation from what I want to set. Or if i use AddRelativeRotation:
Start: P=90.000000 Y=0.000000 R=0.000000 End: P=180.000000 Y=0.000000 R=0.000000
Delta: P=90.000000 Y=0.000000 R=0.000000
Delta per step (20 step): P=4.500000 Y=0.000000 R=0.000000
For 0 to 20 step AddRelativeRotation(P=4.500000 Y=0.000000 R=0.000000) :
P=85.499977 Y=180.000000 R=-180.000000 P=90.000000 Y=-179.999985 R=179.999985 P=85.500107 Y=0.000020 R=-0.000020 P=90.000000 Y=-179.999969 R=179.999985 …