HTC VIVE 基础开发1

news/2024/12/30 1:37:41/

此文章用于自己学习过程中的记录,以便日后翻阅


开发HTC VIVE 首先需要下载Steam 平台,然后在Steam的商店里搜索Steam VR下载安装就可以了。


创建新的Unity项目

创建一个新的Unity工程




下载Steam VR插件

打开unity的 Asset Store 




在Unity中的商店里搜索Steam vr插件


下载完成后点击Import按钮




将下载好的Steam VR插件全部导入到新的Unity工程中



导入中会有绿色的读条,如果导入完成后弹出API Update Required,这是在提示你API更新,可以不用管他,点击No Thanks即可。(原因应该是Steam VR 插件的版本不是最新的)


等待SteamVr_Settings弹出后点击Accept All。到这里导入就完成了



实现对手柄的控制

打开SteamVR_LaserPointer,在这里实现对激光笔的控制功能,首先把SteamVR_LaserPointer

Ctrl+d 复制一份,然后再该脚本的基础上进行修改


新建一个文件夹命名为Script,把SteamVR_LaserPointer脚本重命名为LaserPointer,然后拖入新建的Script文件夹中


进入LaserPointer脚本,然后修改类名为LaserPointer



删除掉选中的蓝色部分,然后保存



制作激光笔选中的目标点




在void Update 找到代码判断的语句进行扩充,并执行Hit判断,把Hit到的点存到刚刚创建的HitPoint变量中


在SteamVr文件夹中找到Prefabs文件夹然后把CameraRig放到场景中去


在场景中用Cube搭建一个简单的房间,然后把CameraRig的位置进行调整


展开CameraRig,选择Controller(left)对左手的手柄进行控制操作


给Controller(left)添加修改的Laser Point 赋予给CameraRig和SteamVR_TrackedController

然后去掉TrackSteamVR_Tracked Object



到了这一步,如果你的HTC VIVE设备调试正确,那就能在Unity的场景中看到他们了。






创建传送的脚本

创建Teleport

复制脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Teleport : MonoBehaviour {//手柄的引用public GameObject Left;//储存一些变量LaserPointer LP_Left;SteamVR_TrackedController ST_Left;Transform CurrentTransform;// Use this for initializationvoid Start () {//初始化变量  注册监听  获取激光笔和控制器LP_Left = Left.GetComponent<LaserPointer>();ST_Left = Left.GetComponent<SteamVR_TrackedController>();LP_Left.PointerIn += LeftPointIn;//手柄指向事件LP_Left.PointerOut += LeftPointOut;//手柄取消事件ST_Left.TriggerClicked += TriggerClicked;//手柄扳机事件}//手柄有物体指向void  LeftPointIn(object sender,PointerEventArgs e){//当有物体指向  设置变量标识CurrentTransform = e.target;}//取消指向void LeftPointOut(object sender,PointerEventArgs e){//取消指向事件 变量标识设置为空CurrentTransform = null;}void TriggerClicked(object sender,ClickedEventArgs e){//当指向不为空的时候,进行移动if (CurrentTransform != null){TeleportPosition(LP_Left.HitPoint);}}//移动的方法private void TeleportPosition(Vector3 targetPosition){this.gameObject.transform.position = new Vector3(targetPosition.x - Left.transform.localPosition.x, targetPosition.y, targetPosition.z - Left.transform.localPosition.z);}// Update is called once per framevoid Update () {}
}


赋予Teleport脚本给CameraRig组件,然后把Controller(left)赋值到Left



到这一步就完成了传送功能




实现多场景加载

创建一个新的Check脚本用来检测


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class Check : MonoBehaviour {//检测 条件完成 达到时 隐藏public GameObject _Object;// 加载场景名字public string SceneName;//异步加载控制器AsyncOperation _AsyncOperation;private void OnTriggerEnter(Collider other){//当检测到碰撞时 检查碰撞物体是不是主相机  如果是进行场景加载  对__AsyncOperation赋值  进行标记if (other.tag == "MainCamera" && _AsyncOperation == null){_AsyncOperation = SceneManager.LoadSceneAsync(SceneName, LoadSceneMode.Additive);}}// Use this for initializationvoid Start () {}// Update is called once per framevoid FixedUpdate () {//通过_AsyncOperation.isDone 来检测场景是否加载完成  如果加载完成 就隐藏特殊物体 来展现新的场景 同时避免再度触发碰撞进行场景加载if (_AsyncOperation!=null && _AsyncOperation.isDone){_AsyncOperation = null;_Object.SetActive(false);}}
}

把Check 赋予给一面墙(创建一个CUBE拉成一面墙的样子,既点击墙面之后跳转的场景),然后对这个墙壁添加BoxCollider组件,BoxCollider组件大小为包裹住墙壁。然后勾选IsTrigger(勾上代表触发器)





在CameraRig上的Camera(eye)上添加BoxCollider 组件,同意勾选上IsTrigger 选项


然后添加Rigidbody组件取消勾选UseGravity



创建场景管理

创建一个新的脚本 Manager 用来管理你的场景

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Manager : MonoBehaviour {public static Manager Instance;Check CurrentCheck;private void Awake(){if (Instance == null){Instance = this;}else{Debug.LogError("不能重复创建Manager");}}public void StartNewScene(Check _Check){//检测当前是否有场景加载 如果没有将调用对象设置为currentCheckif (CurrentCheck == null){CurrentCheck = _Check;}else if (CurrentCheck != _Check)//如果有  就调用CurrentCheck.Reset方法重置 并且更新CurrentCheck调用{CurrentCheck.Reset();CurrentCheck = _Check;}}}

回到Check脚本,添加两行新的代码


然后在Check脚本中添加Reset方法


回到Unity里创建一个GameObject,然后把它的位置Reset,重命名为Manager,然后把Manager脚本挂上去


现在不会两个场景一起显示了,只会显示其中一个

到这里就完成了场景卸载的功能




制作不可传送区域

需要对传送进行限制,例如不能传送到界外,或者不能传送到屋顶或者水里了

例如把水面设置为不可传送区域,在搜索栏中搜索命名为water的所有模型(前提是你的模型的名字为water,如果是别的就搜索你模型的名字)



然后把Layer层的Default全部设置为Ignore Raycast


到这里就无法选择水面进行移动了。但是还没有明显的禁止移动提示。

接下来需要把禁止移动的提示制作的更明显

打开LaserPoint脚本进行编辑,需要先添加一个Material 来控制射线的颜色


因为上面定义了新的Material ,所以把下面的删掉


在指向判断这里添加新的更改,把可以只想设置为绿色,否则设置为红色



到这里就完成了点击不可传送地区射线变红的功能


制作抛物线---把激光笔的直线更改为抛物线


创建一个新的脚本parabola

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Parabola : MonoBehaviour {//发射器位置public Transform ShootTransform;//起点public Vector3 StartPosition;//终点public Vector3 EndPosition;//重力加速度public float GravitationalAcceleration = 10;//绘制节点数量public int LineNodeNum = 10;//绘制抛物线public LineRenderer Line;Vector3[] Position;// Use this for initializationvoid Start () {//初始化线段绘制节点Position = new Vector3[LineNodeNum];//设置定点数量Line.SetVertexCount(LineNodeNum);}Vector3 GetPlaneVector(Vector3 v3){return new Vector3(v3.x, 0, v3.z);}// Update is called once per framevoid FixedUpdate () {//更新发射点的位置(曲线)ShootTransform.position = this.transform.position;ShootTransform.rotation = Quaternion.Euler(this.transform.rotation.eulerAngles.x - 30, this.transform.rotation.eulerAngles.y, 0);//当结束点为0但没有结束点的时候 将线段恢复为直线if (EndPosition == Vector3.zero){ResetLine();return;}StartPosition = ShootTransform.position;//计算出水平和垂直上的位移float Sx = Vector3.Distance(GetPlaneVector(EndPosition), GetPlaneVector(StartPosition));float Sy = StartPosition.y - EndPosition.y;//计算出垂直方向和水平方向上的初始速度比值float tanA = -ShootTransform.forward.y / Vector3.Distance(Vector3.zero, GetPlaneVector(ShootTransform.forward));//计算运动时间float t = Mathf.Sqrt((2 * Sy - 2 * Sx * tanA) / GravitationalAcceleration);if(float.IsNaN(t)){ResetLine();return;}//推导出水平和垂直的初速度float Vx = Sx / t;float Vy = Vx * tanA;//绘制出线段float FirstLineNodeTime = t / LineNodeNum;Position[8] = StartPosition;for (int i = 1; i < LineNodeNum; i++){float xz = GetX(Vx, FirstLineNodeTime * (i + 1));float y = GetY(FirstLineNodeTime * (i + 1), Vy);Position[i] = Vector3.Normalize(GetPlaneVector(ShootTransform.forward)) * xz + Vector3.down * y + ShootTransform.position;}Line.SetPositions(Position);}/// <summary>/// 计算水平方向的位移/// </summary>/// <param name="Speed">水平方向初速度</param>/// <param name="time">时间</param>/// <returns></returns>private float GetX(float Speed,float time){float X = Speed * time;return X;}/// <summary>/// 计算垂直方向的位移/// </summary>/// <param name="time">时间</param>/// <param name="SpeedDownFloat">垂直方向的初速度</param>/// <returns></returns>private float GetY(float time,float SpeedDownFloat){float Y = (float)(SpeedDownFloat * time + 0.5 * GravitationalAcceleration * time * time);return Y;}void  ResetLine(){for (int i = 0; i < LineNodeNum; i++){Position[i] = transform.forward * i + transform.position;Line.SetPositions(Position);}}}













回到LaserPointer脚本里去抛物线的处理












创建一个GameObject命名为Shooter,再创建一个命名为ShootLine



对ShootLine添加Line Renderer组件,然后创建一个材质球赋予它(颜色随意)



找到Controller (left)添加刚刚写好的抛物线脚本,然后把刚刚的Shooter、ShootLine指定过来


可以增加LineNodeNum的节点数让抛物线更平滑

到这里就实现了抛物线


这时由于激光笔自带的射线和制作的抛物线同时存在,需要把内置的直线取消掉,打开LaserPointer脚本注销掉所有pointer相关的代码







全部注销后激光笔内置的直线就消失了,只剩下抛物线。

启用单例模式制作抛物线颜色

在Parabola脚本中添加一个新的单例模式 用来改变抛物线的颜色




回到LaserPointer脚本,在指向判断处添加控制颜色的代码


回到Unity运行测试,如果可以移动的抛物线则为绿色,否则为红色直线-------文章结束


http://www.ppmy.cn/news/339274.html

相关文章

HTC Vive实现开关门(VRTK版)

开关门这类操作在Htc Vive中是常用的操作&#xff0c;其中使用动画实现功能是最直接方便的&#xff0c;今天给大家分享下用Joint实现开关门的方法。 看完这篇文章相信对所有绕轴旋转的操作问题&#xff0c;你都可以解决。 废话不多说&#xff0c;直接打开场景 场景中的物体如…

HTC教程

在微软IE 5.0版本的浏览器发布以前&#xff0c;网页编程中面对的最大挑战就是不能轻易地创建组件&#xff0c;以达到代码重用和多页面共享的目的。这个问题一直困扰着DHTML&#xff08;动态 HEML&#xff09;的网页编程者。他们只能不断地重复书写HTML、CSS和javascript的代码&…

HTC VIVE UI框架

在开发VR过程中 UI点击用射线检测&#xff0c;改写了SteamVR_LaserPointer类。 目标实现 PointerIn&#xff0c;PointerOut&#xff0c;ClickedDown&#xff0c;Clicking&#xff0c;ClickedUp。 用的是手柄的Trigger VR UI SteamVR_LaserPointer 类改写 // Copyright (c) …

HTC简介

HTC简介 作者&#xff1a;闪吧 类型:原创 来源:闪吧 src"http://www2.flash8.net/teach/teachInfo.aspx?id4017" style"margin: 0pt; padding: 0pt; width: 400px; height: 25px;" frameborder"0" scrolling"no"> HTC是 HTML…

简单的json解析工具

json解析有太多的工具&#xff0c;例如gson&#xff0c;jackson等等&#xff0c;如果做一般的app都可以轻松导入&#xff0c;可是有一个问题&#xff0c;就是太大了&#xff0c;而且对于做第三方sdk项目的人来说&#xff0c;还可能出现重复。例如项目A要引用项目B&#xff0c;B…

2020中国汽车后市场白皮书

今日看点 ✦ 腾讯云&#xff1a;云开发日调用超7亿次&#xff0c;推出云开发低代码平台 ✦ 百度网盘&#xff1a;用户规模破7亿&#xff0c;数据存储总量超1000亿GB ✦ 蔚来汽车成立6周年&#xff1a;累计车主超6万人&#xff0c;开设门店186家 ✦ 凯撒集团完成京东所持途牛股份…

蔚来、吉利纷纷加码,新能源汽车换电模式按下加速键

随着碳中和目标的提出及相关政策的落地&#xff0c;以换代充的换电时代正向我们悄然走来。 在更为便捷、轻巧的电动车领域&#xff0c;易马达e换电、中国铁塔、易骑、宇谷科技、小哈换电等成为换电之路的先行者&#xff0c;后又有爱玛携手AI换电步入换电赛道、雅迪推出爱换换换…

macbook 连接不上蓝牙鼠标 m585 m590 解决方法

鼠标切换到1&#xff0c;然后一直按那圆按钮&#xff0c;按了得15秒以上&#xff0c;放开还是一直闪个不停&#xff0c;这时别再动鼠标了&#xff0c;直接电脑连接&#xff0c;然后就连上了。 已连接后右边可能还是一直转圈&#xff0c;这个不用理会。 亲测有效 原文&#xf…