steamvr怎么换中文自身的瞬移怎么用

后使用我的收藏没有帐号?
所属分类: &
查看: 7|回复: 0
steamvr自身的瞬移怎么用
发表于 4&小时前
steamvr自身的瞬移怎么用
点这里&&&&
抢先预约赢丑萌好礼!关于StEAmVR的相关帖子
1 个回复 - 58 次查看
8 个回复 - 531 次查看
17 个回复 - 459 次查看
1 个回复 - 83 次查看
2 个回复 - 141 次查看
6 个回复 - 234 次查看
7 个回复 - 93 次查看
7 个回复 - 432 次查看
6 个回复 - 190 次查看
1 个回复 - 212 次查看
0 个回复 - 101 次查看
0 个回复 - 202 次查看
9 个回复 - 2801 次查看
2 个回复 - 722 次查看
2 个回复 - 1541 次查看
0 个回复 - 1313 次查看
10 个回复 - 939 次查看
1 个回复 - 326 次查看
0 个回复 - 202 次查看
16 个回复 - 1564 次查看
12 个回复 - 907 次查看
4 个回复 - 250 次查看
8 个回复 - 2472 次查看1444人阅读
VR开发专栏(6)
从这一节起我开始介绍一些vive的交互实现方式,比如手柄发出的射线,凝视,瞬移等等。SteamVR插件内都有这三种交互的辅助类。
Extras文件夹里面的SteamVR_GazeTracker是凝视的工具类,SteamVR_LaserPointer是射线的工具类,SteamVR_Teleporter是瞬移的工具类,下面我们来分析这三种交互是如何实现的。
SteamVR_GazeTracker(凝视)
凝视是一种在没有手柄等输入设备的情况下,可以通过眼睛盯着某个物体看来与物体进行交互的体验。
我们只需要将个辅组类添加到我们想要凝视的物体上,比如菜单等,就可以实现凝视的功能。现在我们来看看凝视的实现原理。
void Update ()
if (hmdTrackedObject == null)
SteamVR_TrackedObject[] trackedObjects = FindObjectsOfType&SteamVR_TrackedObject&();
foreach (SteamVR_TrackedObject tracked in trackedObjects)
if (tracked.index == SteamVR_TrackedObject.EIndex.Hmd)
hmdTrackedObject = tracked.
if (hmdTrackedObject)
Ray r = new Ray(hmdTrackedObject.position, hmdTrackedObject.forward);
Plane p = new Plane(hmdTrackedObject.forward, transform.position);
float enter = 0.0f;
if (p.Raycast(r, out enter))
Vector3 intersect = hmdTrackedObject.position + hmdTrackedObject.forward *
float dist = Vector3.Distance(intersect, transform.position);
if (dist & gazeInCutoff && !isInGaze)
isInGaze = true;
GazeEventA
e.distance =
OnGazeOn(e);
else if (dist &= gazeOutCutoff && isInGaze)
isInGaze = false;
GazeEventA
e.distance =
OnGazeOff(e);
通过上面的代码我们知道了凝视的原理实际上是从头盔的位置发出一条射线判断是否与物体相交来做选中或者交互的。而且因为凝视的精确度不高,所以没有做直接与物体相交,而是在物体的位置创建了一个平面,通过射线与平面相交的交点的位置与物体的距离来大概判断的。这个距离值是可以调的,缺省是0.15到0.4米之间就算选中了。
我们现在知道了凝视的交互是如何实现的,实现的方式其实还是挺简单的,下面我们在来看看射线这种交互方式。
SteamVR_LaserPointer(激光束)
SteamVR_LaserPointer的作用是从指定位置(通常是手柄)发出一条射线,它会将这条射线显示出来,然后也是判断这条视线与场景中的物体是否相交。与凝视不一样的是,它可以精确操作,所以不需要一个辅助平面。用法和凝视也不太一样,需要将这个组件添加发出射线的物体上,比如手柄。
我们来分析一下这个类的代码
public struct PointerEventArgs
public uint controllerI
public uint
public float
public delegate void PointerEventHandler(object sender, PointerEventArgs e);
public class SteamVR_LaserPointer : MonoBehaviour
public float thickness = 0.002f;
public GameO
public GameO
bool isActive = false;
public bool addRigidBody = false;
public event PointerEventHandler PointerIn;
public event PointerEventHandler PointerO
Transform previousContact = null;
void Start ()
holder = new GameObject();
holder.transform.parent = this.
holder.transform.localPosition = Vector3.
pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
pointer.transform.parent = holder.
pointer.transform.localScale = new Vector3(thickness, thickness, 100f);
pointer.transform.localPosition = new Vector3(0f, 0f, 50f);
BoxCollider collider = pointer.GetComponent&BoxCollider&();
if (addRigidBody)
if (collider)
collider.isTrigger = true;
Rigidbody rigidBody = pointer.AddComponent&Rigidbody&();
rigidBody.isKinematic = true;
if(collider)
Object.Destroy(collider);
Material newMaterial = new Material(Shader.Find("Unlit/Color"));
newMaterial.SetColor("_Color", color);
pointer.GetComponent&MeshRenderer&().material = newM
public virtual void OnPointerIn(PointerEventArgs e)
if (PointerIn != null)
PointerIn(this, e);
public virtual void OnPointerOut(PointerEventArgs e)
if (PointerOut != null)
PointerOut(this, e);
void Update ()
if (!isActive)
isActive = true;
this.transform.GetChild(0).gameObject.SetActive(true);
float dist = 100f;
SteamVR_TrackedController controller = GetComponent&SteamVR_TrackedController&();
Ray raycast = new Ray(transform.position, transform.forward);
bool bHit = Physics.Raycast(raycast, out hit);
if(previousContact && previousContact != hit.transform)
PointerEventArgs args = new PointerEventArgs();
if (controller != null)
args.controllerIndex = controller.controllerI
args.distance = 0f;
args.flags = 0;
args.target = previousC
OnPointerOut(args);
previousContact = null;
if(bHit && previousContact != hit.transform)
PointerEventArgs argsIn = new PointerEventArgs();
if (controller != null)
argsIn.controllerIndex = controller.controllerI
argsIn.distance = hit.
argsIn.flags = 0;
argsIn.target = hit.
OnPointerIn(argsIn);
previousContact = hit.
previousContact = null;
if (bHit && hit.distance & 100f)
dist = hit.
if (controller != null && controller.triggerPressed)
pointer.transform.localScale = new Vector3(thickness * 5f, thickness * 5f, dist);
pointer.transform.localScale = new Vector3(thickness, thickness, dist);
pointer.transform.localPosition = new Vector3(0f, 0f, dist/2f);
看完了SteamVR_LaserPointer的代码,我们就知道了激光束实现的原理,其实激光束实现起来还是蛮简单的,但是在VR的交互中,使用起来非常的方便。
好了,我们接下来再看看最后一种交互方式,瞬移。
SteamVR_Teleporter(瞬移)
我们只需要将这个脚本添加到手柄上就能使用瞬移功能,这个类的面板如下图
可以看到,它只有两个可控制的参数
Teleport On Click:表示是否激活按扳机键瞬移功能
Teleport Type:瞬移类型,有三种
Teleport Type Use Terrain:表示在地形上做瞬移,地形有高低的区别
Teleport Type Use Collider:表示与场景中的任何碰撞体做相交瞬移
eleport Type Use Zero Y:表示在Y方向0坐标的平面上做瞬移,当地面为平面时可以使用
同样,我们再来分析瞬移的源码,为了精简,一些不太核心的源码我直接省去了
public class SteamVR_Teleporter : MonoBehaviour
Transform reference
var top = SteamVR_Render.Top()
return (top != null) ? top.origin : null
void Start ()
var trackedController = GetComponent&SteamVR_TrackedController&()
if (trackedController == null)
trackedController = gameObject.AddComponent&SteamVR_TrackedController&()
trackedController.TriggerClicked += new ClickedEventHandler(DoClick)
if (teleportType == TeleportType.TeleportTypeUseTerrain)
var t = reference
if (t != null)
t.position = new Vector3(t.position.x, Terrain.activeTerrain.SampleHeight(t.position), t.position.z)
void DoClick(object sender, ClickedEventArgs e)
if (teleportOnClick)
var t = reference
if (t == null)
float refY = t.position.y
Plane plane = new Plane(Vector3.up, -refY)
Ray ray = new Ray(this.transform.position, transform.forward)
bool hasGroundTarget = false
float dist = 0f
if (teleportType == TeleportType.TeleportTypeUseTerrain)
RaycastHit hitInfo
TerrainCollider tc = Terrain.activeTerrain.GetComponent&TerrainCollider&()
hasGroundTarget = tc.Raycast(ray, out hitInfo, 1000f)
dist = hitInfo.distance
else if (teleportType == TeleportType.TeleportTypeUseCollider)
RaycastHit hitInfo
Physics.Raycast(ray, out hitInfo)
dist = hitInfo.distance
hasGroundTarget = plane.Raycast(ray, out dist)
if (hasGroundTarget)
Vector3 headPosOnGround = new Vector3(SteamVR_Render.Top().head.localPosition.x, 0.0f, SteamVR_Render.Top().head.localPosition.z)
t.position = ray.origin + ray.direction * dist - new Vector3(t.GetChild(0).localPosition.x, 0f, t.GetChild(0).localPosition.z) - headPosOnGround
我们可以看到,瞬移的核心不是怎么移过去,而是如何确定瞬移的目标位置,确定了移动的目标位置后再将Camera的position设置成目标位置就行了,瞬移的难点在于对不同地形的处理。
现在我们已经知道这三种交互方式的用法和原理了,在VIVE的开发中,这三种交互是很常见的。同样,我们也可以根据这几种交互的实现原理,设计出我们自己想要的交互。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6217次
排名:千里之外
原创:11篇
(1)(2)(5)(3)

我要回帖

更多关于 怎么卸载steamvr 的文章

 

随机推荐