Turn the player to face wherever the mouse goes, swap the cursor for a crosshair, and click the targets to pop them.
Loading the game engine. This takes a moment the first time.
The player still walks with WASD, but now it also turns to face the mouse every single frame. The normal mouse arrow is hidden, and a crosshair drawn in the scene follows the mouse in its place. Click a red target and it pops: that half is target.gd, which listens to the mouse instead of the keyboard.
■ UI node · ■ 2D node · % unique name · .tscn instanced scene
extends CharacterBody2D
## How fast the player moves.
@export var speed: float = 180.0
# "_physics_process()" runs about 60 times a second. Godot calls it for you.
func _physics_process(_delta: float) -> void:
# Move with WASD, exactly like every other lesson.
var direction: Vector2 = Input.get_vector(
"move_left", "move_right", "move_up", "move_down"
)
velocity = direction * speed
move_and_slide()
# "get_global_mouse_position()" asks where the mouse is on screen.
# "look_at()" then turns the player to face that spot. Doing it every
# frame is what makes the player track the mouse everywhere it goes.
look_at(get_global_mouse_position())
# Aiming left would turn the picture upside down, so mirror it back.
$Body.flip_v = abs(rotation) > PI / 2extends Node2D
func _ready() -> void:
# Hide the normal mouse arrow, so only our drawn crosshair shows up.
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN
func _process(_delta: float) -> void:
# Every frame, move this node to wherever the mouse is. That is the whole
# trick: the crosshair is just a normal node being dragged along.
global_position = get_global_mouse_position()
# "_exit_tree()" runs when this node is about to leave the scene, which
# happens when you press the Home button.
func _exit_tree() -> void:
# Give the normal mouse arrow back. Without this line the mouse would
# stay invisible on the lesson list screen, and you could not click.
Input.mouse_mode = Input.MOUSE_MODE_VISIBLEextends Area2D
func _ready() -> void:
# "input_event" fires for ANY mouse activity over this target, even just
# sliding across it. The checks below sort out the one we actually want.
input_event.connect(_on_input_event)
# Godot fills in all three of these for us. We only use "event".
func _on_input_event(_viewport: Node, event: InputEvent, _shape_idx: int) -> void:
# Three checks, and all three have to be true:
# is this a mouse button at all (not the mouse simply moving)
# is the button going DOWN (not springing back up)
# is it the LEFT button (not the right or middle one)
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
# "queue_free()" erases the target, so the click looks like a hit.
queue_free()