פעולה עם ג'ויסטיק (גרסה ארוזה של מערכת קלט)

עודכן דף :
תאריך יצירת דף :

סביבת אימות

חלונות
  • חלונות 11
עורך Unity
  • 2020.3.25F1
חבילות מערכת קלט
  • 1.2.0

תנאים מוקדמים לטיפ זה

ההגדרות הבאות מוגדרות מראש כתנאי מוקדם להסבר של עצות אלה.

אודות XInput ו- DirectInput

למרות שהוא מוגבל ל- Windows, ישנם שני פורמטים חיבור עבור בקרי משחק: "DirectInput" ו "XInput". "ג'ויסטיק" כאן מתאים "DirectInput".

בתוכנית Joystick זו, אנו מתמודדים עם כיתה, אבל זה יכול רק להתמודד עם בקרים התומכים "DirectInput". כדי להשתמש בבקר התומך "XInput", עליך להשתמש בכיתה אחרת Gamepad .

"DirectInput" הוא פורמט חיבור ישן, וההגדרה של לחצנים היא מעורפלת יחסית, והוא יכול להתמודד עם בקרים עם צורות מיוחדות. עם זאת, לאחרונה, "XInput" הפך המיינסטרים, ואת מספר הבקרים שאינם תומכים "DirectInput" גדל. מכיוון ש- "DirectInput" מגדיר לחצנים כ- "1", "2" ו- "3", יוצרי המשחק חייבים ליצור מערכת המאפשרת להגדיר את התכתובת בין המשחק ללחצן הבקר בהתאם.

"XInput" מוגדר כדור הבא של "DirectInput" ויש לו כפתורי A ו- B מוגדרים מראש, טריגרים, מקלות וכו '. לכן, צורת הבקר יכולה לשמש רק, וזה כמעט קבוע. מכיוון שהגדרת הכפתורים מוגדרת היטב, יוצרי משחקים יכולים ליצור משחקים התואמים את הבקר מבלי לדאוג למיקום הכפתורים. מספר גדל והולך של בקרי משחק אחרונים תואמים רק עם "XInput".

אודות ג'ויסטיקים

כאמור, אין הגדרה של הכפתור, ולכן על מנת להשתמש בו בפועל, יש צורך להוסיף תהליכים בעייתיים כגון הקצאת פעולות משחק תוך בחינת המידע של כל כפתור. אני לא חושב שאתה צריך להשתמש DirectInput במשחק חדש כי זה ישן, אבל זכור שאם אתה באמת רוצה לתמוך בו, התוכנית שלך יכולה להיות מסובכת.

מדגם זה מוגבל בעצם לקבלת מידע על הלחצנים המפורטים. name למעשה, אתה צריך לבדוק ולהקצות פעולות.

ג'ויסטיק רכישת מידע

מקם אובייקט טקסט כדי להציג מידע על כל לחצן בג'ויסטיק.

צור קובץ Script. השם הוא שרירותי, אבל במקרה JoystickInfo זה , הוא .

הסקריפט נראה כך: המידע המתקבל משתנה בהתאם לסוג הבקר. קשה מאוד לתכנת עבור כל בקר, אז אני פשוט מונה את כל הכפתורים ומקבל את סוג הכפתור ולחץ על מידע.

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();
  }
}

אתה יכול לקבל מידע Joystick.current על הג'ויסטיק המחובר ב- . Joystick לאחר מכן, נקבל כל מידע מהכיתה.

Joystick כפי שניתן לראות מהכיתה, ישנן הגדרות כגון ו- , stick trigger אך אין הגדרות כגון לחצן A או לחצן התחל. לכן, עליך להשתמש במאפיינים כדי למנות את כל הלחצנים, המקלות,allControls ולברר את סוג הלחצן ואת פרטי הלחיצה.

לאחר שמירת EventSystem הסקריפט, צרף אותו לאובייקט טקסט והגדר אותו להצגת מידע.

נסה להפעיל את המשחק באמצעות בקר התומך ב- DirectInput. ניתן לאחזר כל פיסת מידע.

בהתאם לבקר, ייתכן שלא תקבל את הערך כמתוכנן בעת לחיצה על מקל, מקש חץ וכו '. מכיוון שהכפתורים אינם מוגדרים בדרך זו, קשה לקבל מידע לחיצה מדויק עבור כל כפתור. בנוסף, ניתן לראות כי זה די קשה לתמוך באופן מלא את הג'ויסטיק, כגון הסדר של הכפתורים שונה בהתאם לבקר.

אם המשחק הוא לתמוך ג'ויסטיקים, רצוי שיהיה מסך הגדרה כמו תצורת מפתח, כך שכל משתמש יכול להתאים אישית את פריסת הלחצן של הבקר שיש להם.

כיצד לקבל מידע עבור ג'ויסטיקים מרובים

מידע על Joystick.all כל הג'ויסטיקים המחוברים ניתן לקבל ב- . ReadOnlyArray זה foreach יכול להיות מונה וכן הלאה.

מאז כל ערך הוא Joystick בכיתה, אתה יכול לקבל מידע ג'ויסטיק כמו בתוכנית הקודמת.