(I’m getting the foward vector from the player CharacterBody3D, which is a child node of the rigidBody (I did that because I locked the rotation of the RB)).
Like this :
I checked, of course, if the rotation of the player was correct. (and it is)
Main Problem
It’s not going in the right direction, and it sometimes get “locked”, like its not even moving anymore.
Have you considered rotating the planet under the player? Besides that the way I’d do it is have a node constantly teleporting to the player (not childed), get the angle from the planet to that node, then rotate the player to that angle (maybe lerp the camera for smoothness). But yeah the information provided is too vague to help fix whatever you’re trying to do
Here’s your answer, apologize for the very imprecise help request :
I set the rotation of the player to be aligned on a downward vector, pointing to the planet/sphere, but (see 2).
The right Direction is the forward vector of the player
LookAt(planet.Position); RotateObjectLocal(Vector3.Right, Mathf.DegToRad(90.0f)); RotateObjectLocal(Vector3.Up, Mathf.DegToRad(90.0f));
I’m rotating it at the end since the rotation of LookAt is making it forward, not Upward/downward.
I locked every axis of my rigibody to prevent it from spinning and doing some unexpected behavior (such as adding speed, since it spin…).
I did not understand your method, like you want to set it the rotation of the player to the planet rotation ? And rotating the planet under the player isn’t a very good option in my case, since a plan to make it multiplayer (Of course there would be some methods with that system but it would just be too hard, I think).
Maybe this helps, a character controller that uses spherical gravity and rotates its body along the normal. It’s important that you take your current up vector in account, otherwise you get the problems you described.
extends CharacterBody3D
var planet_pos := Vector3.ZERO
const SPEED = 5.0
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += up_direction * -10.0 * delta
else:
velocity = Vector3.ZERO
var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
var input_rot := Input.get_axis("ui_left", "ui_right")
if input_rot and Input.is_key_pressed(KEY_SHIFT):
global_rotate(up_direction, PI * -0.5 * delta * input_rot)
input_dir = Vector2.ZERO # clear move dir so we don't rotate AND move
var direction := (global_basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
velocity += direction * SPEED
# set the new up vector based on the next position on the planet
var new_up := ((global_position + velocity * delta) - planet_pos).normalized()
var angle := up_direction.angle_to(new_up)
if angle > 0.0:
var axis := up_direction.cross(new_up).normalized()
global_basis = global_basis.rotated(axis, angle)
up_direction = new_up
move_and_slide()
# clear movement velocity after move_and_slide
velocity -= direction * SPEED
I mean set the player’s rotation relative to the planet to the direction of the teleporting-player-following node relative to the planet, like:
var player:CharacterBody3D
var player_pos_node:Node3D
var planet
func _physics_process(delta)->void:
if player_pos_node.position == player.position and player.rotation == (planet.rotation - player_pos_node.rotation):
return
if player_pos_node.position != player.position:
player_pos_node.position = player.position
if player.rotation != (planet.rotation - player_pos_node.rotation):
player.rotation = (planet.rotation - player_pos_node.rotation)
# subtract 90 from an axis or two to get the player facing forward
You method is weird. I guess it could work, but locking axes won’t help. Even if it did somehow work it would just gloss over errors in the rotation algorithm.
it sometimes get “locked”, like its not even moving anymore.
That’s probably a situation in which the only directions in which the player is capable of moving are along axes you’ve locked.
Also yeah set gravity to go towards the center of the planet if you haven’t already
Thanks for the script, I will convert it in C# and see if it work ! But with that I do clearly understand that I was rotating my player forwardly and not upwardly (weirdly because I would be able to see the difference between upward and forward, like i don’t know just see the code)
LookAt has a second parameter, which defines the up vector. With your code you lose information because LookAt() doesn’t know what the last rotation was like