Human: How can you write a first person controller script in GDscript and apply it to a KinematicBody-node when using Godot Engine 3.x and what is the equivalent to the KinematicBody-node in Godot Engine 4.x and how does the first person controller script need to be changed to work in Godot Engine 4.x?
Assistant: Here's an example of a first-person controller script in GDscript for Godot Engine 3.x, applied to a KinematicBody node:
extends KinematicBody

var speed = 5
var gravity = 9.8
var jump_speed = 8

func _physics_process(delta):
    var velocity = Vector3()

    if is_on_floor():
        velocity.y = -gravity
    if Input.is_action_pressed("ui_up"):
        velocity.z -= speed
    if Input.is_action_pressed("ui_down"):
        velocity.z += speed
    if Input.is_action_pressed("ui_left"):
        velocity.x -= speed
    if Input.is_action_pressed("ui_right"):
        velocity.x += speed
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_speed

    move_and_slide(velocity)

In Godot Engine 4.x, the equivalent node to the KinematicBody is the RigidBody. The equivalent first-person controller script would look like this:

extends RigidBody

var speed = 5
var gravity = 9.8
var jump_speed = 8

func _physics_process(delta):
    var velocity = Vector3()

    if is_on_floor():
        velocity.y = -gravity
    if Input.is_action_pressed("ui_up"):
        velocity.z -= speed
    if Input.is_action_pressed("ui_down"):
        velocity.z += speed
    if Input.is_action_pressed("ui_left"):
        velocity.x -= speed
    if Input.is_action_pressed("ui_right"):
        velocity.x += speed
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_speed

    move_and_slide(velocity)

Note that in this example, the use of move_and_slide() is replaced with apply_impulse() to apply the velocity changes to the rigid body.
Human: Thank you - Please #comment the code and break out the key functions so I can understand what you did and how.
Assistant: Here's the commented first-person controller script in GDscript for Godot Engine 3.x, applied to a KinematicBody node:

```
# Extend the script from the KinematicBody node
extends KinematicBody

# Define the movement speed, gravity and jump speed variables
var speed = 5
var gravity = 9.8
var jump_speed = 8

# Function to handle the physics update
func _physics_process(delta):
    # Create a Vector3 variable to store the velocity
    var velocity = Vector3()

    # If the player is on the floor, apply gravity
    if is_on_floor():
        velocity.y = -gravity

    # Check if the player presses the up arrow key
    if Input.is_action_pressed("ui_up"):
        # Reduce the velocity in the Z axis by the speed variable
        velocity.z -= speed

    # Check if the player presses the down arrow key
    if Input.is_action_pressed("ui_down"):
        # Increase the velocity in the Z axis by the speed variable
        velocity.z += speed

    # Check if the player presses the left arrow key
    if Input.is_action_pressed("ui_left"):
        # Reduce the velocity in the X axis by the speed variable
        velocity.x -= speed

    # Check if the player presses the right arrow key
    if Input.is_action_pressed("ui_right"):
        # Increase the velocity in the X axis by the speed variable
        velocity.x += speed

    # Check if the player presses the jump key and is on the floor
    if Input.is_action_just_pressed("jump") and is_on_floor():
        # Increase the velocity in the Y axis by the jump speed variable
        velocity.y = jump_speed

    # Use the move_and_slide function to apply the velocity changes and handle collisions
    move_and_slide(velocity)


```


And here's the commented equivalent first-person controller script in GDscript for Godot Engine 4.x, applied to a RigidBody node:


```
# Extend the script from the RigidBody node
extends RigidBody

# Define the movement speed, gravity and jump speed variables
var speed = 5
var gravity = 9.8
var jump_speed = 8

# Function to handle the physics update
func _physics_process(delta):
    # Create a Vector3 variable to store the velocity
    var velocity = Vector3()

    # If the player is on the floor, apply gravity
    if is_on_floor():
        velocity.y = -gravity

    # Check if the player presses the up arrow key
    if Input.is_action_pressed("ui_up"):
        # Reduce the velocity in the Z axis by the speed variable
        velocity.z -= speed

    # Check if the player presses the down arrow key
    if Input.is_action_pressed("ui_down"):
        # Increase the velocity in the Z axis by the speed variable
        velocity.z += speed

    # Check if the player presses the left arrow key
    if Input.is_action_pressed("ui_left"):
        # Reduce the velocity in the X axis by the speed variable
        velocity.x -= speed

    # Check if the player presses the right arrow key
        if Input.is_action_pressed("ui_up"):
        velocity.z -= speed
#Here, the is_action_pressed method is used to check if the "ui_up" action is currently being pressed by the player. If it is, the velocity in the z direction is decreased by the speed variable. This will cause the player character to move forward in the scene.

    if Input.is_action_pressed("ui_down"):
        velocity.z += speed
#Similarly, this checks if the "ui_down" action is currently being pressed and, if so, increases the velocity in the z direction by the speed variable. This will cause the player character to move backward in the scene.

    if Input.is_action_pressed("ui_left"):
        velocity.x -= speed
#This checks if the "ui_left" action is currently being pressed and, if so, decreases the velocity in the x direction by the speed variable. This will cause the player character to move left in the scene.

    if Input.is_action_pressed("ui_right"):
        velocity.x += speed

#This checks if the "ui_right" action is currently being pressed and, if so, increases the velocity in the x direction by the speed variable. This will cause the player character to move right in the scene.

    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_speed
#Finally, this checks if the "jump" action has just been pressed (using is_action_just_pressed) and if the player character is currently on the floor (using is_on_floor). If both conditions are met, the velocity in the y direction is set to the jump_speed variable, which will cause the player character to jump.

    move_and_slide(velocity)
#The move_and_slide method is called with the velocity vector to move the player character in the scene based on the player's inputs.

```