Hoạt động bằng cần điều khiển (Phiên bản đóng gói Hệ thống đầu vào)
Môi trường xác minh
- Windows
-
- cửa sổ 11
- Biên tập viên Unity
-
- 2020.3.25f1
- Gói hệ thống đầu vào
-
- 1.2.0
Điều kiện tiên quyết cho mẹo này
Các cài đặt sau đây được cấu hình sẵn làm điều kiện tiên quyết để giải thích các mẹo này.
Giới thiệu về XInput và DirectInput
Mặc dù nó bị giới hạn ở Windows, nhưng có hai định dạng kết nối cho bộ điều khiển trò chơi: "DirectInput" và "XInput". "Cần điều khiển" ở đây tương ứng với "Đầu vào trực tiếp".
Trong Joystick
chương trình này, chúng ta đang xử lý một lớp, nhưng nó chỉ có thể xử lý các bộ điều khiển hỗ trợ "DirectInput".
Để sử dụng bộ điều khiển hỗ trợ "XInput", bạn cần sử dụng một lớp khác Gamepad
.
"DirectInput" là một định dạng kết nối cũ và định nghĩa về các nút tương đối mơ hồ và nó có thể xử lý các bộ điều khiển có hình dạng đặc biệt. Tuy nhiên, gần đây, "XInput" đã trở thành xu hướng chủ đạo và số lượng bộ điều khiển không hỗ trợ "DirectInput" ngày càng tăng. Vì "DirectInput" định nghĩa các nút là "1", "2" và "3", người tạo trò chơi phải tạo một hệ thống cho phép đặt tương ứng nút trò chơi và bộ điều khiển một cách thích hợp.
"XInput" được định nghĩa là thế hệ tiếp theo của "DirectInput" và có các nút, trình kích hoạt, gậy A và B được xác định trước, v.v. Do đó, hình dạng của bộ điều khiển chỉ có thể được sử dụng, gần như cố định. Vì định nghĩa về các nút được xác định rõ, người tạo trò chơi có thể tạo trò chơi phù hợp với bộ điều khiển mà không phải lo lắng về vị trí của các nút. Ngày càng có nhiều bộ điều khiển trò chơi gần đây chỉ tương thích với "XInput".
Giới thiệu về cần điều khiển
Như đã đề cập ở trên, không có định nghĩa về nút, vì vậy để thực sự sử dụng nó, cần phải thêm các quy trình rắc rối như chỉ định hoạt động trò chơi trong khi kiểm tra thông tin của từng nút. Tôi không nghĩ rằng bạn cần sử dụng DirectInput trong một trò chơi mới vì nó đã cũ, nhưng hãy nhớ rằng nếu bạn thực sự muốn hỗ trợ nó, chương trình của bạn có thể phức tạp.
Mẫu này về cơ bản được giới hạn để có được thông tin về các nút được liệt kê.
name
Trong thực tế, bạn cần phải kiểm tra và phân công các hoạt động.
Thu thập thông tin cần điều khiển
Đặt một đối tượng văn bản để hiển thị thông tin về từng nút trên cần điều khiển.
Tạo tập lệnh. Tên là tùy ý, nhưng trong trường hợp JoystickInfo
này , nó là .
Kịch bản trông như thế này: Thông tin thu được khác nhau tùy thuộc vào loại bộ điều khiển. Rất khó để lập trình cho từng bộ điều khiển, vì vậy tôi chỉ cần liệt kê tất cả các nút và lấy loại nút và nhấn thông tin.
using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;
public class JoystickInfo : MonoBehaviour
{
<summary>情報を表示させるテキストオブジェクト。</summary>
[SerializeField] private Text TextObject;
StringBuilder Builder = new StringBuilder();
// 更新はフレームごとに1回呼び出されます
void Update()
{
if (TextObject == null)
{
Debug.Log($"{nameof(TextObject)} が null です。");
return;
}
// 1つ目のジョイスティックの情報を取得
var joystick = Joystick.current;
if (joystick == null)
{
Debug.Log("ジョイスティックがありません。");
TextObject.text = "";
return;
}
Builder.Clear();
// ジョイスティックの情報取得
Builder.AppendLine($"deviceId:{joystick.deviceId}");
Builder.AppendLine($"name:{joystick.name}");
Builder.AppendLine($"displayName:{joystick.displayName}");
// ジョイスティックにはボタンの大部分が定義されていないので
// 基本的には allControls で列挙して入力の種類と値を確認していく
foreach (var key in joystick.allControls)
{
if (key is StickControl stick)
{
if (stick.up.isPressed) Builder.AppendLine($"{key.name} Up");
if (stick.down.isPressed) Builder.AppendLine($"{key.name} Down");
if (stick.left.isPressed) Builder.AppendLine($"{key.name} Left");
if (stick.right.isPressed) Builder.AppendLine($"{key.name} Right");
var value = stick.ReadValue();
if (value.magnitude > 0f)
{
Builder.AppendLine($"{key.name}:{value.normalized * value.magnitude}");
}
}
else if (key is Vector2Control vec2)
{
var value = vec2.ReadValue();
if (value.magnitude > 0f)
{
Builder.AppendLine($"{key.name}:{value.normalized * value.magnitude}");
}
if (vec2.x.ReadValue() != 0f)
{
Builder.AppendLine($"{key.name}.x:{vec2.x.ReadValue()}");
}
if (vec2.y.ReadValue() != 0f)
{
Builder.AppendLine($"{key.name}.x:{vec2.y.ReadValue()}");
}
}
else if (key is ButtonControl button)
{
if (button.isPressed) Builder.AppendLine($"{key.name} isPress");
var value = button.ReadValue();
if (value != 0f)
{
Builder.AppendLine($"{key.name}:{value}");
}
}
else if (key is AxisControl axis)
{
if (axis.IsPressed()) Builder.AppendLine($"{key.name} isPress");
var value = axis.ReadValue();
if (value != 0f)
{
Builder.AppendLine($"{key.name}:{value}");
}
}
else
{
Builder.AppendLine($"Type={key.GetType()}");
}
}
// 押しているボタン一覧をテキストで表示
TextObject.text = Builder.ToString();
}
}
Bạn có thể nhận thông tin Joystick.current
về cần điều khiển được kết nối trong .
Joystick
Sau đó, chúng tôi sẽ lấy từng thông tin từ lớp.
Joystick
Như bạn có thể thấy từ lớp, có các định nghĩa như và , stick
trigger
nhưng không có định nghĩa nào như nút A hoặc nút bắt đầu.
Do đó, bạn nên sử dụng Thuộc tính để liệt kê tất cả các nút,allControls
gậy và tìm ra loại nút và nhấn thông tin.
Khi tập lệnh được lưu, EventSystem
hãy đính kèm nó và đặt một đối tượng văn bản để hiển thị thông tin.
Hãy thử chạy trò chơi bằng bộ điều khiển hỗ trợ DirectInput. Mỗi mẩu thông tin có thể được truy xuất.
Tùy thuộc vào bộ điều khiển, bạn có thể không nhận được giá trị như dự định khi nhấn gậy, phím mũi tên, v.v. Vì các nút không được xác định theo cách này, rất khó để có được thông tin nhấn chính xác cho mỗi nút. Ngoài ra, bạn có thể thấy rằng khá khó để hỗ trợ đầy đủ cần điều khiển, chẳng hạn như cách sắp xếp các nút khác nhau tùy thuộc vào bộ điều khiển.
Nếu trò chơi hỗ trợ cần điều khiển, bạn nên có một màn hình cài đặt như cấu hình phím để mỗi người dùng có thể tùy chỉnh bố cục nút của bộ điều khiển mà họ có.
Cách lấy thông tin cho nhiều cần điều khiển
Thông tin về Joystick.all
tất cả các cần điều khiển được kết nối có thể được lấy trong .
ReadOnlyArray
Nó foreach
có thể được liệt kê trong và như vậy.
Vì mỗi giá trị là Joystick
một lớp, bạn có thể nhận được thông tin cần điều khiển như trong chương trình trước.