A game about forced loneliness, made by TACStudios
1using System.Globalization; 2using UnityEngine.InputSystem.LowLevel; 3using UnityEngine.Scripting; 4 5namespace UnityEngine.InputSystem.Controls 6{ 7 /// <summary> 8 /// A key on a <see cref="Keyboard"/>. 9 /// </summary> 10 /// <remarks> 11 /// This is an extended button control which adds various features to account for the fact that keys 12 /// have symbols associated with them which may change depending on keyboard layout as well as in combination 13 /// with other keys. 14 /// 15 /// Note: 16 /// Unity input system key codes and input manager key codes are designed with game controls in mind. 17 /// 18 /// This means the way they are assigned is intended to preserve the location of keys on keyboards, 19 /// so that pressing a key in the same location on different keyboards should result in the same action 20 /// regardless of what is printed on a key or what current system language is set. 21 /// 22 /// This means, for example, that <see cref="Key.A"/> is always the key to the right of <see cref="Key.CapsLock"/>, 23 /// regardless of which key (if any) produces the "a" character on the current keyboard layout. 24 /// 25 /// Unity relies on physical hardware in the keyboards to report same USB HID "usage" for the keys in 26 /// the same location.This puts a practical limit on what can be achieved, because different keyboards 27 /// might report different data, and this is outside of Unity's control. 28 /// 29 /// For this reason, you should not use key codes to read text input. 30 /// Instead, you should use the <see cref="Keyboard.onTextInput"/> callback. 31 /// The `onTextInput` callback provides you with the actual text characters which correspond 32 /// to the symbols printed on a keyboard, based on the end user's current system language layout. 33 /// 34 /// To find the text character (if any) generated by a key according to the currently active keyboard 35 /// layout, use the <see cref="InputControl.displayName"/> property of <see cref="KeyControl"/>. 36 /// </remarks> 37 public class KeyControl : ButtonControl 38 { 39 /// <summary> 40 /// The code used in Unity to identify the key. 41 /// </summary> 42 /// <remarks> 43 /// This property must be initialized by <see cref="InputControl.FinishSetup"/> of 44 /// the device owning the control. 45 /// You should not use `keyCode` to read text input. For more information, <see cref="KeyControl"/> 46 /// </remarks> 47 public Key keyCode { get; set; } 48 49 ////REVIEW: rename this to something like platformKeyCode? We're not really dealing with scan code here. 50 /// <summary> 51 /// The code that the underlying platform uses to identify the key. 52 /// </summary> 53 public int scanCode 54 { 55 get 56 { 57 RefreshConfigurationIfNeeded(); 58 return m_ScanCode; 59 } 60 } 61 62 protected override void RefreshConfiguration() 63 { 64 // Wipe our last cached set of data (if any). 65 displayName = null; 66 m_ScanCode = 0; 67 68 var command = QueryKeyNameCommand.Create(keyCode); 69 if (device.ExecuteCommand(ref command) > 0) 70 { 71 m_ScanCode = command.scanOrKeyCode; 72 73 var rawKeyName = command.ReadKeyName(); 74 if (string.IsNullOrEmpty(rawKeyName)) 75 { 76 displayName = rawKeyName; 77 return; 78 } 79 80 var textInfo = CultureInfo.InvariantCulture.TextInfo; 81 // We need to lower case first because ToTitleCase preserves upper casing. 82 // For example on Swedish Windows layout right shift display name is "HÖGER SKIFT". 83 // Just passing it to ToTitleCase won't change anything. But passing "höger skift" will return "Höger Skift". 84 var keyNameLowerCase = textInfo.ToLower(rawKeyName); 85 if (string.IsNullOrEmpty(keyNameLowerCase)) 86 { 87 displayName = rawKeyName; 88 return; 89 } 90 91 displayName = textInfo.ToTitleCase(keyNameLowerCase); 92 } 93 } 94 95 // Cached configuration data for the key. We fetch this from the 96 // device on demand. 97 private int m_ScanCode; 98 } 99}