100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Unity虚拟键盘

Unity虚拟键盘

时间:2020-01-07 00:38:18

相关推荐

Unity虚拟键盘

这是一个网上找的插件,自己改了点东西,方便使用在项目中。暂时不适用中文输入,中文输入可能得调出系统输入法,项目不需要就没去研究了,大伙有兴趣可以研究研究。

包含两个类,一个是虚拟键盘类,还一个是文本框输入类。

在场景中新建个空物体,用来放虚拟键盘脚本,再新建个输入文本框,脚本可以挂在空物体上就可以了。把输入文本框赋上去就可以了。

下面上代码:

using UnityEngine;using System.Collections.Generic;/// <summary>/// 虚拟键盘主要逻辑脚本/// Tips:June 于 .3.13修改/// </summary>public class OnScreenKeyboard : MonoBehaviour{// INSPECTOR VISIBLE PROPERTIES -------------------------------------------// Skinningpublic GUIStyle boardStyle;public GUIStyle keyStyle;public Texture2D selectionImage;// Board and button sizesprivate Rect screenRect = new Rect(0, 0, 0, 0);public Vector2 stdKeySize = new Vector2(32, 32);public Vector2 lgeKeySize = new Vector2(64, 32);// Key audiopublic AudioClip keySelectSound = null;public AudioClip keyPressSound = null;// Shift settingspublic bool shiftStateSwitchEnabled = true;public ShiftState shiftStateDefault = ShiftState.Off;// Joystick settingspublic bool joystickEnabled = true;public string joyPressButton = "Fire1";public string joyCapsButton = "Fire2";// Our keys. By default we'll include a simplified QWERTY keyboard handy // for name entry, but this can literally be anything you want. Either the // two arrays must be of matching length, or lowerKeys must be of size 0.public string[] upperKeys = { "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "<<", "<row>","A", "S", "D", "F", "G", "H", "J", "K", "L", "Done", "<row>","Z", "X", "C", "V", "B", "N", "M", "Caps", "Space" };public string[] lowerKeys = { "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "<<", "<row>","a", "s", "d", "f", "g", "h", "j", "k", "l", "Done", "<row>","z", "x", "c", "v", "b", "n", "m", "Caps", "Space" };// The size must match the number of rows, or be 0public float[] rowIndents = { 0.0f, 0.2f, 0.5f };// Delays for repeated eventspublic float initialRepeatDelay = 0.8f;public float continuedRepeatDelay = 0.2f;public float moveRepeatDelay = 0.3f;// INTERNAL DATA MEMBERS --------------------------------------------------private string keyPressed = "";private int pSelectedButton;private GUIStyle pressedStyle = null;private float keyRepeatTimer = 0;private bool keyDownPrevFrame = false;private bool keyReleased = false;private bool lastKeyWasShift = false;private float moveTimer = 0;private ShiftState shiftState;private bool[] keySizes;private Rect[] keyRects;private int[] rowMarkers;private int selectedButton;private AudioSource keySelectSource = null;private AudioSource keyPressSource = null;// Change this if it's conflicting with your own GUI's windowsprivate int windowId = 0;[Header("在屏幕中的位置")]public float posX;public float posY;// INITIALISATION ---------------------------------------------------------void Awake(){// Check that our key array sizes matchif (upperKeys.Length != lowerKeys.Length && !(lowerKeys.Length == 0 && !shiftStateSwitchEnabled)){print("Error: OnScreenKeyboard needs the same number of upper and lower case keys, or there must be no lower keys and caps switch must be disabled");Destroy(this);}// Check for row markers and count row lengthsList<int> rowMarkersTemp = new List<int>();for (int i = 0; i < upperKeys.Length; i++)if (upperKeys[i] == "<row>") rowMarkersTemp.Add(i);rowMarkers = rowMarkersTemp.ToArray();// Check row indentsif (rowIndents.Length < rowMarkers.Length + 1){float[] rowIndentsTemp = new float[rowMarkers.Length + 1];for (int i = 0; i < rowIndentsTemp.Length; i++){if (i < rowIndents.Length) rowIndentsTemp[i] = rowIndents[i];else rowIndentsTemp[i] = 0;}}// Check button sizes - anything that's not a single character is a "large" keykeySizes = new bool[upperKeys.Length];for (int i = 0; i < upperKeys.Length; i++) keySizes[i] = upperKeys[i].Length > 1;// Populate the array of key rectangleskeyRects = new Rect[upperKeys.Length];int currentRow = 0;float xPos = (rowIndents.Length > 0 ? rowIndents[currentRow] : 0) + stdKeySize.x * 0.33f;float yPos = stdKeySize.y * 1.33f * currentRow + stdKeySize.y * 0.33f;for (int i = 0; i < upperKeys.Length; i++){// On the start of a new line, position the new key accordinglyif (IsRowMarker(i)){if (i != 0) currentRow++;xPos = (rowIndents.Length > 0 ? rowIndents[currentRow] : 0) + stdKeySize.x * 0.33f;yPos = stdKeySize.y * 1.33f * currentRow + stdKeySize.y * 0.33f;}else{// Draw the key, and set keyPressed accordinglykeyRects[i] = new Rect(screenRect.x + xPos, screenRect.y + yPos, keySizes[i] ? lgeKeySize.x : stdKeySize.x, keySizes[i] ? lgeKeySize.y : stdKeySize.y);// Move over to the next key's position on this linexPos += keySizes[i] ? lgeKeySize.x + stdKeySize.x * 0.33f : stdKeySize.x * 1.33f;}}//设置在屏幕中的位置if (screenRect.x == 0 && screenRect.y == 0 && screenRect.width == 0 && screenRect.height == 0){// Figure out how big we need to befloat maxWidth = 0;float maxHeight = 0;for (int i = 0; i < keyRects.Length; i++){if (keyRects[i].xMax > maxWidth) maxWidth = keyRects[i].xMax;if (keyRects[i].yMax > maxHeight) maxHeight = keyRects[i].yMax;}maxWidth += stdKeySize.x * 0.33f;maxHeight += stdKeySize.y * 0.33f;screenRect = new Rect(posX, posY, maxWidth, maxHeight);}// If we've got audio, create sources so we can play itif (keySelectSound != null){keySelectSource = gameObject.AddComponent<AudioSource>() as AudioSource;keySelectSource.spatialBlend = 0;keySelectSource.clip = keySelectSound;}if (keyPressSound != null){keyPressSource = gameObject.AddComponent<AudioSource>() as AudioSource;keyPressSource.spatialBlend = 0;keyPressSource.clip = keyPressSound;}// Set the initial shift stateif (shiftStateSwitchEnabled) SetShiftState(shiftStateDefault);// Create a pressed button skin for joystickspressedStyle = new GUIStyle();pressedStyle.normal.background = keyStyle.active.background;pressedStyle.border = keyStyle.border;pressedStyle.normal.textColor = keyStyle.active.textColor;pressedStyle.alignment = keyStyle.alignment;//新增字体样式------->按钮按下的时候调用pressedStyle.font = keyStyle.font;}// GAME LOOP --------------------------------------------------------------void Update(){// Handle keys being releasedif (!keyDownPrevFrame){keyRepeatTimer = 0;if (!keyReleased) KeyReleased();}keyDownPrevFrame = false;// Check mouse inputVector3 guiMousePos = Input.mousePosition;guiMousePos.y = Screen.height - guiMousePos.y;for (int i = 0; i < keyRects.Length; i++){Rect clickRect = keyRects[i];clickRect.x += screenRect.x; clickRect.y += screenRect.y;// Check for the click ourself, because we want to do it differently to usualif (clickRect.Contains(guiMousePos)){selectedButton = i;if (Input.GetMouseButtonDown(0)) KeyPressed();else if (Input.GetMouseButton(0)) KeyHeld();else if (Input.GetMouseButtonUp(0)) KeyReleased();}}// If the joystick is in use, update accordinglyif (joystickEnabled) CheckJoystickInput();}private void CheckJoystickInput(){// KEY SELECTIONfloat horiz = Input.GetAxis("Horizontal");float vert = Input.GetAxis("Vertical");moveTimer -= Time.deltaTime;if (moveTimer < 0) moveTimer = 0;bool hadInput = false;bool moved = false;if (horiz > 0.5f){if (moveTimer <= 0){SelectRight();moved = true;}hadInput = true;}else if (horiz < -0.5f){if (moveTimer <= 0){SelectLeft();moved = true;}hadInput = true;}if (vert < -0.5f){if (moveTimer <= 0){SelectDown();moved = true;}hadInput = true;}else if (vert > 0.5f){if (moveTimer <= 0){SelectUp();moved = true;}hadInput = true;}if (!hadInput) moveTimer = 0;if (moved){moveTimer += moveRepeatDelay;if (keySelectSource != null) keySelectSource.Play();}selectedButton = Mathf.Clamp(selectedButton, 0, upperKeys.Length - 1);// CAPITALSif (shiftStateSwitchEnabled &&(Input.GetKeyDown(KeyCode.LeftShift) ||Input.GetButtonDown(joyCapsButton)))shiftState = (shiftState == ShiftState.CapsLock ? ShiftState.Off : ShiftState.CapsLock);// TYPINGif (Input.GetButtonDown(joyPressButton)) KeyPressed();else if (Input.GetButton(joyPressButton)) KeyHeld();}// Called on the first frame where a new key is pressedprivate void KeyPressed(){keyPressed = (shiftState != ShiftState.Off) ? upperKeys[selectedButton] : lowerKeys[selectedButton];pSelectedButton = selectedButton;keyRepeatTimer = initialRepeatDelay;keyDownPrevFrame = true;keyReleased = false;lastKeyWasShift = false;if (keyPressSource != null) keyPressSource.Play();}// Called for every frame AFTER the first while a key is being heldprivate void KeyHeld(){// If the key being pressed has changed, revert to an initial pressif (selectedButton != pSelectedButton){KeyReleased();KeyPressed();return;}// Check if we're ready to report another press yetkeyRepeatTimer -= Time.deltaTime;if (keyRepeatTimer < 0){keyPressed = (shiftState != ShiftState.Off) ? upperKeys[selectedButton] : lowerKeys[selectedButton];keyRepeatTimer += continuedRepeatDelay;if (keyPressSource != null) keyPressSource.Play();}keyDownPrevFrame = true;keyReleased = false;}// Called the frame after a key is releasedprivate void KeyReleased(){keyDownPrevFrame = false;keyReleased = true;if (shiftState == ShiftState.Shift && !lastKeyWasShift)SetShiftState(ShiftState.Off);}// Selects the key to the left of the currently selected keyprivate void SelectLeft(){selectedButton--;// If we've hit the start of a row, wrap to the end of it insteadif (IsRowMarker(selectedButton) || selectedButton < 0){selectedButton++;while (!IsRowMarker(selectedButton + 1) && selectedButton + 1 < upperKeys.Length) selectedButton++;}}// Selects the key to the right of the currently selected keyprivate void SelectRight(){selectedButton++;// If we've hit the end of a row, wrap to the start of it insteadif (IsRowMarker(selectedButton) || selectedButton >= upperKeys.Length){selectedButton--;while (!IsRowMarker(selectedButton - 1) && selectedButton - 1 >= 0) selectedButton--;}}// Selects the key above the currently selected keyprivate void SelectUp(){// Find the center of the currently selected buttonfloat selCenter = keyRects[selectedButton].x + keyRects[selectedButton].width / 2;// Find the start of the next button;int tgtButton = selectedButton;while (!IsRowMarker(tgtButton) && tgtButton >= 0) tgtButton--;if (IsRowMarker(tgtButton)) tgtButton--;if (tgtButton < 0) tgtButton = upperKeys.Length - 1;// Find the button with the closest center on that linefloat nDist = float.MaxValue;while (!IsRowMarker(tgtButton) && tgtButton >= 0){float tgtCenter = keyRects[tgtButton].x + keyRects[tgtButton].width / 2;float tDist = Mathf.Abs(tgtCenter - selCenter);if (tDist < nDist){nDist = tDist;}else{selectedButton = tgtButton + 1;return;}tgtButton--;}selectedButton = tgtButton + 1;}// Selects the key below the currently selected keyprivate void SelectDown(){// Find the center of the currently selected buttonfloat selCenter = keyRects[selectedButton].x + keyRects[selectedButton].width / 2;// Find the start of the next button;int tgtButton = selectedButton;while (!IsRowMarker(tgtButton) && tgtButton < upperKeys.Length) tgtButton++;if (IsRowMarker(tgtButton)) tgtButton++;if (tgtButton >= upperKeys.Length) tgtButton = 0;// Find the button with the closest center on that linefloat nDist = float.MaxValue;while (!IsRowMarker(tgtButton) && tgtButton < upperKeys.Length){float tgtCenter = keyRects[tgtButton].x + keyRects[tgtButton].width / 2;float tDist = Mathf.Abs(tgtCenter - selCenter);if (tDist < nDist){nDist = tDist;}else{selectedButton = tgtButton - 1;return;}tgtButton++;}selectedButton = tgtButton - 1;}// Returns the row number of a specified buttonprivate int ButtonRow(int buttonIndex){for (int i = 0; i < rowMarkers.Length; i++)if (buttonIndex < rowMarkers[i]) return i;return rowMarkers.Length;}// GUI FUNCTIONALITY ------------------------------------------------------void OnGUI(){GUI.Window(windowId, screenRect, WindowFunc, "", boardStyle);}private void WindowFunc(int id){for (int i = 0; i < upperKeys.Length; i++){if (!IsRowMarker(i)){// Draw a glow behind the selected buttonif (i == selectedButton)GUI.DrawTexture(new Rect(keyRects[i].x - 5, keyRects[i].y - 5, keyRects[i].width + 10, keyRects[i].height + 10), selectionImage);// Draw the key// Note that we don't do click detection here, we do it in updateGUI.Button(keyRects[i], (shiftState != ShiftState.Off) ? upperKeys[i] : lowerKeys[i],(joystickEnabled && selectedButton == i && Input.GetButton(joyPressButton) ? pressedStyle : keyStyle));}}}// Returns true if they item at a specified index is a row end markerprivate bool IsRowMarker(int currentKeyIndex){for (int i = 0; i < rowMarkers.Length; i++) if (rowMarkers[i] == currentKeyIndex) return true;return false;}// CONTROL INTERFACE ------------------------------------------------------// Returns the latest key to be pressed, or null if no new key was pressed // since last time you checked. This means that you can only grab a single // keypress once, as it's cleared once you've read it. It also means that // if you let the user press multiple keys between checks only the most // recent one will be picked up each time.public string GetKeyPressed(){if (keyPressed == null) keyPressed = "";string key = keyPressed;keyPressed = "";return key;}// Toggle the caps state from elsewherepublic void SetShiftState(ShiftState newShiftState){if (!shiftStateSwitchEnabled) return;shiftState = newShiftState;if (shiftState == ShiftState.Shift) lastKeyWasShift = true;}public ShiftState GetShiftState() { return shiftState; }}/// <summary>/// 是否按下Shift/// </summary>public enum ShiftState { Off, Shift, CapsLock }

using UnityEngine;using UnityEngine.UI;/// <summary>/// 这是虚拟键盘插件脚本/// Tips:June于.3.13修改/// </summary>[RequireComponent(typeof(OnScreenKeyboard))]//必须添加必要的脚本public class OnScreenKeyboardExample : MonoBehaviour{/// <summary>/// 虚拟键盘脚本/// </summary>private OnScreenKeyboard osk;/// <summary>/// 输入文字/// </summary>private string inputString;/// <summary>/// 输入文本框/// </summary>public InputField inputField;private string keyPressed;//每次激活清空文本框内容(lambda表达式)private void OnEnable() => inputString = "";private void Start() => osk = GetComponent<OnScreenKeyboard>();//获取组件private void Update(){keyPressed = osk.GetKeyPressed();if (keyPressed != ""){if (keyPressed == "Backspace" || keyPressed == "<<"){if (inputString.Length > 0)inputString = inputString.Substring(0, inputString.Length - 1);}else if (keyPressed == "Space"){inputString += " ";}else if (keyPressed == "Enter" || keyPressed == "Done"){// 完成输入,这里可以写自己的逻辑-->隐藏等操作...}else if (keyPressed == "Caps"){// Toggle the capslock state yourselfosk.SetShiftState(osk.GetShiftState() == ShiftState.CapsLock ? ShiftState.Off : ShiftState.CapsLock);}else if (keyPressed == "Shift"){// Toggle shift state ourselvesosk.SetShiftState(osk.GetShiftState() == ShiftState.Shift ? ShiftState.Off : ShiftState.Shift);}else inputString += keyPressed;//将文字赋值给文本框中的文本属性inputField.text = inputString;}}}

可以根据自己的风格,调整

背景图在这里调

有个按键的风格的,在这里调

键盘的音频相关

这是我当时做项目时的,运行效果:

.3.13补充的总结:除非不得已,还是强烈推荐自己,根据这个思路写一个,或者改写一下。这个脚本实际上是用的GUI,大家都知道,GUI对于UGUI来说,性能是比较差的。一般使用情况,最多用来调试。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。