Sorry if i'm stupid or something, but i having a deep dread from a work on a "full 3d" space movement.
I'm trying to make a "space ship" KinematicBody controller which using basis vectors as a rotation point and have ability to strafe/move left,right,up,down based on it's facing direction.
The issue is i'm having that i want to use a Vector3 as a storage of all input variables, an input strength in particular, but i can't find a convenient way to orient or use this vector's variables to apply it to velocity.
I got a sort of cheap solution which i don't like with applying a rotation to an input vector so it will "corresponds" to one of the basis, but it's starting to brake at some angels.
Could please somebody suggest what i can change in my logic or maybe there is a way to use quaternion/matrix related methods/formulas?
I'm not sure I fully understand what you want to do, but I can give you something to work with.
I'll assume that you already have the input as a
Vector3. If not, you want to seeInput.get_action_strength,Input.get_axisandInput.get_vector.I'm also assuming that the braking situations you encountered are a case of gimbal lock. But since you are asking about applying velocity not rotation, I'll not go into that topic.
Since you are using a
KinematicBody, I suppose you would be usingmove_and_slideor similar method, which work in global space. But you want the input to have to be based on the current orientation. Thus, you would consider yourVector3which represents the input to be in local space. And the issue is how to go from that local space to the global space thatmove_and_slideet.al. need.Transform
You might be familiar with
to_localandto_global. Which would interpret theVector3as a position:And the opposite operation would be:
The problem with these is that since these consider the
Vector3to be positions, they will translate the vector depending where theKinematicBodyis. We can undo that translation:And the opposite operation would be:
By the way this is another way to write the same code:
And the opposite operation would be:
Which I'm mentioning because I want you to see the similarity with the following approach.
Basis
I would rather not consider the
Vector3to be positions. Just free vectors. So, we would transform it with only theBasis, like this:And the opposite operation would be:
This approach will not have the translation problem.
You can think of the
Basisas a 3 by 3 matrix, and theTransformis that same matrix augmented with a translation vector (origin).Quat
However, if you only want rotation, let us se quaternions instead:
And the opposite operation would be:
Well, actually, let us invert just the quaternion:
These will only rotate the vector (no scaling, or any other transformation, just rotation) according to the current orientation of the
KinematicBody.Rotating a Transform
If you are trying to rotate a Transform, either…
Do this (quaternion):
Or this (quaternion):
Or this (axis-angle):
Or this (axis-angle):
Or this (Euler angles):
Or this (Euler angles):
Avoid this:
The reason is that this rotation is always before translation (i.e. this rotates around the global origin instead of the current position), and you will end up with an undesirable result.
And yes, you could use
rotate_x,rotate_yandrotate_z, or setrotationof aSpatial. But sometimes you need to work with aTransformdirectly.See also: