在Pico的开发过程中,发现了一个严重的问题,Pico没有办法像手机那样调取键盘输入,如果想要调取,需要Pico那面的技术支持,非常的麻烦,所以就自己做了一个输入键盘,唯一的缺点就是不能进行中文输入,只能输入英文和数字。有需要的小伙伴可以借鉴一下,如果有更好的方法,欢迎指导,大家共同学习。工程文件会在文章末尾分想给大家
效果如下:
下面来分享一下实现过程:
Pico开发最好不要用UI(Canvas),我最开始的时候用的就是UI,但是各种问题不断,所以后来改用Plane了。首先就是搭建上面效果图的场景,将所有的Plane摆放好,在要点击的地方放上一个BoxCollider,用来进行射线检测,就像下图
我们将建好的虚拟键盘放到Pvr_UnitySDK下面,Pico的搭建之前的文章就有,不懂的可以看一下(都到这一步了,不可能不知道咋弄)。
接下来就可进行编写代码了,在这之前还需要所有按键编辑一个Tag.
在这里就直接上代码了,代码中都有注释,简单易懂
using System.Collections.Generic;
using UnityEngine;
using Pvr_UnitySDKAPI;
public class KeyInput : MonoBehaviour
{
private GameObject currentTrigerobj;
///
/// 是否大写
///
private bool isUp = false;
///
/// 显示输入的内容
///
public TextMesh Acctext;
///
/// 存放按键的列表
///
public static List mList = new List();
///
/// 键盘
///
public GameObject Keyboard;
///
/// 键盘父物体
///
public GameObject KeyboardFather;
///
/// 是否隐藏
///
private bool isHide = true;
///
/// 限制输入的字符数
///
private float Cha_max = 15;
private float Cha_min = 0;
///
/// 当前输入的字符数
///
public static float Cha_now = 0;
public TextMesh bug;
private void Awake()
{
Init();
KeyboardFather.SetActive(false);
}
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Pvr_Controller.CurrColliderGameObject != null)
{
//获取选中的按键
CurrentTrigerObj = Pvr_Controller.CurrColliderGameObject;
//播放选中动画
if (CurrentTrigerObj.tag == "Key" || CurrentTrigerObj.tag == "Back" || CurrentTrigerObj.tag == "Change" || CurrentTrigerObj.tag == "Ent" || CurrentTrigerObj.tag == "Sure" || CurrentTrigerObj.tag == "Return")
{
CurrentTrigerObj.GetComponent().Play();
}
//获取选中按键的名称
string s = CurrentTrigerObj.name;
if (Controller.UPvr_GetKeyDown(0, Pvr_KeyCode.TOUCHPAD) || Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
{
bug.text = "点击的按键为:"+CurrentTrigerObj.name;
switch (CurrentTrigerObj.tag)
{
case "Account":
//点击输入框显示键盘
Acctext = CurrentTrigerObj.GetComponentInChildren();
Cha_now = Acctext.text.Length;
Keyboard.SetActive(true);
break;
case "Key":
if (Cha_min <= Cha_now && Cha_now < Cha_max)
{
//判断一下是不是“.”
if (s == "。")
{
s = ".";
}
//将输入的内容显示出来
Acctext.text += s;
//统计输入的字符
Cha_now++;
}
break;
case "Back":
//删除输入的内容
if (Cha_min < Cha_now && Cha_now <= Cha_max)
{
if (Acctext.text != "")
{
Acctext.text = DelString(Acctext.text);
Cha_now--;
}
}
break;
case "Change":
//修改大小写
Capslk();
isUp = !isUp;
break;
case "Ent":
Keyboard.SetActive(false);
break;
case "Sure":
//退出
if (Acctext.text == "zxc")
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
else
{
bug.text = "您输入的内容为:" + Acctext.text;
}
break;
case "Return":
Keyboard.SetActive(false);
KeyboardFather.SetActive(false);
break;
}
}
}
}
public GameObject CurrentTrigerObj
{
get { return currentTrigerobj; }
set
{
if (currentTrigerobj != value)
{
}
currentTrigerobj = value;
}
}
///
/// 删除
///
///
///
private string DelString(string s)
{
if (s.Length > 0)
{
int len = s.Length;
Debug.Log(len);
s = s.Substring(0, len - 1);
}
return s;
}
///
/// 大小写锁定
///
private void Capslk()
{
Debug.Log("切换大小写");
for (int i = 0; i < mList.Count; i++)
{
mList[i].name = ChangeStr(mList[i].name);
if (!isUp)
{
mList[i].GetComponent().materials[0].CopyPropertiesFromMaterial((Material)Resources.Load("Key/" + mList[i].name.ToString() + mList[i].name.ToString(), typeof(Material)));
}
if (isUp)
{
mList[i].GetComponent().materials[0].CopyPropertiesFromMaterial((Material)Resources.Load("Key/" + mList[i].name.ToString(), typeof(Material)));
}
Debug.Log("success");
}
}
///
/// 改变字符的大小写
///
///
///
private string ChangeStr(string s)
{
if (!isUp)
{
s = s.ToUpper();
}
if (isUp)
{
s = s.ToLower();
}
return s;
}
///
/// 将所有按键放到队列中
///
public void Init()
{
Cha_now = 0;
try
{
GameObject go = GameObject.Find("Key");
foreach (Transform item in go.transform)
{
mList.Add(item.gameObject);
}
}
catch (System.Exception)
{
}
Keyboard.SetActive(false);
}
}
如果有小伙伴将上面的的代码直接拷贝下来之后,会发现Pvr_Controller.CurrColliderGameObject这个地方会报错。那是因为我没有找到自带的射线检测在什么位置(有的人说没有。咱也不知道是真是假),所以就自己在Pvr_Controller脚本中又添加了一下射线检测的方法:
需要用到的变量
/*************************************Modified Added****************************************/
///
/// 手柄碰撞圆点(自带的)
///
public GameObject dot;
///
/// 手柄射线检测碰撞到的物体
///
public static GameObject CurrColliderGameObject;
///
/// 手柄射线的初始点
///
private Transform StartPoint;
上面的StartPoint指的是发射射线的初始点,自己创建一个空物体放到手柄前方就好了。
手柄发射射线的方法
/*************************************Modified Added****************************************/
///
/// 手柄射线检测
/// 控制碰撞圆点的位置
///
void RayColliderObj()
{
RaycastHit hit;
Ray ray = new Ray(StartPoint.position, (dot.transform.position - StartPoint.position).normalized);
if (Physics.Raycast(ray, out hit))
{
dot.transform.position = hit.point;
Debug.DrawLine(StartPoint.position, hit.point, Color.red);
GameObject hitObj = hit.collider.gameObject;
if (hitObj != null)
{
CurrColliderGameObject = hitObj;
}
else
{
CurrColliderGameObject = null;
}
}
}
然后再Update中调用上面的方法就OK,解决问题。如果有知道SDK如果有自带的检测的话还请告知一下,感激不尽。
Demo地址:在这里https://github.com/ShuxinWen/Pico_KeyBoardInput