การควบคุมด้วย Gamepad (Input System Package Version)

ปรับปรุงหน้า :
วันที่สร้างเพจ :

สภาพแวดล้อมการตรวจสอบ

หน้าต่าง
  • หน้าต่าง 11
บรรณาธิการ Unity
  • ปี 2020.3.25f1
แพ็คเกจระบบอินพุต
  • 1.2.0

ข้อกําหนดเบื้องต้นสําหรับเคล็ดลับนี้

การตั้งค่าต่อไปนี้ได้ทําไว้ล่วงหน้าเพื่อเป็นหลักฐานสําหรับคําอธิบายของเคล็ดลับนี้

เกี่ยวกับ XInput และ DirectInput

แม้ว่าจะ จํากัด เฉพาะ Windows แต่ก็มีรูปแบบการเชื่อมต่อสองรูปแบบสําหรับตัวควบคุมเกม: DirectInput และ XInput ที่นี่ "Gamepad" สอดคล้องกับ "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 บันทึกสคริปต์แล้ว ให้แนบสคริปต์นั้นและกําหนดค่าวัตถุข้อความที่แสดง

ลองเล่นเกมและดูว่าแต่ละปุ่มตอบสนองหรือไม่

อย่างไรก็ตามปุ่มต่อไปนี้ถูกกําหนดให้เป็นปุ่มเดียวกันแม้ว่าจะมีการเตรียมปุ่มหลายปุ่มเนื่องจากอ่านแตกต่างกันขึ้นอยู่กับคอนโซลเกม ในแต่ละโปรแกรมข้างต้นจะมีกระบวนการตัดสินรวมอยู่ด้วยดังนั้นเมื่อคุณกดปุ่มปุ่มสามปุ่มจะปรากฏขึ้น

XboxPlayStation และอีกมากมาย
bButton วงกลม Button ปุ่มตะวันออก
aButton ครอสบัตตัน ปุ่มใต้
x ปุ่ม สแควร์บัตตัน ปุ่มตะวันตก
yButton สามเหลี่ยมปุ่ม ปุ่มเหนือ

สิ่งที่สามารถตัดสินเป็นปุ่มได้มีดังนี้

  • ปุ่ม ปุ่ม× ปุ่มลง
  • ปุ่ม 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-pad แต่ทั้งคู่จะได้รับการปฏิบัติเหมือนกัน โดยทั่วไป 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 มีคุณสมบัติleftupdownrightสําหรับแต่ละทิศทางและคุณสามารถระบุได้ว่าถูกกดหรือไม่โดยคุณสมบัติเป็นต้น isPressed

DpadControl.ReadValueคุณยังสามารถใช้วิธีการเพื่อรับสถานะของVector2สื่อมวลชนใน . ถ้าไม่มีอะไรถูกกด (0, 0) ถ้าซ้ายจะถูกกด (-1, 0) และอื่น ๆ

หลังจาก EventSystem บันทึกสคริปต์แล้วให้แนบและตั้งค่าวัตถุข้อความสําหรับการแสดงผล

ลองเล่นเกมและโต้ตอบกับ DPAD

Vector2โดยวิธีการอยู่ในสถานะปกติดังนั้นเมื่อคุณกดในแนวทแยงมุมจะได้รับเป็นตัวเลขเช่น (0.7071, 0.7071) แทนที่จะเป็น (1, 1)

กําหนดทริกเกอร์กด

คอนโทรลเลอร์ Xbox มีปุ่มที่เรียกว่าทริกเกอร์ทางด้านซ้ายและขวา บน PlayStation จะสอดคล้องกับ L2R2 ปุ่มนี้แตกต่างจากปุ่มปกติและคุณจะได้รับจํานวนเงินที่คุณกดใน 0.0 ~ 1.0 ตัวควบคุมอื่น ๆ บางตัวมีชื่ออื่นที่ไม่ใช่ทริกเกอร์ แต่ในคอนโทรลเลอร์รุ่นเก่า ฯลฯ อาจวางเป็นปุ่มซึ่งในกรณีนี้การตัดสินการกดจะถูกจัดการเป็น 0, 1 เท่านั้น

ที่นี่ฉันต้องการตรวจสอบจํานวนการกดทริกเกอร์ วางวัตถุข้อความสําหรับแสดงบน Canvas

สร้างสคริปต์ เนื่องจากจะใช้ที่อื่นเราจะตั้งชื่อที่นี่ 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ชั้นเรียนมีคุณสมบัติและrightTriggerReadValueคุณจะได้รับจํานวนการกดในช่วง 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ดังนั้นคุณจะได้รับxyจํานวนที่คุณกดบนแกน X และแกน Y โดยและคุณสมบัติ หากคุณต้องการรับทิศทางที่คุณกําลังกดคุณสามารถรับได้ในที่พักและหากคุณต้องการmagnitudeรับจํานวนเงินที่คุณกดคุณสามารถnormalizedรับได้ในที่พัก

พยายามขยับเกมและใช้ไม้เท้า

รับข้อมูลเกมแพด

คุณสามารถรับ ID ชื่อ ฯลฯ จาก gamepad ที่เชื่อมต่อ ตัวอย่างเช่น อ้างถึงเพื่อระบุ 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 แนบและตั้งค่าวัตถุข้อความสําหรับการแสดงผล

ลองรันเกมเพื่อดูว่าข้อมูลปรากฏขึ้นหรือไม่