Unity3D HTC 完整开发过程详解
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Unity3D HTC 完整开发过程详解,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含12367字,纯文字阅读大概需要18分钟。
内容图文
- 下载和配置 StreamVR
- 处理控制器输入
- 在 VR 中和物理对象交互
- 创建一支激光笔
- 瞬移
- 一台支持 VR 的 Windows PC。
- 在机器上安装有 Unity 5.5 或更高版本。
- 一套完整的 HTC Vive 硬件,并配置和升级好软件。
- 安装 Steam 和 SteamVR。请参考 https://help.steampowered.com/zh-cn/,它将指引你完成硬件安装,并提供 Steam 和 SteamVR 的下载链接。
- 熟悉基本的 Unity 使用:[Introduction to Unity: Getting Started](Introduction to Unity: Getting Started)。
- 熟悉基本的脚本:https://www.raywenderlich.com/980-introduction-to-unity-scripting。
- Materials: 场景所用到的材质,包括蓝色小球。
// 1 private SteamVR_TrackedObject trackedObj; // 2 private SteamVR_Controller.Device Controller { get { return SteamVR_Controller.Input((int)trackedObj.index); } }
- 对正在被跟踪的对象进行一个引用。在这里,也就是一只手柄。
- Device 属性能够很方便地访问到这个手柄。通过所跟踪的对象的索引来访问控制器的 input,并返回这个 input。
void Awake() { trackedObj = GetComponent<SteamVR_TrackedObject>(); }
// 1 if (Controller.GetAxis() != Vector2.zero) { Debug.Log(gameObject.name + Controller.GetAxis()); } // 2if (Controller.GetHairTriggerDown()) { Debug.Log(gameObject.name + " Trigger Press"); } // 3if (Controller.GetHairTriggerUp()) { Debug.Log(gameObject.name + " Trigger Release"); } // 4if (Controller.GetPressDown(SteamVR_Controller.ButtonMask.Grip)) { Debug.Log(gameObject.name + " Grip Press"); } // 5if (Controller.GetPressUp(SteamVR_Controller.ButtonMask.Grip)) { Debug.Log(gameObject.name + " Grip Release"); }
- 获取手指在 touchpad 上的位置并输出到控制台。
- 当你按下扳机时,这会打印到控制台。扳机有一个专门的方法用于判断它是否被按下:GetHairTrigger(), GetHairTriggerDown() 和 GetHairTriggerUp()。
- 如果松开扳机,这会打印到控制台。
- 如果按下抓取(grip)键,这会打印到控制台。GetPressDown 方法是用于判断某个按钮已经被按下的标准方法。
- 如果释放抓取键,这会打印到控制台。GetPressUp 方法是用于判断某个按钮是否已经被释放的标准方法。
private SteamVR_TrackedObject trackedObj; private SteamVR_Controller.Device Controller { get { return SteamVR_Controller.Input((int)trackedObj.index); } } void Awake() { trackedObj = GetComponent<SteamVR_TrackedObject>(); }
private GameObject collidingObject; // 2 private GameObject objectInHand;
- 一个 GameObject,用于保存当前与之碰撞的触发器(trigger),这样你才能抓住这个对象。
- 一个 GameObject,用于保存玩家当前抓住的对象。
private void SetCollidingObject(Collider col) { // 1 if (collidingObject || !col.GetComponent<Rigidbody>()) { return; } // 2 collidingObject = col.gameObject; }
- 如果玩家已经抓着某些东西了,或者这个对象没有一个刚性体,则不要将这个 GameObject 作为可以抓取目标。
- 将这个对象作为可以抓取的目标。
// 1 public void OnTriggerEnter(Collider other) { SetCollidingObject(other); } // 2 public void OnTriggerStay(Collider other) { SetCollidingObject(other); } // 3 public void OnTriggerExit(Collider other) { if (!collidingObject) { return; } collidingObject = null; }、
- 当触发器碰撞体进入另一个碰撞体时,将另一个碰撞体作为可以抓取的目标。
- 和第一段类似(第一段注释 //1),但不同的是玩家已经将手柄放在一个对象上并持续一段时间。如果没有这段代码,碰撞会失败或者会导致异常。
- 当碰撞体退出一个对象,放弃目标,这段代码会将 collidingObject 设为 null 以删除目标对象。
private void GrabObject() { // 1 objectInHand = collidingObject; collidingObject = null; // 2var joint = AddFixedJoint(); joint.connectedBody = objectInHand.GetComponent<Rigidbody>(); } // 3private FixedJoint AddFixedJoint() { FixedJoint fx = gameObject.AddComponent<FixedJoint>(); fx.breakForce = 20000; fx.breakTorque = 20000; return fx; }
- 在玩家手中的 GameObject 转移到 objectInHand 中,将 collidingObject 中保存的 GameObject 移除。
- 添加一个连接对象,调用下面的 FixedJoint 方法将手柄和 GameObject 连接起来。
- 创建一个固定连接并加到手柄中,并设置连接属性,使它坚固,不那么容易断裂。最后返回这个连接。
private void ReleaseObject() { // 1 if (GetComponent<FixedJoint>()) { // 2 GetComponent<FixedJoint>().connectedBody = null; Destroy(GetComponent<FixedJoint>()); // 3 objectInHand.GetComponent<Rigidbody>().velocity = Controller.velocity; objectInHand.GetComponent<Rigidbody>().angularVelocity = Controller.angularVelocity; } // 4 objectInHand = null; }
- 确定控制器上一定有一个固定连接。
- 删除这个连接上所连的对象,然后销毁这个连接。
- 将玩家放开物体时手柄的速度和角度赋给这个物体,这样会形成了一个完美的抛物线。
- 将 objectInHand 变量置空。
// 1 if (Controller.GetHairTriggerDown()) { if (collidingObject) { GrabObject(); } } // 2 if (Controller.GetHairTriggerUp()) { if (objectInHand) { ReleaseObject(); } }
- 当玩家按下扳机,同时手上有一个可以抓取的对象,则将对象抓住。
- 当玩家松开扳机,同时手柄上连接着一个物体,则放开这个物体。
private SteamVR_TrackedObject trackedObj; private SteamVR_Controller.Device Controller { get { return SteamVR_Controller.Input((int)trackedObj.index); } } void Awake() { trackedObj = GetComponent<SteamVR_TrackedObject>(); }
// 1 public GameObject laserPrefab; // 2 private GameObject laser; // 3 private Transform laserTransform; // 4 private Vector3 hitPoint;
- 这个变量用于引用 Laser 预制件。
- 这个变量用于引用一个 Laser 实例。
- 一个 Transform 组件,方便后面适用。
- 激光击中的位置。
private void ShowLaser(RaycastHit hit) { // 1 laser.SetActive(true); // 2 laserTransform.position = Vector3.Lerp(trackedObj.transform.position, hitPoint, .5f); // 3 laserTransform.LookAt(hitPoint); // 4 laserTransform.localScale = new Vector3(laserTransform.localScale.x, laserTransform.localScale.y, hit.distance); }
- 显示激光。
- 激光位于手柄和投射点之间。我们可以用 Lerp 方法,这样我们只需要给它两个端点,以及一个距离百分比即可。如果我们设置这个百分比为 0.5,也就是 50%,这会返回一个中点的位置。
- 将激光照射到 hitPoint 的位置。
// 1 if (Controller.GetPress(SteamVR_Controller.ButtonMask.Touchpad)) { RaycastHit hit; // 2 if (Physics.Raycast(trackedObj.transform.position, transform.forward, out hit, 100)) { hitPoint = hit.point; ShowLaser(hit); } } else// 3{ laser.SetActive(false); }
- 如果 touchpad 被按下…
- 从手柄发射激光。如果激光照射到某样物体,保存射到的位置并显示激光。
- 当玩家放开 touchpad,隐藏激光。
// 1 laser = Instantiate(laserPrefab); // 2 laserTransform = laser.transform;
- 制造出一束新的激光,然后保存一个它的引用。
- 保存激光的 transform 组件。
// 1 public Transform cameraRigTransform; // 2 public GameObject teleportReticlePrefab; // 3 private GameObject reticle; // 4 private Transform teleportReticleTransform; // 5 public Transform headTransform; // 6 public Vector3 teleportReticleOffset; // 7 public LayerMask teleportMask; // 8 private bool shouldTeleport;
- 这是 [CameraRig] 的 transform 组件。
- 一个对传送标记预制件的引用。
- 一个传送标记实例的引用。
- 一个传送标记的 transform 的引用。
- 玩家的头(摄像机)的引用。
- 标记距离地板的偏移,以防止和其他平面发生“z-缓冲冲突”。
- 一个层遮罩,用于过滤这个地方允许什么东西传送。
- 如果为 true,表明找到一个有效的传送点。
if (Physics.Raycast(trackedObj.transform.position, transform.forward, out hit, 100))
if (Physics.Raycast(trackedObj.transform.position, transform.forward, out hit, 100, teleportMask))
// 1 reticle.SetActive(true); // 2 teleportReticleTransform.position = hitPoint + teleportReticleOffset; // 3 shouldTeleport = true;
- 显示传送标记。
- 移动传送标记到激光点到的地方,并添加一个偏移以免 z 缓冲冲突。
- 将 shouldTeleport 设为 true,表明找到了一个有效的瞬移位置。
reticle.SetActive(false);
private void Teleport() { // 1 shouldTeleport = false; // 2 reticle.SetActive(false); // 3 Vector3 difference = cameraRigTransform.position - headTransform.position; // 4 difference.y = 0; // 5 cameraRigTransform.position = hitPoint + difference; }
- 将 shouldTeleport 设为 false。表明传送进行中。
- 隐藏传送标记。
- 计算从玩家头盔到摄像机中心的坐标偏移。
- 将这个差中的 y 坐标设置为0,因为我们不考虑玩家头部有多高。
- 移动相机到照射点加上所算出来的坐标偏移。如果不加上这个偏移,玩家会传送到一个错误的地方。看下面的例子:
if (Controller.GetPressUp(SteamVR_Controller.ButtonMask.Touchpad) && shouldTeleport) { Teleport(); }
// 1 reticle = Instantiate(teleportReticlePrefab); // 2 teleportReticleTransform = reticle.transform;
- 创建一个标记点,并将它保存到 reticle 变量。
- 保存 reticle 的 transform 组件。
原文:https://www.cnblogs.com/zpy1993-09/p/14848619.html
内容总结
以上是互联网集市为您收集整理的Unity3D HTC 完整开发过程详解全部内容,希望文章能够帮你解决Unity3D HTC 完整开发过程详解所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。