game-physicsgodotgdscriptgodot4

How to make CharacterBody3D fly at certain height above the ground?


I tried making an enemy (CharacterBody3D) fly above the ground with use of RayCast3D and checking if it collides with anything, If it did, I wanted to place enemy at certain height above the ground. However, my code doesn’t work and I don’t know how to fix it. Have a look:

func _physics_process(delta: float) -> void:

 if raycastNode.is_colliding():
  var collisionPoint=raycastNode.get_collision_point()
  global_transform.origin.y=collisionPoint.y+2.5 #this makes enemies fall down and teleport back to new height and messes a lot with their ability to move

 # Add the gravity.
 if not is_on_floor():
   velocity.y -= gravity * delta #commenting this makes enemies unable to move and if you go below them, they get moved higher

If I add global_transform.origin.y=collisionPoint.y+2.5 instruction, enemies start falling from from the position set by instruction, then almost instantly reappear at that height (2.5) and when they want to move toward detected player, they have huge issues with it. Removing if not is_on_floor(): code stops enemies from falling in place, but they do not move at all except upwards if they detect something under them.

I don’t know how to fix it and would be thankful for any help provided!

The scene

_physics_process


Solution

  • After a lot of experimenting with velocities, I found imperfect, but good enough solution:

    func _physics_process(delta: float) -> void:
        #var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
        
        if raycastNode.is_colliding():
            var collisionPoint: Vector3 = raycastNode.get_collision_point()
            var distanceToGround: float = global_transform.origin.y - collisionPoint.y
            
            if distanceToGround>1.0:
                velocity.y-=delta*gravity
                print(">1.0")
            elif distanceToGround>0.1:
                velocity.y+=delta
                print(">0.1")
            else:
                if velocity.y<0:
                    velocity.y=0.001
                velocity.y+=delta*gravity
                print("<=0.1")
        else:
            if velocity.y>0:
                velocity.y=-0.001
            velocity.y -= gravity * delta
            print("noColl") 
    ...
    

    The scene with RayCast3D