Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
Приклади введення¶
Вступ¶
У цьому уроці ви дізнаєтеся, як використовувати систему вхідних подій Godot InputEvent для захоплення вводу гравця. Є багато різних типів введення, які ваша гра може використовувати - клавіатура, геймпад, миша і т. д. - і багато різних способів перетворити ці введення в дії у вашій грі. Цей документ покаже вам деякі з найбільш поширених сценаріїв, які ви можете використовувати як відправні точки для власних проектів.
Примітка
Детально робота системи вхідних подій Godot розглянута в Використання inputEvent.
Події та опитування¶
Іноді ви хочете, щоб ваша гра реагувала на певну вхідну подію - наприклад, натискання кнопки "стрибка". В інших ситуаціях ви можете хотіти, щоб щось відбувалося, коли натиснута клавіша, наприклад, рух. У першому випадку можна скористатися функцією _input()
, яка буде викликатися при виникненні вхідної події. Для другого випадку Godot надає синглтон Input, який можна використовувати для запиту стану вводу.
Приклади:
func _input(event):
if event.is_action_pressed("jump"):
jump()
func _physics_process(delta):
if Input.is_action_pressed("move_right"):
# Move as long as the key/button is pressed.
position.x += speed * delta
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("jump"))
{
Jump();
}
}
public override void _PhysicsProcess(double delta)
{
if (Input.IsActionPressed("move_right"))
{
// Move as long as the key/button is pressed.
position.X += speed * (float)delta;
}
}
Це дає вам гнучкість для змішування та поєднання типів введення.
В решті цього уроку ми зосередимося на захопленні окремих подій у _input()
.
Вхідні події¶
Вхідні події - це об'єкти, які успадковуються від InputEvent. Залежно від типу події об'єкт міститиме певні властивості, пов'язані з цією подією. Щоб побачити, як насправді виглядають події, додайте вузол і прикріпіть такий скрипт:
extends Node
func _input(event):
print(event.as_text())
using Godot;
public partial class Node : Godot.Node
{
public override void _Input(InputEvent @event)
{
GD.Print(@event.AsText());
}
}
При натисканні клавіші, переміщенні мишку та виконанні іншого введення, ви можете бачити, що кожна подія прокручується у вікні виводу. Ось приклад виводу:
A
Mouse motion at position ((971, 5)) with velocity ((0, 0))
Right Mouse Button
Mouse motion at position ((870, 243)) with velocity ((0.454937, -0.454937))
Left Mouse Button
Mouse Wheel Up
A
B
Shift
Alt+Shift
Alt
Shift+T
Mouse motion at position ((868, 242)) with velocity ((-2.134768, 2.134768))
Як бачите, результати дуже різні для різних типів введення. Події клавіш навіть друкуються як символи, за які вони відповідають. Для прикладу, розглянемо вхідну події клавіші мишки InputEventMouseButton. Вона успадковується від наступних класів:
InputEvent - базовий клас для всіх вхідних подій
InputEventWithModifiers - додає можливість перевірити, чи натиснуті модифікатори, такі як Shift, або Alt.
InputEventMouse - додає властивості події мишки, такі як
position
InputEventMouseButton - містить індекс клавіші, яка була натиснута, чи це було подвійне клацання і т. д.
Порада
Рекомендовано тримати посилання на клас відкритим під час роботи з подіями, щоб ви могли перевірити доступні властивості та методи типу події.
Ви можете зіткнутися з помилками, при спробі отримати доступ до тої властивості типу введення, якої він не містить , наприклад, викликати position
з InputEventKey
. Щоб уникнути цього, спочатку перевіряйте тип події:
func _input(event):
if event is InputEventMouseButton:
print("mouse button event at ", event.position)
public override void _Input(InputEvent @event)
{
if (@event is InputEventMouseButton mouseEvent)
{
GD.Print("mouse button event at ", mouseEvent.Position);
}
}
InputMap (карта введення)¶
The InputMap is the most flexible way to handle a variety of inputs. You use this by creating named input actions, to which you can assign any number of input events, such as keypresses or mouse clicks. To see them, and to add your own, open Project -> Project Settings and select the InputMap tab:
Порада
A new Godot project includes a number of default actions already defined.
To see them, turn on Show Built-in Actions
in the InputMap dialog.
Захоплення дій¶
Визначивши дії, ви можете обробити їх у своїх скриптах, використовуючи is_action_pressed()
та is_action_released()
, передаючи назву дії, яку ви шукаєте:
func _input(event):
if event.is_action_pressed("my_action"):
print("my_action occurred!")
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("my_action"))
{
GD.Print("my_action occurred!");
}
}
Події клавіатури¶
Події клавіатури фіксуються в InputEventKey. Хоча рекомендується використовувати дії введення, можуть бути випадки, коли ви хочете переглянути саме події клавіатури. Для прикладу давайте перевіримо клавішу T:
func _input(event):
if event is InputEventKey and event.pressed:
if event.keycode == KEY_T:
print("T was pressed")
public override void _Input(InputEvent @event)
{
if (@event is InputEventKey keyEvent && keyEvent.Pressed)
{
if (keyEvent.Keycode == Key.T)
{
GD.Print("T was pressed");
}
}
}
Порада
See @GlobalScope_Key for a list of keycode constants.
Попередження
Через примару клавіатури не всі введення клавіш можуть бути зареєстровані одночасно, якщо натиснути занадто багато клавіш разом. Завдяки своєму розташуванню на клавіатурі, деякі клавіші більш схильні до ставати привидами, ніж інші. Деякі клавіатури мають анти-примарний захист на апаратному рівні, але ця функція, як правило, відсутня на клавіатурах низького класу та клавіатурах ноутбуків.
В результаті рекомендується використовувати розкладку клавіатури за замовчуванням, яка призначена для гарної роботи клавіатурі, без примар. Дивіться це питання на Gamedev Stack Exchange для отримання додаткової інформації.
Модифікатори клавіатури¶
Властивості модифікатора успадковуються від InputEventWithModifiers. Вони дозволяють перевірити наявність комбінацій модифікаторів за допомогою логічних властивостей. Давайте уявимо, що ви хочете, щоб одна річ відбулася, коли натиснута T, але зовсім інша, коли натиснуті Shift + T:
func _input(event):
if event is InputEventKey and event.pressed:
if event.keycode == KEY_T:
if event.shift_pressed:
print("Shift+T was pressed")
else:
print("T was pressed")
public override void _Input(InputEvent @event)
{
if (@event is InputEventKey keyEvent && keyEvent.Pressed)
{
switch (keyEvent.Keycode)
{
case Key.T:
GD.Print(keyEvent.ShiftPressed ? "Shift+T was pressed" : "T was pressed");
break;
}
}
}
Порада
See @GlobalScope_Key for a list of keycode constants.
Події мишки¶
Події миші випливають з класу InputEventMouse і розділені на два типи: InputEventMouseButton та InputEventMouseMotion. Зауважте, що це означає, що всі події мишки міститимуть властивість position
.
Рух мишки¶
Події InputEventMouseMotion відбуваються щоразу, коли мишка рухається. Ви можете знайти відстань переміщення у властивості relative
.
Here's an example using mouse events to drag-and-drop a Sprite2D node:
extends Node
var dragging = false
var click_radius = 32 # Size of the sprite.
func _input(event):
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
if (event.position - $Sprite2D.position).length() < click_radius:
# Start dragging if the click is on the sprite.
if not dragging and event.pressed:
dragging = true
# Stop dragging if the button is released.
if dragging and not event.pressed:
dragging = false
if event is InputEventMouseMotion and dragging:
# While dragging, move the sprite with the mouse.
$Sprite2D.position = event.position
using Godot;
public partial class MyNode2D : Node2D
{
private bool _dragging = false;
private int _clickRadius = 32; // Size of the sprite.
public override void _Input(InputEvent @event)
{
Sprite2D sprite = GetNodeOrNull<Sprite2D>("Sprite2D");
if (sprite == null)
{
return; // No suitable node was found.
}
if (@event is InputEventMouseButton mouseEvent && mouseEvent.ButtonIndex == MouseButton.Left)
{
if ((mouseEvent.Position - sprite.Position).Length() < _clickRadius)
{
// Start dragging if the click is on the sprite.
if (!_dragging && mouseEvent.Pressed)
{
_dragging = true;
}
}
// Stop dragging if the button is released.
if (_dragging && !mouseEvent.Pressed)
{
_dragging = false;
}
}
else
{
if (@event is InputEventMouseMotion motionEvent && _dragging)
{
// While dragging, move the sprite with the mouse.
sprite.Position = motionEvent.Position;
}
}
}
}
Сенсорні події¶
Якщо використовується сенсорний пристрій, можна генерувати сенсорні події. InputEventScreenTouch еквівалентний події клацання мишки, а InputEventScreenDrag працює так само, як і рух мишки.
Порада
Щоб перевірити сенсорні події на пристрої без сенсорного екрана, відкрийте вікно Параметри проекту та перейдіть до розділу Пристрої вводу/вказівки. Увімкніть "Emulate Touch From Mouse" ("Емулювати дотик від миші"), і ваш проект інтерпретуватиме клацання та рух мишки, як сенсорні події.