目前htc交互比较主流的还是那个实体射线交互,工具包自带的三种:
GetComponent().DestinationMarkerEnter
GetComponent().DestinationMarkerExit
GetComponent().DestinationMarkerSet
工具包自带的三种交互使用起来不太灵活,自己在VRTK_SimplePointer基础上拓展了一点功能,这里提供一个简单的例子:

废话不多说直接上:
public class Msg_PointTrigger
{
public const string PointEnterMsg = "EnterTrigger";
public const string PointStayDownMsg = "PointStayDownMsg";
public const string PointStayUpMsg = "PointStayUPMsg";
public const string PointExittMsg = "ExittMsg";
}
1、这是Base模版,大概思路是,触发后根据消息解析做出相应处理,还是比较灵活的。
public class SteamVR_PointTriggerBase : MonoBehaviour {
public SteamVR_TrackedObject rightTracket;
public SteamVR_TrackedObject leftTracket;
public Transform rightPoint;
public Transform leftPoint;
protected string msg;
public virtual void Trigger(string msg)
{
this.msg = msg;
ExplainMSg();
}
private void ExplainMSg()
{
switch (msg)
{
case Msg_PointTrigger.PointEnterMsg :
OnPointEnter();
break;
case Msg_PointTrigger.PointStayDownMsg:
OnPointStayDown();
break;
case Msg_PointTrigger.PointStayUpMsg:
OnPointStayUp();
break;
case Msg_PointTrigger.PointExittMsg:
OnExitState();
break;
default:
break;
}
}
protected virtual void OnPointEnter() { Debug.Log("OnPointEnter"); }
protected virtual void OnPointStayDown()
{
EffectHighting.AddConstantHighting(gameObject);
if (null!=rightTracket)
{
SteamVR_Controller.Device rightDevice = SteamVR_Controller.Input((int)rightTracket.index);
if (rightDevice.GetTouch(SteamVR_Controller.ButtonMask.Trigger))
{
Debug.Log("右手Triger按下");
OnPointStayDownRightTriggerTouch();
}
}
if (null!=leftTracket)
{
SteamVR_Controller.Device leftDevice = SteamVR_Controller.Input((int)leftTracket.index);
if (leftDevice.GetTouch(SteamVR_Controller.ButtonMask.Trigger))
{
Debug.Log("左手Triger按下");
OnPointStayDownLeftTriggerTouch();
}
}
}
protected virtual void OnPointStayDownRightTriggerTouch() { }
protected virtual void OnPointStayDownLeftTriggerTouch() { }
protected virtual void OnPointStayUp() { Debug.Log("OnPointStayUp"); }
protected virtual void OnExitState() {EffectHighting.ResetRemoveHightingEffect();Debug.Log("OnExitState"); }
2、使用的例子:
如我写的一个控制灯的开关的功能,只需要利用其中一种就可以了:
public class SteamVR_PointTriggerLights : SteamVR_PointTriggerBase
{
public bool isOn = false;
public void TrunColor(Color openColor, Color closeColor)
{
if (isOn)
{
gameObject.GetComponent<MeshRenderer>().material.color = openColor;
}
else
{
gameObject.GetComponent<MeshRenderer>().material.color = closeColor; ;
}
}
private void TurnLights(bool isOn)
{
PointLightControler.instance.TurnLights(isOn);
}
protected override void OnPointEnter()
{
base.OnPointEnter();
}
protected override void OnPointStayDown()
{
base.OnPointStayDown();
}
protected override void OnPointStayDownRightTriggerTouch()
{
base.OnPointStayDownRightTriggerTouch();
}
protected override void OnPointStayDownLeftTriggerTouch()
{
base.OnPointStayDownLeftTriggerTouch();
}
protected override void OnPointStayUp()
{
base.OnPointStayUp();
isOn = !isOn;
TrunColor(Color.green, Color.red);
TurnLights(isOn);
Debug.Log("OnPointStayUp");
}
protected override void OnExitState()
{
base.OnExitState();
}
}
3、下面是改写的VRTK_SimplePointer,临时改的,还没有优化过,后期可以补上,思路就是利用射线检测判断一些情况的逻辑,主要是改了Update方法,附上参考一下
protected override void Update()
{
base.Update()
if (pointer.gameObject.activeSelf)
{
RaycastHit pointerCollidedWith
Ray pointerRaycast = new Ray(transform.position, transform.forward)
var rayHit = Physics.Raycast(pointerRaycast, out pointerCollidedWith, pointerLength, ~layersToIgnore)
var pointerBeamLength = GetPointerBeamLength(rayHit, pointerCollidedWith)
SetPointerTransform(pointerBeamLength, pointerThickness)
//增加射线触发事件
//是否检测到物体
if (null!=pointerCollidedWith.collider)
{
selectObj = pointerCollidedWith.collider.gameObject
}
else
{
if (null!=selectObj)
{
if (null != selectObj.GetComponent<SteamVR_PointTriggerBase>())
{
selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointExittMsg)
}
}
selectObj = null
canEnter = true
}
//当检检测到物体时
if (null != selectObj)
{
//物体是VR交互物体
if (null != selectObj.GetComponent<SteamVR_PointTriggerBase>())
{
if (canEnter)
{
canEnter = false
if (transform.root.GetComponent<SteamVR_ControllerManager>().right.activeSelf)
{
selectObj.GetComponent<SteamVR_PointTriggerBase>().rightTracket = transform.root.GetComponent<SteamVR_ControllerManager>().right.GetComponent<SteamVR_TrackedObject>()
selectObj.GetComponent<SteamVR_PointTriggerBase>().rightPoint = pointerTip.transform
//Debug.Log(pointerTip.transform.position)
}
if (transform.root.GetComponent<SteamVR_ControllerManager>().left.activeSelf)
{
selectObj.GetComponent<SteamVR_PointTriggerBase>().leftTracket = transform.root.GetComponent<SteamVR_ControllerManager>().left.GetComponent<SteamVR_TrackedObject>()
selectObj.GetComponent<SteamVR_PointTriggerBase>().leftPoint = pointerTip.transform
}
selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointEnterMsg)
}
selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointStayDownMsg)
}
}
}
else
{
if (null != selectObj)
{
if (null != selectObj.GetComponent<SteamVR_PointTriggerBase>())
{
selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointStayUpMsg)
selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointExittMsg)
selectObj = null
}
}
}
}
|