التحكم باستخدام لوحة الألعاب (إصدار حزمة نظام الإدخال)

تحديث الصفحة :
تاريخ إنشاء الصفحة :

بيئة التحقق

نوافذ
  • ويندوز ١١
محرر الوحدة
  • 2020.3.25f1
حزمة نظام الإدخال
  • 1.2.0

المتطلبات الأساسية لهذه النصيحة

تم إجراء الإعدادات التالية مسبقا كمقدمة لوصف هذه النصيحة.

حول XInput و DirectInput

على الرغم من أنه يقتصر على Windows ، إلا أن هناك تنسيقين للاتصال لأجهزة التحكم في الألعاب: DirectInput و XInput. هنا ، تتوافق "لوحة الألعاب" مع "XInput".

يتعامل هذا Gamepad البرنامج مع الفئات ، ولكن هذا يمكنه فقط التعامل مع وحدات التحكم التي تدعم "XInput". لاستخدام وحدة تحكم تدعم DirectInput ، تحتاج إلى استخدام فئة مختلفة Joystick .

"DirectInput" هو تنسيق اتصال قديم وتعريف الزر غامض نسبيا ، ويمكنه التعامل مع وحدات التحكم ذات الأشكال الخاصة. ومع ذلك ، في الآونة الأخيرة ، أصبح "XInput" سائدا ، ويتزايد عدد وحدات التحكم التي لا تدعم "DirectInput". يحتوي "DirectInput" على تعريفات للأزرار مثل "1" و "2" و "3" ، لذلك يجب على منشئي اللعبة إنشاء مراسلات زر بين اللعبة ووحدة التحكم بحيث يمكن ضبطها بشكل مناسب.

يتم تعريف XInput على أنه الجيل التالي من DirectInput ويتضمن أزرار A و B المحددة مسبقا ، والمشغلات ، والعصي ، وما إلى ذلك. لذلك ، يمكن استخدام شكل ثابت فقط من وحدة التحكم ، نظرا لأن تعريف الأزرار محدد جيدا ، يمكن لمنشئي الألعاب إنشاء ألعاب تناسب وحدة التحكم دون القلق بشأن وضع الأزرار. تتزايد وحدات التحكم في الألعاب الحديثة التي تدعم "XInput" فقط.

تحديد ما إذا كان يتم الضغط على زر

يمكنك تحديد ما إذا كان يتم الضغط على زر أم لا بواسطة الخصائص بالإضافة إلى xxxxxxxx.isPressed لوحة المفاتيح والماوس. هنا ، أود عرض نوع الزر الذي أضغط عليه في النص.

أولا ، ضع كائن نص العرض.

إنشاء برنامج نصي للحكم. اسم الملف تعسفي ، ولكن ها GamepadButtons هو .

يبدو البرنامج النصي كما يلي:

using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadButtons : 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 gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // ボタンを押している間は xxxxxxxx.isPressed が true を返します

    // B ボタンや East ボタン、○ボタンは読み方が違うだけで同じボタンです
    // これは PlayStation や Xbox, Switch などでボタンの読み方が違うためです
    if (gamepad.aButton.isPressed) Builder.AppendLine($"A");
    if (gamepad.bButton.isPressed) Builder.AppendLine($"B");
    if (gamepad.xButton.isPressed) Builder.AppendLine($"X");
    if (gamepad.yButton.isPressed) Builder.AppendLine($"Y");

    if (gamepad.buttonEast.isPressed) Builder.AppendLine($"East");
    if (gamepad.buttonWest.isPressed) Builder.AppendLine($"West");
    if (gamepad.buttonNorth.isPressed) Builder.AppendLine($"North");
    if (gamepad.buttonSouth.isPressed) Builder.AppendLine($"South");

    if (gamepad.circleButton.isPressed) Builder.AppendLine($"Circle");
    if (gamepad.crossButton.isPressed) Builder.AppendLine($"Cross");
    if (gamepad.triangleButton.isPressed) Builder.AppendLine($"Triangle");
    if (gamepad.squareButton.isPressed) Builder.AppendLine($"Square");

    // コントローラーの中央にあるスタートボタン、セレクトボタン、メニューボタン、ビューボタンなどに該当します。
    if (gamepad.startButton.isPressed) Builder.AppendLine($"Start");
    if (gamepad.selectButton.isPressed) Builder.AppendLine($"Select");

    // 左と右のスティックをまっすぐ押し込んだかどうかを判定します
    if (gamepad.leftStickButton.isPressed) Builder.AppendLine($"LeftStickButton");
    if (gamepad.rightStickButton.isPressed) Builder.AppendLine($"RightStickButton");

    // 左上と右上にあるボタン。PlayStation だと L1 や R1 に該当します
    if (gamepad.leftShoulder.isPressed) Builder.AppendLine($"LeftShoulder");
    if (gamepad.rightShoulder.isPressed) Builder.AppendLine($"RightShoulder");

    // 押しているボタン一覧をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

بعد EventSystem حفظ البرنامج النصي، قم بإرفاقه بكائن نص العرض وتكوينه.

حاول تشغيل اللعبة ومعرفة ما إذا كان كل زر يستجيب.

بالمناسبة ، يتم تعريف الأزرار التالية على أنها نفس الزر ، على الرغم من إعداد أزرار متعددة لأنها تقرأ بشكل مختلف اعتمادا على وحدة التحكم في اللعبة. في كل برنامج من البرامج المذكورة أعلاه ، يتم تضمين عملية الحكم ، لذلك عند الضغط على الزر ، يتم عرض ثلاثة أزرار.

إكس بوكسبلاي ستيشن والمزيد
ب باتون زر الدائرة buttonEast
أزر زر متقاطع زرالجنوب
اكس باتون زر مربع buttonWest
واي باتون مثلثزر زرالشمال

ما يمكن الحكم عليه كزر هو على النحو التالي.

  • زر، زر ×، زر لأسفل
  • الزر B، الزر ○، الزر الأيمن
  • زر X ، زر □ ، الزر الأيسر
  • الزر Y، زر السهم لأسفل، الزر لأعلى
  • الزر "ابدأ"، الزر "القائمة"
  • حدد زر، الزر عرض
  • زر الكتف الأيسر ، زر L1
  • زر الكتف الأيمن ، زر R1
  • زر العصا اليسرى
  • زر العصا اليمنى

تحديد ما إذا كان يتم الضغط على الزر

يمكن تحديد الحكم في لحظة الصحافة من خلال الخصائص كما هو الحال مع xxxxxxxx.wasPressedThisFrame لوحة المفاتيح والماوس. ترجع قيمة لحظة true الضغط عليها، وترجع حتى إذا false تم الضغط عليها والاحتفاظ بها بعد ذلك.

دعنا نعرض الزر الذي تم الضغط عليه كنص كفحص عملية. ضع كائن نص للعرض.

يمكن أن يكون اسم ملف البرنامج النصي أي شيء ، ولكن ها GamepadButtonsOneFrame هو .

يبدو البرنامج النصي كما يلي: للبساطة ، يتم الحكم على 4 أزرار فقط.

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadButtonsOneFrame : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    if (TextObject == null)
    {
      Debug.Log($"{nameof(TextObject)} が null です。");
      return;
    }

    // 1つ目のゲームパッドの情報を取得
    var gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    // ボタンが押された瞬間かどうかを判定
    if (gamepad.aButton.wasPressedThisFrame) TextObject.text += "A";
    if (gamepad.bButton.wasPressedThisFrame) TextObject.text += "B";
    if (gamepad.xButton.wasPressedThisFrame) TextObject.text += "X";
    if (gamepad.yButton.wasPressedThisFrame) TextObject.text += "Y";
  }
}

بعد EventSystem حفظ البرنامج النصي ، قم بإرفاقه وتعيين كائن نصي للعرض.

حاول تشغيل اللعبة والضغط على الزر. أعتقد أنه سيتم إضافة الزر الذي ضغطت عليه. يمكنك أيضا أن ترى أن الضغط باستمرار على الزر لا يضيف أي نص.

تحديد ما إذا كانت لحظة تحرير الزر

لا توجد عينة، ولكن يمكنك تحديد ما إذا كانت هذه هي wasPressedThisFrame اللحظة التي تطلقها فيها باستخدام خاصية بدلا من wasReleasedThisFrame خاصية.

تحديد متى تضغط على مفاتيح الأسهم

يحدد الضغط على DPAD. اعتمادا على وحدة التحكم في اللعبة ، سوف تطير مع مفاتيح الأسهم ولوحة D ، ولكن يتم التعامل مع كلاهما على نفس النحو. يحدد DPAD بشكل أساسي فقط ما إذا كنت تدفع في هذا الاتجاه أم لا. لا يوجد حكم مثل "الدفع قليلا" مثل العصا.

يضع كائن نص لعرض قرار سواء تم الضغط عليه أم لا كفحص عملية.

إنشاء برنامج نصي. اسم الملف تعسفي ، ولكن ها GamepadDpad هو .

يبدو البرنامج النصي كما يلي:

using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadDpad : 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 gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // Dpad の押下情報を Vector2 として取得するパターン
    var value = gamepad.dpad.ReadValue();
    Builder.Append($"(x:{value.x}, y:{value.y})");

    // Dpad の各方向のボタンを押しているかどうかの判定
    if (gamepad.dpad.left.isPressed) Builder.Append(" left");
    if (gamepad.dpad.right.isPressed) Builder.Append(" right");
    if (gamepad.dpad.up.isPressed) Builder.Append(" up");
    if (gamepad.dpad.down.isPressed) Builder.Append(" down");

    // Dpad の情報をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

يمكنك الحصول على معلومات Gamepad.dpad DPAD على .

يحتوي DPAD على leftupdown rightخصائص لكل اتجاه ، ويمكنك تحديد ما إذا كان يتم الضغط عليه أم لا بواسطة العقار وما إلى ذلك. isPressed

DpadControl.ReadValue يمكنك أيضا استخدام الطريقة للحصول على حالة Vector2 الصحافة في . إذا لم يتم الضغط على أي شيء (0 ، 0) ، إذا تم الضغط على اليسار (-1 ، 0) ، وهكذا.

بعد EventSystem حفظ البرنامج النصي ، قم بإرفاقه وتعيين كائن نصي للعرض.

حاول تشغيل اللعبة والتفاعل مع DPAD.

Vector2 بالمناسبة ، في حالة طبيعية ، لذلك عند الضغط قطريا ، يتم الحصول عليها كرقم مثل (0.7071 ، 0.7071) بدلا من (1 ، 1).

تحديد مكابس الزناد

تحتوي وحدات تحكم Xbox على أزرار تسمى المشغلات على اليسار واليمين. على بلاي ستيشن ، يتوافق مع L2R2. يختلف هذا الزر عن الزر العادي ، ويمكنك الحصول على المبلغ الذي تضغط عليه في 0.0 ~ 1.0. تم تجهيز بعض وحدات التحكم الأخرى بأسماء أخرى غير المشغلات ، ولكن في وحدات التحكم القديمة ، وما إلى ذلك ، يمكن ببساطة وضعها كأزرار ، وفي هذه الحالة يتم التعامل مع حكم الضغط فقط على أنه 0 ، 1.

هنا ، أود التحقق من مقدار مكابس الزناد. يضع كائن نص للعرض على اللوحة.

إنشاء برنامج نصي. نظرا لأنه سيتم استخدامه في مكان آخر ، فسوف نسميه هنا GamepadReadValue .

يبدو البرنامج النصي كما يلي:

using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadReadValue : 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 gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // トリガーの押下量を取得
    Builder.AppendLine($"LeftTrigger:{gamepad.leftTrigger.ReadValue()}");
    Builder.AppendLine($"RightTrigger:{gamepad.rightTrigger.ReadValue()}");

    // 情報をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

Gamepad كل leftTriggerفئة لها خاصية ويمكنك rightTrigger ReadValue الحصول على كمية المكابس في نطاق 0.0 ~ 1.0 عن طريق استدعاء الطريقة. يمكن أيضا التعامل مع المشغلات كأزرار ، بحيث isPressed يمكنك أيضا الحكم مثل. isPressed true بالمناسبة ، يعتمد مقدار يصبح ReadValue على 0.5.

بعد حفظ البرنامج النصي ، EventSystem قم بإرفاقه وتعيين كائن نصي للعرض.

حاول تشغيل اللعبة وتحريك الزناد.

تحديد معلومات العصا

يمكن للعصا الحصول على معلومات العصا اليسرى والعصا اليمنى على التوالي ، ويمكنك الحصول على مقدار دفع العصا لأسفل في أي اتجاه. بالطبع ، إذا لم يكن لديك عصا على وحدة التحكم الخاصة بك ، فلن تتمكن من الحصول على هذه المعلومات.

يمكن استرجاع معلومات العصا باستخدام ، Gamepad.rightStick على التواليGamepad.leftStick.

بالنسبة للبرنامج النصي لتأكيد العملية ، سنقوم بتحويل البرنامج النصي المستخدم مسبقا للحصول على المشغل.

// 省略

public class GamepadReadValue : MonoBehaviour
{
  // 省略

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    // 省略

    // トリガーの押下量を取得
    Builder.AppendLine($"LeftTrigger:{gamepad.leftTrigger.ReadValue()}");
    Builder.AppendLine($"RightTrigger:{gamepad.rightTrigger.ReadValue()}");

    // スティックの入力を取得
    var leftStickValue = gamepad.leftStick.ReadValue();
    Builder.AppendLine($"LeftStick:{leftStickValue.normalized * leftStickValue.magnitude}");
    var rightStickValue = gamepad.rightStick.ReadValue();
    Builder.AppendLine($"RightStick:{rightStickValue.normalized * rightStickValue.magnitude}");

    // 情報をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

leftStickrightStick يمكنك الحصول على المعلومات الصحفية عن طريق الاتصال بالطريقة Vector2 من ReadValue أو . Vector2 حتى تتمكن من الحصول على مقدار x y الضغط على المحور X والمحور Y بواسطة والخصائص ، إذا كنت ترغب في الحصول على الاتجاه الذي تضغط عليه ، يمكنك الحصول عليه في العقار ، وإذا كنت magnitude ترغب في الحصول على المبلغ الذي تضغط عليه ، فيمكنك normalized الحصول عليه في العقار.

حاول تحريك اللعبة بالفعل وتشغيل العصا.

الحصول على معلومات لوحة الألعاب

يمكنك الحصول على المعرف والاسم وما إلى ذلك من لوحة الألعاب المتصلة. على سبيل المثال، راجع إلى لتحديد name نوع وحدة التحكم المتصلة، أو يمكنك الرجوع إلى لوحة الألعاب التي deviceId يجب ربطها عند توصيل لوحات ألعاب متعددة.

هنا ، سنعرض المعلومات في النص للتحقق من العملية.

اسم البرنامج النصي تعسفي ، ولكن ها GamepadInfo هو .

يبدو البرنامج النصي كما يلي:

using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadInfo : 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 gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // ゲームパッドの各情報を取得
    Builder.AppendLine($"deviceId:{gamepad.deviceId}");
    Builder.AppendLine($"name:{gamepad.name}");
    Builder.AppendLine($"displayName:{gamepad.displayName}");
    Builder.AppendLine($"shortDisplayName:{gamepad.shortDisplayName}");
    Builder.AppendLine($"path:{gamepad.path}");
    Builder.AppendLine($"layout:{gamepad.layout}");

    // 情報をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

Gamepad يمكنك الحصول على معلومات مختلفة من تم استردادها. وهنا بعض المقتطفات.

بعد حفظ البرنامج النصي ، EventSystem قم بإرفاقه وتعيين كائن نصي للعرض.

حاول تشغيل اللعبة لمعرفة ما إذا كانت المعلومات تظهر أم لا.