1 实现曲线和直线的切换
1.头衔手柄的控制采取VRTK自带场景里的升级版的预设体,不同于第一天学习的预制体,如下图所示
2.为有手柄RightController添加脚本,更改VRTK中的Pointer Renderer即可改变射线形状
3.以下是Bezier曲线,可以为其添加特效。注意setting的设置,颜色,箭头图标,最远距离。
2 功能的封装实例
public class VrController : MonoBehaviour
{
public SteamVR_TrackedObject tObje; //面板拖拽赋值
SteamVR_Controller.Device dev;
private VRTK_Pointer pointer;
private VRTK_StraightPointerRenderer strainghtPointerARender;
private VRTK_BezierPointerRenderer bezierPointerRenderer;
public GoodsTypes goodsTypes;
bool flag = false; //是否振动
ButtonController BtnCtrl;
void Awake()
{
pointer = GetComponent<VRTK_Pointer>();
strainghtPointerARender = GetComponent<VRTK_StraightPointerRenderer>();
bezierPointerRenderer = GetComponent<VRTK_BezierPointerRenderer>();
GetComponent<VRTK_Pointer>().DestinationMarkerEnter += new DestinationMarkerEventHandler(DoPointerIn);
GetComponent<VRTK_Pointer>().DestinationMarkerSet += new DestinationMarkerEventHandler(DoPointerDestinationSet);
BtnCtrl = this.gameObject.transform.Find("[VRTK][AUTOGEN][Controller][CollidersContainer]/Head").GetComponent<ButtonController>();
//Head是手柄上头部的位置,提前在资源找到预制体,加入ButtonController控制脚本,这个脚本是自己写的,用来实现一些功能,手柄触碰不同的物品,会有枚举记录下来。注意路径的查询
}
void Update()
{
if ((int)tObje.index >= 0) //排除index = -1的情况,这个很重要,测试时需排除!!!!
{
dev = SteamVR_Controller.Input((int)tObje.index);
if (dev.GetPressDown(SteamVR_Controller.ButtonMask.Trigger))
{
JudeTypes(BtnCtrl.types);
}
}
}
/// <summary>
/// 根据手柄接触的物体,触发不同的方法
/// </summary>
/// <param name="types"></param>
public void JudeTypes(GoodsTypes types)
{
switch (types)
{
case GoodsTypes.CanGrab:
BtnCtrl.OnTriggerGet(); //抓取拆卸
break;
case GoodsTypes.FunctionBtn:
BtnCtrl.OnChangeWupin(); //触发面板上按钮的脚本
break;
case GoodsTypes.NumBtn:
BtnCtrl.ChangeWendu(); //触发面板上数字按钮的脚本
break;
case GoodsTypes.None:
break;
default:
break;
}
}
/// <summary>
/// 手柄振动方法
/// </summary>
IEnumerator HpaticPulse(float time,bool bl)
{
flag = bl;
while (flag)
{
Invoke("StopHapticPulse", time);
dev.TriggerHapticPulse(1000);
//等待帧结束执行,等待所有的摄像机和GUI渲染接受后渲染(在屏幕显示之前)
yield return new WaitForEndOfFrame();
}
}
public void StopHapticPulse()
{
flag = false;
}
/// <summary>
/// 外界调用手柄振动方法
/// </summary>
public void ShowShok(float t)
{
StartCoroutine(HpaticPulse(t, true));
}
/// <summary>
/// 更改射线的类型和颜色
/// </summary>
private void DoPointerIn(object sender, DestinationMarkerEventArgs e)
{
if (e.target.tag == "Plane" || e.target.tag == "ZhuoMian") //曲线
{
pointer.pointerRenderer = bezierPointerRenderer;
pointer.enableTeleport = true;
strainghtPointerARender.enabled = false;
bezierPointerRenderer.enabled = true;
}
else
{
pointer.pointerRenderer = strainghtPointerARender;
pointer.enableTeleport = false;
strainghtPointerARender.enabled = true;
bezierPointerRenderer.enabled = false;
}
}
/// <summary>
/// 圆盘抬起时,高亮触发事件
/// </summary>
private void DoPointerDestinationSet(object sender, DestinationMarkerEventArgs e)
{
bool isFlashing;
HighLighter liter = e.target.GetComponent<HighLighter>();
if (liter)
{
isFlashing = liter.isFlashIng;
}
else
{
isFlashing = false;
}
if (isFlashing) //高亮即可触发事件
{
InputHandler inputHander = e.target.GetComponent<InputHandler>();
if (inputHander)
{
bool juedeHand = e.target.gameObject.layer == LayerMask.NameToLayer("CanGrab") && e.target.GetComponent<Rigidbody>();//手柄上有物体
if (!juedeHand)
{
inputHander.OnVRClick(Click.ray);
}
}
if (e.target.gameObject.layer == LayerMask.NameToLayer("NumBtn"))
{
string num = e.target.gameObject.GetComponent<NumBtnCtroller>().GetNum();
YIQIUIHandler._instances.ChangeWendu(num);
}
}
}
}
3 新版实现物体的抓取
1.手柄添加如下脚本
2.被抓物体添加如下脚本
抓取物体后可以设置物体的位置,指定某个点和向指定方向旋转
另外通过铰链也可以实现抓取,物体被抓时的高光颜色,边缘颜色