Rotation.y Acting Similarly to global_rotation.y

Godot Version : 4.4

Hello again!

I am having trouble trying to rotate the Y axis of a Rigidbody3D locally. The code I’ve written works, but, only when there is no X or Z rotation. Otherwise, with any XZ rotation, it rotates the given Y globally and additionally for some reason cannot face backwards globally anymore:

var last_direction : Vector2 = Vector2.UP

func _physics_process(delta: float) -> void:
		var input_dir := Input.get_vector("left_key", "right_key", "forward_key", "backwards_key")

		if direction:
			last_direction = (Vector2(input_dir.x,-input_dir.y)).rotated(cam_arm.rotation.y).normalized()

		var r_x : float = 2.0 
		var r_y : float = lerp_angle(rotation.y , -atan2(last_direction.x, last_direction.y) , delta * 5)
		var r_z : float = 2.0 
		rotation = Vector3(r_x, r_y, r_z)

(I just pasted the relevant code here, feel free to ask if more info is needed)

I wanted the local Y rotation to smoothly face the last_direction vector. I’ve made the test X and Z separate global_rotations while the Y stayed a separate rotation, though it still behaved similarly. Additionally, there are no other rotations being applied to the RigidBody3D then what is shown here, and all angular axis are locked in the RigidBody3D’s PhysicsBody3D’s Axis Lock.

Don’t use euler angles when orienting things in 3d. Work directly with the basis.

1 Like
		var r_y : Vector3 = -gravity_direct.normalized()
		var r_x : Vector3 = r_y.cross(global_transform.basis.z)
		var r_z : Vector3 = r_x.cross((r_y * last_direction).normalized()) #basis I want to face towards direction vector cross to basis.y
		global_transform.basis = Basis(r_x,r_y,r_z)
		global_transform.basis = global_transform.basis.orthonormalized() #not quite sure if this is needed here
		scale = Vector3(1,1,1)

I looked into Basis’ a bit more, and took some time to try to make something just like look_at() that worked for my issue, that I could also add smoothing to later. I’ve gotten it to point -Y towards the gravity_direct just fine without bugs, but, once I started trying to add last_direction which I changed to this for the time:

	var last_dir = Vector2(input_dir.x, input_dir.y).rotated(cam_arm.rotation.y)
	last_direction = Vector3(last_dir.x, 0, last_dir.y).normalized() #I'll probably remove this variable

It doesn’t rotate as I hoped, flipping on it’s Y every frame sometimes and partly ignoring last_direction along with other issues. Though I’m still new to Transforms and Basis’. How would I apply last_direction to global_basis.z/r_z? I thought multiplying it by basis.y was correct, but, I’m unsure if thats what’s wrong or how it’s all being added in general

Rotation cannot “face” anything. And direction cannot be “faced”, only aligned with. Did you perhaps meant local y axis to be aligned with last_direction?

You need to describe the problem as precisely as possible.

As a caveat, rigid bodies motion is not really meant to be controlled directly via script code, but rather by engine’s physics simulation.

(I’m not very good at explaining things at times, so I made this to try to show what I’m attempting to do if I still fail to explain)

Sorry, for the confusion, that makes sense however. From what I do understand now, I think I have to first align global_basis.y to -gravity_direct (normalized). Then try to align global_basis.z with last_direct made perpendicular to global_basis.y/-gravity_direct (which is what I’m struggling to figure out how to do), then just make X = Y.cross(Z)
last_direct being the last non zero input vector rotated by the current local Y of the camera in a Vector2 then made into a Vector3 as seen in the past reply (the camera itself also subtracts the local y rotation of the player)
If that is incorrect, I pretty much just want to try to recreate what is shown in the picture above

(Also, the only reason I’m using a rigidbody here, is because I’m pretty much trying to make my own CharacterBody3D that can still function with an very inconsistent up. I did get the motion to work as I wanted through script, but for the moment it’s partly broken by having to re-program rotation as the last one I made drift issues)

r_y = -gravity_direct
r_z = last_direction.slide(r_y)
r_x = r_y.cross(r_z) 
global_basis = Basis(r_x, r_y, r_z).orthonormalized()
3 Likes

This is what I exactly needed, but, in testing, I think I’ll just go back to the workaround I originally had made after you advised I use Basis’. As the drift issue persists and with this way currently I need to flip last_direction when basis.y’s Y is less then 0 or else it has issues in my case. (in short, the “drift” I am attempting to fix is if the player was to try to go around a sphere by just going forward, it’ll curve as it goes around instead of going perfectly around the sphere. Though, I got an loose idea on how to fix that now that admittedly I’ll feel a bit dumb for overlooking if it works, but, at least I know a bit more though)

Thank you for the help, I think I understand rotations and basis’ a bit better now. I was not aware of .slide either and even though I might not be able to use it here, I do have something after this that can use it, so thank you again for that

Perhaps describe exactly what type of control you’re after. The problems you’re experiencing may be due to still using euler angles in some parts of your code. Using bases exclusively is in general the best approach for manipulating 3d orientation.

slide() is just a projection of a vector onto a plane defined by its normal vector.

So you want a standard player controller but on a sphere? There’s no need to use rigid bodies for that. You can do it with a character body. And yeah, don’t use euler angles (aka rotation). They’ll just cause problems.

I think I even made a demo a few years back. I’ll try to dig it up if this is what you’re actually after. Here’s a gif I have of it in detached camera mode, but it had a follow mode as well.

sphere_character

2 Likes

If you want useful advice, you’ll need to fully describe what are you trying to make. Revealing it piece by piece, adding a bit of new information in each post is counterproductive. We’re already quite far from your original question and it’s still not clear what exactly are you after and what are the main obstacles to get there.

I do, I really do, but, the only issue is there is only so much I can disclose for reasons I annoyingly also can not disclose. Its frustrating, I understand, I rather not frustrate someone else too and I’m sorry if I have. I want to make another topic explaining exactly what I am trying to do from the very start, to avoid all of that, but, it’s not an option for me as much as I wish it were

I’m really sorry I’ve been so vague, and didn’t mention the above before. The question I originally asked is solved though, even if in my case it didn’t help, that would be the right answer otherwise and I should’ve ended it there. But, the help and advise you gave while I was trailing off has given me a clearer direction on how to tackle a few things I was really stuck on, and knowing now I might not have to use rigidbodies anymore majorly helps, so thank you for that. From here, I can eventually solve this on my own, I have before, even if it takes me awhile it’s just what I have to do. I don’t like that I have to be stubborn and counterproductive here, but, I have to say its solved and done as I can’t say anything more and shouldn’t too because of how off topic it’s become like you said. I’ll make a new topic if its something I can ask about and I get really stuck again. Likely a bit more organized and without the trailing off like this one

I sincerely appreciate the help you gave for what I could explain, thank you for that, and again, I’m sorry for being vague and taking so long to explain. This will be my last reply here

(I looked back at this topic, on my end, I already checked it off as solved at the time quite awhile ago. but, returning to it now it wasn’t. I do not know what happened, if it was an error on this site, or if it was from not sleeping at the time and just hallucinating that I did. Either way it’s still a mistake on my part, and I’m sorry for that. It should be marked as solved now, it is on my end, but, I don’t know if it is on the site here. If it is not, let me know. I set your third reply as the answer when I first saw it, or at least I (mis)remembered that I did. Again, sorry I failed to realize this topic wasn’t actually marked as solved and continuing to take your time)