שימוש במפות פעולה להקצאת לחצנים להתנהגויות משחק

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

סביבת אימות

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

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

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

אודות מפות פעולה

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

יצירת מפת פעולה

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

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

בעת לחיצה כפולה על הקובץ שנוצר, יוצג החלון הבא.

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

כאן, כדוגמה, אנו מגדירים פעולת גלילה צידית וקוראים לה "SideScrollActionMap".

לאחר מכן, צור פעולות. מכיוון שמדובר במדגם, לא אעשה הרבה מהם, אבל כאן ניצור פעולות "תנועה" לתנועה ו"התקפה" להתקפה. מכיוון שאחד כבר נוצר, אנא שנה את השם או צור שם חדש, לחץ על כפתור + בפינה השמאלית העליונה והזן אותו.

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

כאשר אתה בוחר העבר, יש בחירה סוג פעולה מימין, אז להגדיר את זה "ערך".

תראה את סוג הבקרה למטה, אז בחר וקטור2. הסיבה לכך היא שהעליון והתחתון מוקצים ל- Y, והשמאל והימני מוקצים ל- X.

לאחר מכן בחר את המפתח שברצונך להקצות לאירוע זה. בחרו 'ללא כריכה' באמצע ובחרו 'נתיב' מימין. כאן אנו בוחרים את GamePad LeftStick.

פעולה זו קושרת את ה- GamePad השמאלי של ה- GamePad למהלך.

כדי לקשור גם בקרים אחרים, בחר "הוסף כריכה" מלחצן + מימין ל- Move.

כעת, לאחר הוספת No Binding, אנו מקצים Dpad עבור GamePad.

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

Sticks ו- Dpads הם לחצנים שמניחים למעלה, למטה, שמאלה וימינה, כך שניתן להוסיף אותם עם זה, אבל במקרה של מקלדות, כולם מקשים בודדים, ולכן אין הגדרה למעלה, למטה, שמאלה וימינה. כדי להגדיר את לוח המקשים למעלה, למטה, שמאלה או ימינה, בחר הוסף למעלה למטה שמאל ימין מורכב מלחצן +.

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

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

למעלה מוגדר כעת כחץ למעלה.

באופן דומה, הגדר את Down, Left ו- Right וסיימת.

כמובן, לא רק מקשי סמן אלא גם WASD ניתן להגדיר.

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

לאחר מכן בחרו 'ללא כריכה' ובחרו בלחצן שברצונכם להקצות מהנתיב.

אם ברצונך להוסיף עוד, בחר "הוסף כריכה" מהלחצן +.

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

לאחר השלמת כל ההגדרות, לחץ על "שמור נכס" כדי לשמור. באפשרותך לסגור חלון זה.

לבסוף, עם קובץ הקלט של הפרויקט (במקרה זה, הקובץ InputActionSample שיצרת קודם לכן), סמן את "צור C# Class" במפקח. הפרמטר יתווסף, אך לחץ על הלחצן "החל" כפי שהוא.

פעולה זו תיצור קובץ script עם אותו שם. הוא מכיל מחלקות שימושיות לשימוש במפות פעולה מתוכניות.

כיצד לקבל מידע קלט

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

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

קבלת פרטי קלט ב'שליחת הודעות'

השיטה הראשונה כאן היא כיצד לקבל מידע קלט ב "שלח הודעות".

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

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

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

ב "הוסף רכיב", יש "קלט שחקן" בקטגוריה "קלט", אז להוסיף אותו.

לאחר הוספת רכיב קלט הנגן, הגדר את מפת הפעולות שיצרת ב"פעולות". שחרר אותו מהפרויקט או בחר אותו מהסמל + מימין.

ודא שמפת ברירת המחדל היא זו שיצרת במפת הפעולות.

ודא שאופן הפעולה הוא "שלח הודעות".

לאחר מכן, צור סקריפט. שם הקובץ יכול להיות כל דבר, אבל הנה InputSendMessage הוא .

הסקריפט נראה כך:

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

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

  /// <summary>
  /// Move アクションが実行されたときに呼ばれる。
  /// </summary>
  /// <param name="inputValue">入力量。</param>
  public void OnMove(InputValue inputValue)
  {
    var vec = inputValue.Get<Vector2>();
    TextObject.text = $"Move:({vec.x:f2}, {vec.y:f2})\n{TextObject.text}";
  }

  /// <summary>
  /// Attack アクションが実行されたときに呼ばれる。
  /// </summary>
  public void OnAttack(InputValue inputValue)
  {
    TextObject.text = $"Attack:{inputValue.isPressed}\n{TextObject.text}";
  }
}
  • לאובייקט מצורף קלט נגן המגדיר שלח הודעות
  • ירושה מ-MonoBehavior

אם התנאים מתקיימים, אז אם אתה מגדיר שיטה בשם "OnXXXXXXXX", שיטת היעד תיקרא בעת ביצוע פעולת הפעולה שצוינה. "XXXXXXXX" הוא השם של הפעולות שנוצרו במפת הפעולות. כאן, יצרנו פעולות "העבר" ו "התקפה", ולכן שמות השיטה הם "OnMove" ו "OnAttack", בהתאמה.

OnMove ניתן לקבל את הסכום שהוזן מהארגומנט InputValue של . מכיוון שסוג הבקרה מוגדר כ- "וקטור 2", ערך InputValue.Get<Vector2> הקלט יתקבל ב- .

OnAttackInputValue.isPressed אתה יכול לקבל אם אתה לוחץ גם כן.

לאחר שמירת קובץ ה- Script, צרף אותו לאובייקט הכולל רכיב קלט נגן. הגדר גם את אובייקט הטקסט לתצוגה.

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

כפי שאתה יכול לראות כאשר אתה מזיז אותו, אתה יכול לראות כי השיטה נקראת רק כאשר יש שינוי בערך מהמצב הקודם. לדוגמה, בעת הזזת המקל שמאלה, הוא נקרא באופן יחיד, אך לא שמאלה (- OnMove 1,0). OnMove כפתור ההתקפה מגיב גם רק ברגע שלוחצים עליו, ואם לוחצים עליו ומחזיקים אותו, השיטה לא נקראת.

לכן, אני חושב שהשימוש האידיאלי הוא לא לבצע עיבוד משחק כאשר OnXXXXXXXX נקרא, אלא לשמור רק את תוכן הקלט ולהשתמש בערכים אלה בעיבוד העדכון של המשחק.

אגב, במצב הנוכחי, זה לא נקרא כאשר הלחצן משוחרר, ולכן לא ניתן לקבוע מתי OnAttack הלחצן משתחרר. כדי להגיב לכך, בחר את פעולת ההתקפה המגדירה את הלחצן בהגדרות מפת הפעולות והוסף "לחץ" מתוך "אינטראקציות". לאחר מכן, הגדר את התנהגות המפעיל של העיתונות שנוספה ל- "Press And Release" ושמור אותה.

כאשר הוא מופעל, אתה יכול לראות את זה נקרא גם OnAttack כאשר הלחצן משתחרר. isPressed false מאז זה הופך , אפשר גם לקבוע אם זה העיתוי של שחרור.

אגב, אנא מחק אינטראקציה זו מכיוון שלא ייעשה בה שימוש בעתיד.

קבל קלט באמצעות Invoke Unity Events

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

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

Invoke Unity Events יוצר אובייקט ריק המבצע פעולות קשורות.

הוסף קלט > קלט נגן לאובייקט הריק.

הגדר את קובץ מפת הפעולות שיצרת עבור פעולות (במקרה זה, InputActionSample) והגדר את מפת הפעולות שיצרת (במקרה זה, SideScrollActionMap) למפת ברירת מחדל. הגדר התנהגות כדי להפעיל אירועי אחדות.

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

הסקריפט נראה כך:

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

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

  /// <summary>
  /// Move 操作を行ったときに呼ばれる。
  /// </summary>
  /// <param name="context">コールバック内容。</param>
  public void OnMove(InputAction.CallbackContext context)
  {
    var vec = context.ReadValue<Vector2>();
    TextObject.text = $"Move:({vec.x:f2}, {vec.y:f2})\n{TextObject.text}";
  }

  /// <summary>
  /// Move 操作を行ったときに呼ばれる。
  /// </summary>
  /// <param name="context">コールバック内容。</param>
  public void OnAttack(InputAction.CallbackContext context)
  {
    var value = context.ReadValueAsButton();
    TextObject.text = $"Attack:{value}\n{TextObject.text}";
  }
}

שם OnMoveOnAttack השיטה שנקרא כאשר המשתמש מקיים אינטראקציה איתו הוא , כמו במקרה של שליחת הודעות. ב- Invoke Unity Events, באפשרותך להגדיר שם שיטה זה כרצונך.

כאשר כל אחד מהם נקרא, הוא מועבר כארגומנטInputAction.CallbackContext, כך שתוכל לקבל את מצב הקלט משם. אם אתה מגדיר "ערך" בפעולה, אתה יכול לקבל אותו בשיטה, ואם אתה מגדיר ReadValueAsButton "כפתור", אתה ReadValue יכול לקבל אותו בשיטה.

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

לאחר מכן, הרחב את "אירוע" ו "שם מפת פעולה (SideScrollActionMap)" בקלט הנגן ואתה אמור לראות את הפעולות "העבר" ו "התקפה" שיצרת.

ראשית, לחץ על כפתור + בהעברה כדי להוסיף אותו.

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

הגדר גם את אירוע ההתקפה.

הפעל את המשחק כדי לראות כיצד הוא פועל.

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

שימוש בסקריפט שנוצר באופן אוטומטי לקבלת מידע קלט

החלק השלישי מתאר כיצד להשיג מידע קלט באמצעות סקריפט שנוצר מקובץ מפת פעולות.

מכיוון שקיימת אפשרות של התנגשויות עם תהליכי רכישה אחרים, אנא השבת תהליכי רכישה אחרים.

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

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

קובץ ה- Script שנוצר באופן אוטומטי ממפת הפעולות הוא ספריה בלבד, לכן צור קובץ Script נפרד לפקדים. השם שרירותי, אבל במקרה InputScript זה הוא .

הסקריפט נראה כך:

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

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

  /// <summary>アクションマップから自動生成されたクラス。</summary>
  private InputActionSample _actionMap;

  private void Awake()
  {
    // 各操作を行ったときに呼ばれるイベントを設定する
    _actionMap = new InputActionSample();
    _actionMap.SideScrollActionMap.Move.performed += context => OnMove(context);
    _actionMap.SideScrollActionMap.Attack.performed += context => OnAttack(context);
  }

  private void OnEnable()
  {
    // このオブジェクトが有効になったときにアクションマップを有効にする
    _actionMap.Enable();
  }

  private void OnDisable()
  {
    // このオブジェクトが無効になったときにアクションマップが余計な動作を起こさないように無効にする
    _actionMap.Disable();
  }

  /// <summary>
  /// Move 操作をした時に呼ばれるメソッドです。
  /// </summary>
  /// <param name="context">コールバックパラメータ。</param>
  public void OnMove(InputAction.CallbackContext context)
  {
    // Move の入力量を取得
    var vec = context.ReadValue<Vector2>();
    TextObject.text = $"Move:({vec.x:f2}, {vec.y:f2})\n{TextObject.text}";
  }

  /// <summary>
  /// Attack 操作をした時に呼ばれるメソッドです。
  /// </summary>
  /// <param name="context">コールバックパラメータ。</param>
  public void OnAttack(InputAction.CallbackContext context)
  {
    // Attack ボタンの状態を取得
    var value = context.ReadValueAsButton();
    TextObject.text = $"Attack:{value}\n{TextObject.text}";
  }
}

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

Awake בפעולת השירות, InputActionSample נוצר מופע של ומוגדר האירוע שנקרא בזמן הפעולה. בעת OnMoveביצוע פעולות אלה, פעולת השירות , OnAttack נקראת כעת.

עם זאת, מכיוון שהגדרנו את האירוע רק כאן, עלינו OnEnable לקרוא לשיטה כאשר Enable נקראת כדי לאפשר את מפת הפעולה.

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

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

הפעל את המשחק כדי לראות כיצד הוא פועל.

כפי שניתן לראות, השיטה אינה נקראת כאשר OnMove פעולת ההעברה הופכת להיות (0, 0). אני לא בטוח למה, אבל נראה כי האירוע המבוצע רק לוקח את זה עם הקשות מופעל.

אגב, אם לא הגדרת אינטראקציות במפת הפעולה עבור התקפה, היא לא תיקרא כאשר OnAttack תשחרר את הלחצן.

כדי canceled לטפל בזה, אתה צריך להגדיר אירוע. אם אינך רוצה לבצע עיבוד מיוחד ב- (0, 0), תוכל לקרוא לשיטה כפי שהיא OnMove . הדבר נכון גם לגבי התקפה.

private void Awake()
{
  // 各操作を行ったときに呼ばれるイベントを設定する
  _actionMap = new InputActionSample();
  _actionMap.SideScrollActionMap.Move.performed += context => OnMove(context);
  _actionMap.SideScrollActionMap.Attack.performed += context => OnAttack(context);
  _actionMap.SideScrollActionMap.Move.canceled += context => OnMove(context);       // 追加
  _actionMap.SideScrollActionMap.Attack.canceled += context => OnAttack(context);   // 追加
}

הפעל וודא שהאפשרות Move:(0, 0) או Attack:False מופיעה.