Rotating a player correctly on a planet

wozeparrotwozeparrot Posts: 14Member

Hi

I have a planet and a player. The planet has spherical gravity but the player does not rotate correctly around it.


Tags :

Answers

  • wozeparrotwozeparrot Posts: 14Member

    Let me clarify. I want to place the player on the planet correctly so that the player can move around it

  • Pavan_KumarPavan_Kumar Posts: 8Member

    I did it as following:
    1. Create a KinematicBody, add MeshInstance and CollisionShape,
    2. Rotate the character mesh and make it lie down,it's head is on +Z axis(blue), in Godot -Z is forward.(don't skip this step, it will save some rotations while applying gravity, else you may need to calculate some quaternions and then apply it),
    3. Lock all angular axis, since we take full control over the body's rotation,
    4. Optional, create an Area with CollisionShape, names foot at the bottom to check if we are are on ground,so that we need not keep pulling the body when it's on ground,
    5. Calculate the direction from the character to the planet's center, look at planet's center and apply gravity in direction, if we are not on ground.
    6. Note, I made planet as a StaticBody, it is in group "Planet".
    The code is as follows:

    extends KinematicBody
    
    onready var planet = get_parent().get_node("Planet")
    
    const GRAVITY = -1.0
    const ORIGIN = Vector3()
    const ZERO_GRAVITY = Vector3()
    const Y_AXIS = Vector3(0, 1, 0)
    
    var my_gravity_scale = 1
    var gravity_force = Vector3()
    var is_on_ground = false
    
    func _ready():
        self.axis_lock_angular_x = true
        self.axis_lock_angular_y = true
        self.axis_lock_angular_z = true
    
        return
    
    func _physics_process(delta):
        attract(delta)
    
        return
    
    func attract(delta):
    
        if not is_on_ground:
            var target_dir = (planet.global_transform.origin - self.global_transform.origin).normalized()
            gravity_force = target_dir * my_gravity_scale *delta
            self.look_at(planet.global_transform.origin, Y_AXIS)
            self.move_and_collide(gravity_force)
    
        else:
            gravity_force = ZERO_GRAVITY
    
        return
    
    
    func _on_Foot_body_entered(body):
        if body.is_in_group("Planet"):
            print("Landed")
            is_on_ground = true
    
        return
    
    
    func _on_Foot_body_exited(body):
        if body.is_in_group("Planet"):
            is_on_ground = false
    
        return
    
Sign In or Register to comment.