I have two 2D nodes in my project. A world_pivot node and a world_container node which is a only-child of the world_pivot node.
Ive done so the world_pivot node position is always the player position, and the world_container node global position is always 0,0.
According to my math this should make it possible for me to then rotate the world pivot, and when doing so, the world should rotate around the player. Yet this doesnt happen. It just rotates around 0,0 still.
Player Script:
@export var rotation_speed: float = PI / 2.0
@export var world_pivot: Node2D
@export var world_container: Node2D
var mouse_rotation_sensitivity: float = 0.001
var _pending_mouse_x_delta: float = 0.0
func _physics_process(delta):
# Apply world rotation based on the mouse delta
var rotation_amount = -_pending_mouse_x_delta * mouse_rotation_sensitivity
_pending_mouse_x_delta = 0.0 # Reset for the next physics frame
world_pivot.global_position = global_position
world_container.global_position = Vector2.ZERO
if rotation_amount != 0.0:
world_pivot.global_rotation += rotation_amount
Can you show a screenshot of your scene tree? I’m interested in where the Player is located in relation to your other nodes.
And if you could - a short video how it works currently to better understand the issue.
What’s the reason you’re rotating the world instead of the player though? You probably have a good reason for it, but I’m just curious.
Im sorry but i didnt see that i was recording in 720p. I still think you can see the properties tho.
As you can see, in-editor it seems to work fine if i offset the world node from the world_pivot node, and then rotate the world_pivot node. this doesnt happen in code.
My reasoning is that i want gravity to always go down, so i thought it’d make more sense to rotate the world. But maybe also collision wise, it would be better to rotate the player and gravity?
Oh yes, that should be way easier. Rotating the whole world will be cumbersome to handle at one point or another, it’s much better to fake it by rotating the camera and gravity.
Let me knof if you have any issues implementing that.
Ok so that worked a lot better. No collision issues anymore. Now i this is my player script:
func _physics_process(delta):
#Apply world rotation based on the mouse delta
var rotation_amount = -_pending_mouse_x_delta * mouse_rotation_sensitivity
_pending_mouse_x_delta = 0.0 #Reset for the next physics frame
#If mouse is moving (if rotating)
if rotation_amount != 0.0:
#Rotate Player
rotation += rotation_amount
#Rotate Gravity
PhysicsServer2D.area_set_param(get_viewport().find_world_2d().space, PhysicsServer2D.AREA_PARAM_GRAVITY_VECTOR, gravity_rotation.rotated(rotation))
#Update the player up_direction
up_direction = -gravity_rotation.rotated(rotation).normalized()
#Only apply gravity if player is not on ground
if !$floor_ray.is_colliding():
var gravity = gravity_rotation.rotated(rotation) * default_gravity_magnitude
velocity += gravity * delta
else:
#-----THIS LINE IS WEIRD-----
velocity += Vector2.ZERO
if Input.is_action_just_pressed("jump") and $floor_ray.is_colliding():
velocity += get_up_direction() * -JUMP_VELOCITY
var input_vector = Vector2(Input.get_axis("move_left", "move_right"), 0)
#-----AND SOMETHING IS WRONG HERE TOO-----
if input_vector != Vector2.ZERO:
velocity += input_vector.rotated(rotation) * SPEED
else:
velocity.x = move_toward(velocity.x, 0, delta)
velocity.y = move_toward(velocity.y, 0, delta)
move_and_slide()
However even after falling into the pit of vibe coding, nothing can seem to fix an issue i have with movement. Jumping and rotating works fine, but moving left to right keeps incrementing and when i stop holding the left or right, the player continues to slide. A big part of this problem is how i set the velocity. Im not sure how to do it correctly in a case like this.
This video shows that jumping works fine, and overall gravity is fine. But at the end i show what happens when moving left or right.
// Sorry for my previous reply, I realized soon after that it will not work due to the applied rotations
I think instead of rotating the velocity after adding each component (gravity, jump, horizontal movement) separately, you should first set all of these components to the velocity without rotation, and then apply the rotation to the velocity at the end right before you call move_and_slide(). It will make it much easier to work with.
func _physics_process(delta):
#Apply world rotation based on the mouse delta
var rotation_amount = -_pending_mouse_x_delta * mouse_rotation_sensitivity
_pending_mouse_x_delta = 0.0 #Reset for the next physics frame
#If mouse is moving (if rotating)
if rotation_amount != 0.0:
#Rotate Player
rotation += rotation_amount
#Rotate Gravity
PhysicsServer2D.area_set_param(get_viewport().find_world_2d().space, PhysicsServer2D.AREA_PARAM_GRAVITY_VECTOR, gravity_rotation.rotated(rotation))
#Update the player up_direction
up_direction = -gravity_rotation.rotated(rotation).normalized()
#Only apply gravity if player is not on ground
if !$floor_ray.is_colliding():
var gravity = gravity_rotation * default_gravity_magnitude
velocity += gravity * delta
if Input.is_action_just_pressed("jump") and $floor_ray.is_colliding():
velocity += Vector2.UP * -JUMP_VELOCITY
var input_vector = Vector2(Input.get_axis("move_left", "move_right"), 0)
velocity.x = move_toward(input_vector * SPEED, delta)
velocity = velocity.rotated(rotation)
move_and_slide()
You may need to crank up your SPEED constant a little bit more to make it feel good. You can also introduce a new constant ACCELERATION and play around with its value and multiply delta with it like so:
In your previous code, your SPEED was actually an acceleration, not speed. And you had no way of defining max speed, which is the SPEED in my code now. So you need to play around with the values again.
Let me know if that works, or there’s any issue. I haven’t tested it, just wrote it here raw.
Ok thanks. I havent implemented the acceleration yet, but i tried setting the velocity and rotation after, but this introduces new problems as seen in this video:
This is my current code now:
func _physics_process(delta):
#Apply world rotation based on the mouse delta
var rotation_amount = -_pending_mouse_x_delta * mouse_rotation_sensitivity
_pending_mouse_x_delta = 0.0 #Reset for the next physics frame
#If mouse is moving (if rotating)
if rotation_amount != 0.0:
#Rotate Player
rotation += rotation_amount
#Rotate Gravity
PhysicsServer2D.area_set_param(get_viewport().find_world_2d().space, PhysicsServer2D.AREA_PARAM_GRAVITY_VECTOR, gravity_rotation.rotated(rotation))
#Update the player up_direction4
up_direction = -gravity_rotation.rotated(rotation).normalized()
#Only apply gravity if player is not on ground
if !$floor_ray.is_colliding():
velocity.y += default_gravity_magnitude * delta
if Input.is_action_just_pressed("jump") and $floor_ray.is_colliding():
velocity.y = JUMP_VELOCITY
var direction = Input.get_axis("move_left", "move_right")
velocity.x = direction * SPEED
velocity = velocity.rotated(rotation)
move_and_slide()
AI is suggesting that its not good to rotate gravity velocity in the end, but that doesnt make sense to me. I think that your idea with rotating the velocity last makes a lot of sense.
I did a little test world on my side and realized the problem is that we are doing all the calculations within the function on the unrotated velocity, then apply the rotation to the velocity at the end of the function, which works ok on the first pass, but then in the second frame, the velocity that we start with is already rotated, so we can’t just apply more unrotated velocity to it. We first need to unrotate it. So simply doing this at the beginning of the function solved it on my side: