Unity实现虚拟键盘
本文实例为大家分享了Unity实现虚拟键盘的具体代码,供大家参考,具体内容如下
这是一个网上找的插件,自己改了点东西,方便使用在项目中。暂时不适用中文输入,中文输入可能得调出系统输入法,项目不需要就没去研究了,大伙有兴趣可以研究研究。
包含两个类,一个是虚拟键盘类,还一个是文本框输入类。下面直接上代码:
usingUnityEngine;
usingSystem.Collections.Generic;
/*
*OnScreenKeyboard
*ByRichardTaylor,HolopointInteractivePty.Ltd.
*
*FEATURES:
*-Fullyconfigurablelayout
*-Fullyskinnable
*-Keyselectandpressaudio
*-Configurablecapsfunctionality
*-Configurablekeyrepeatsettings
*-Workswithbothjoystick/gamepadandmouse/touchscreeninput
*-Simpleintegration
*-TestedusingXbox360controllerandiPad
*/
/*
*Timelist:
*June于2020.04.17改
*
*/
publicenumShiftState{Off,Shift,CapsLock}
publicclassOnScreenKeyboard:MonoBehaviour{
//INSPECTORVISIBLEPROPERTIES-------------------------------------------
//Skinning
publicGUIStyleboardStyle;
publicGUIStylekeyStyle;
publicTexture2DselectionImage;
//Boardandbuttonsizes
publicRectscreenRect=newRect(0,0,0,0);
publicVector2stdKeySize=newVector2(32,32);
publicVector2lgeKeySize=newVector2(64,32);
//Keyaudio
publicAudioClipkeySelectSound=null;
publicAudioClipkeyPressSound=null;
//Shiftsettings
publicboolshiftStateSwitchEnabled=true;
publicShiftStateshiftStateDefault=ShiftState.Off;
//Joysticksettings
publicbooljoystickEnabled=true;
publicstringjoyPressButton="Fire1";
publicstringjoyCapsButton="Fire2";
//Ourkeys.Bydefaultwe'llincludeasimplifiedQWERTYkeyboardhandy
//fornameentry,butthiscanliterallybeanythingyouwant.Eitherthe
//twoarraysmustbeofmatchinglength,orlowerKeysmustbeofsize0.
publicstring[]upperKeys={"Q","W","E","R","T","Y","U","I","O","P","<<","",
"A","S","D","F","G","H","J","K","L","Done","",
"Z","X","C","V","B","N","M","Caps","Space"};
publicstring[]lowerKeys={"q","w","e","r","t","y","u","i","o","p","<<","",
"a","s","d","f","g","h","j","k","l","Done","",
"z","x","c","v","b","n","m","Caps","Space"};
//Thesizemustmatchthenumberofrows,orbe0
publicfloat[]rowIndents={0.0f,0.2f,0.5f};
//Delaysforrepeatedevents
publicfloatinitialRepeatDelay=0.8f;
publicfloatcontinuedRepeatDelay=0.2f;
publicfloatmoveRepeatDelay=0.3f;
//INTERNALDATAMEMBERS--------------------------------------------------
privatestringkeyPressed="";
privateintpSelectedButton;
privateGUIStylepressedStyle=null;
privatefloatkeyRepeatTimer=0;
privateboolkeyDownPrevFrame=false;
privateboolkeyReleased=false;
privateboollastKeyWasShift=false;
privatefloatmoveTimer=0;
privateShiftStateshiftState;
privatebool[]keySizes;
privateRect[]keyRects;
privateint[]rowMarkers;
privateintselectedButton;
privateAudioSourcekeySelectSource=null;
privateAudioSourcekeyPressSource=null;
//Changethisifit'sconflictingwithyourownGUI'swindows
privateintwindowId=0;
///
///新增属性,控制虚拟键盘在屏幕中的位置
///
[Header("June_Add_Attribute_Control_keyBoardTF---------------------------------------")]
publicfloat_keyBoardTF_X;
publicfloat_keyBoardTF_Y;
//INITIALISATION---------------------------------------------------------
voidAwake()
{
//Checkthatourkeyarraysizesmatch
if(upperKeys.Length!=lowerKeys.Length&&!(lowerKeys.Length==0&&!shiftStateSwitchEnabled))
{
print("Error:OnScreenKeyboardneedsthesamenumberofupperandlowercasekeys,ortheremustbenolowerkeysandcapsswitchmustbedisabled");
Destroy(this);
}
//Checkforrowmarkersandcountrowlengths
ListrowMarkersTemp=newList();
for(inti=0;i")rowMarkersTemp.Add(i);
rowMarkers=rowMarkersTemp.ToArray();
//Checkrowindents
if(rowIndents.Length1;
//Populatethearrayofkeyrectangles
keyRects=newRect[upperKeys.Length];
intcurrentRow=0;
floatxPos=(rowIndents.Length>0?rowIndents[currentRow]:0)+stdKeySize.x*0.33f;
floatyPos=stdKeySize.y*1.33f*currentRow+stdKeySize.y*0.33f;
for(inti=0;i0?rowIndents[currentRow]:0)+stdKeySize.x*0.33f;
yPos=stdKeySize.y*1.33f*currentRow+stdKeySize.y*0.33f;
}
else
{
//Drawthekey,andsetkeyPressedaccordingly
keyRects[i]=newRect(screenRect.x+xPos,screenRect.y+yPos,keySizes[i]?lgeKeySize.x:stdKeySize.x,keySizes[i]?lgeKeySize.y:stdKeySize.y);
//Moveovertothenextkey'spositiononthisline
xPos+=keySizes[i]?lgeKeySize.x+stdKeySize.x*0.33f:stdKeySize.x*1.33f;
}
}
//Putourselvesinadefaultscreenpositionifwehaven'tbeenexplicitlyplacedyet
if(screenRect.x==0&&screenRect.y==0&&screenRect.width==0&&screenRect.height==0)
{
//Figureouthowbigweneedtobe
floatmaxWidth=0;
floatmaxHeight=0;
for(inti=0;imaxWidth)maxWidth=keyRects[i].xMax;
if(keyRects[i].yMax>maxHeight)maxHeight=keyRects[i].yMax;
}
maxWidth+=stdKeySize.x*0.33f;
maxHeight+=stdKeySize.y*0.33f;
screenRect=newRect(_keyBoardTF_X,_keyBoardTF_Y,maxWidth,maxHeight);
}
//Ifwe'vegotaudio,createsourcessowecanplayit
if(keySelectSound!=null)
{
keySelectSource=gameObject.AddComponent()asAudioSource;
keySelectSource.spatialBlend=0;
keySelectSource.clip=keySelectSound;
}
if(keyPressSound!=null)
{
keyPressSource=gameObject.AddComponent()asAudioSource;
keyPressSource.spatialBlend=0;
keyPressSource.clip=keyPressSound;
}
//Settheinitialshiftstate
if(shiftStateSwitchEnabled)SetShiftState(shiftStateDefault);
//Createapressedbuttonskinforjoysticks
pressedStyle=newGUIStyle();
pressedStyle.normal.background=keyStyle.active.background;
pressedStyle.border=keyStyle.border;
pressedStyle.normal.textColor=keyStyle.active.textColor;
pressedStyle.alignment=keyStyle.alignment;
//新增字体样式------->按钮按下的时候调用
pressedStyle.font=keyStyle.font;
}
//GAMELOOP--------------------------------------------------------------
voidUpdate()
{
//Handlekeysbeingreleased
if(!keyDownPrevFrame)
{
keyRepeatTimer=0;
if(!keyReleased)KeyReleased();
}
keyDownPrevFrame=false;
//Checkmouseinput
Vector3guiMousePos=Input.mousePosition;
guiMousePos.y=Screen.height-guiMousePos.y;
for(inti=0;i0.5f)
{
if(moveTimer<=0)
{
SelectRight();
moved=true;
}
hadInput=true;
}
elseif(horiz<-0.5f)
{
if(moveTimer<=0)
{
SelectLeft();
moved=true;
}
hadInput=true;
}
if(vert<-0.5f)
{
if(moveTimer<=0)
{
SelectDown();
moved=true;
}
hadInput=true;
}
elseif(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);
//CAPITALS
if(shiftStateSwitchEnabled&&
(Input.GetKeyDown(KeyCode.LeftShift)||
Input.GetButtonDown(joyCapsButton)))
shiftState=(shiftState==ShiftState.CapsLock?ShiftState.Off:ShiftState.CapsLock);
//TYPING
if(Input.GetButtonDown(joyPressButton))KeyPressed();
elseif(Input.GetButton(joyPressButton))KeyHeld();
}
//Calledonthefirstframewhereanewkeyispressed
privatevoidKeyPressed()
{
keyPressed=(shiftState!=ShiftState.Off)?upperKeys[selectedButton]:lowerKeys[selectedButton];
pSelectedButton=selectedButton;
keyRepeatTimer=initialRepeatDelay;
keyDownPrevFrame=true;
keyReleased=false;
lastKeyWasShift=false;
if(keyPressSource!=null)keyPressSource.Play();
}
//CalledforeveryframeAFTERthefirstwhileakeyisbeingheld
privatevoidKeyHeld()
{
//Ifthekeybeingpressedhaschanged,reverttoaninitialpress
if(selectedButton!=pSelectedButton)
{
KeyReleased();
KeyPressed();
return;
}
//Checkifwe'rereadytoreportanotherpressyet
keyRepeatTimer-=Time.deltaTime;
if(keyRepeatTimer<0)
{
keyPressed=(shiftState!=ShiftState.Off)?upperKeys[selectedButton]:lowerKeys[selectedButton];
keyRepeatTimer+=continuedRepeatDelay;
if(keyPressSource!=null)keyPressSource.Play();
}
keyDownPrevFrame=true;
keyReleased=false;
}
//Calledtheframeafterakeyisreleased
privatevoidKeyReleased()
{
keyDownPrevFrame=false;
keyReleased=true;
if(shiftState==ShiftState.Shift&&!lastKeyWasShift)
SetShiftState(ShiftState.Off);
}
//Selectsthekeytotheleftofthecurrentlyselectedkey
privatevoidSelectLeft()
{
selectedButton--;
//Ifwe'vehitthestartofarow,wraptotheendofitinstead
if(IsRowMarker(selectedButton)||selectedButton<0)
{
selectedButton++;
while(!IsRowMarker(selectedButton+1)&&selectedButton+1=upperKeys.Length)
{
selectedButton--;
while(!IsRowMarker(selectedButton-1)&&selectedButton-1>=0)selectedButton--;
}
}
//Selectsthekeyabovethecurrentlyselectedkey
privatevoidSelectUp()
{
//Findthecenterofthecurrentlyselectedbutton
floatselCenter=keyRects[selectedButton].x+keyRects[selectedButton].width/2;
//Findthestartofthenextbutton;
inttgtButton=selectedButton;
while(!IsRowMarker(tgtButton)&&tgtButton>=0)tgtButton--;
if(IsRowMarker(tgtButton))tgtButton--;
if(tgtButton<0)tgtButton=upperKeys.Length-1;
//Findthebuttonwiththeclosestcenteronthatline
floatnDist=float.MaxValue;
while(!IsRowMarker(tgtButton)&&tgtButton>=0)
{
floattgtCenter=keyRects[tgtButton].x+keyRects[tgtButton].width/2;
floattDist=Mathf.Abs(tgtCenter-selCenter);
if(tDist=upperKeys.Length)tgtButton=0;
//Findthebuttonwiththeclosestcenteronthatline
floatnDist=float.MaxValue;
while(!IsRowMarker(tgtButton)&&tgtButton
usingUnityEngine;
usingUnityEngine.UI;
///
///这是虚拟键盘插件脚本,June于2020.4.16改
///
publicclassOnScreenKeyboardExample:MonoBehaviour
{
publicOnScreenKeyboardosk;
///
///输入文字
///
privatestring_inputString;
///
///输入文本框
///
publicInputField_inputField;
//每次激活清空文本框内容
privatevoidOnEnable()
{
_inputString="";
}
voidUpdate()
{
//YoucanuseinputfromtheOSKjustbyaskingforthemostrecent
//pressedkey,whichwillbereturnedtoyouasastring,ornullif
//nokeyhasbeenpressedsinceyoulastchecked.Notethatifmore
//thanonekeyhasbeenpressedyouwillonlybegiventhemostrecent.
stringkeyPressed=osk.GetKeyPressed();
if(keyPressed!="")
{
//Takedifferentactiondependingonwhatkeywaspressed
if(keyPressed=="Backspace"||keyPressed=="<<")
{
//Removeacharacter
if(_inputString.Length>0)
_inputString=_inputString.Substring(0,_inputString.Length-1);
}
elseif(keyPressed=="Space")
{
//Addaspace
_inputString+="";
}
elseif(keyPressed=="Enter"||keyPressed=="Done")
{
//Changescreens,ordowhateveryouwantto
//dowhenyouruserhasfinishedtyping:-)
}
elseif(keyPressed=="Caps")
{
//Togglethecapslockstateyourself
osk.SetShiftState(osk.GetShiftState()==ShiftState.CapsLock?ShiftState.Off:ShiftState.CapsLock);
}
elseif(keyPressed=="Shift")
{
//Toggleshiftstateourselves
osk.SetShiftState(osk.GetShiftState()==ShiftState.Shift?ShiftState.Off:ShiftState.Shift);
}
else
{
//限制输入
if(_inputField.text.Length>=_inputField.characterLimit)return;
//Addalettertotheexistingstring
_inputString+=keyPressed;
}
//将文字赋值给文本框中的文本属性
_inputField.text=_inputString;
}
}
}
在场景中新建个空物体,用来放虚拟键盘脚本,再新建个输入文本框,脚本可以挂在画布上或者新建个空物体都行。把输入文本框赋上去就可以了。运行效果是这样的
当然,你想要各种风格之类的,换底图之类的,以及按键数量,都可以自行设置。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。