当前位置: 首页 > news >正文

广州番禺网站建设公司黄页网

广州番禺网站建设公司,黄页网,外贸网站建站方案,星星wordpress模板Unity VR 场景手柄交互实现方案 需求 在已创建好的 Unity VR 场景中,接入游戏手柄,通过结合动捕系统与 VRPN,建立刚体,实时系统获取到手柄的定位数据与按键数据,通过编写代码实现手柄的交互逻辑,实现手柄…

Unity VR 场景手柄交互实现方案

需求

在已创建好的 Unity VR 场景中,接入游戏手柄,通过结合动捕系统与 VRPN,建立刚体,实时系统获取到手柄的定位数据与按键数据,通过编写代码实现手柄的交互逻辑,实现手柄抓起物体移动放置。

演示视频

在这里插入图片描述

资源工程附件

(评论区回复:VR交互)

实现方案

1. 控制抓取物体的平移运动(不考虑旋转)

仅控制抓取物体的前后上下左右方向的平移运动,不考虑手柄的旋转

using UnityEngine;
using UVRPN.Core;public class HandleInteraction : MonoBehaviour
{public LayerMask targetLayer; // 目标物体所在的层public float rayLength = 5f; // 射线的长度private GameObject selectedObject; // 当前选中的物体private Vector3 offset; // 物体与手柄的相对位置private bool isHoldingObject = false; // 是否正在抓取物体的标志private VRPN_Button vrpnButton; // VRPN_Button 组件的引用void Start(){vrpnButton = GetComponent<VRPN_Button>();// 或者,如果 VRPN_Button 组件在其他 GameObject 上// vrpnButton = GameObject.Find("GameObjectName").GetComponent<VRPN_Button>();}// Update is called once per framevoid Update(){// 发射射线Ray ray = new Ray(transform.position, -transform.forward);RaycastHit hit;// 如果射线击中了目标层上的物体if (Physics.Raycast(ray, out hit, rayLength, targetLayer)){Debug.DrawLine(ray.origin, hit.point, Color.red); // 绘制射线(仅在 Scene 视图中可见)// 检测手柄按钮是否被按下if (vrpnButton.ButtonDown){// 抓取物体selectedObject = hit.collider.gameObject;offset = selectedObject.transform.position - transform.position;isHoldingObject = true;}}// 如果当前有选中的物体,并且手柄按钮仍然被按住if (isHoldingObject && vrpnButton.ButtonHold){// 移动物体,使其保持与手柄的相对位置selectedObject.transform.position = transform.position + offset;}// 如果手柄按钮被松开if (isHoldingObject && vrpnButton.ButtonUp){// 放置物体isHoldingObject = false;selectedObject = null;}}
}

2. 考虑手柄的旋转处理

将选中物体与手柄作为整体,同时增加重力响应与Game视图中的射线渲染

using UnityEngine;
using UVRPN.Core;public class HandleMove : MonoBehaviour
{public LayerMask targetLayer; // 目标物体所在的层public float rayLength = 5f; // 射线的长度public float lineWidth = 0.01f; // 线条宽度    private GameObject selectedObject; // 当前选中的物体private Vector3 originalLocalPosition; // 物体相对于手柄的初始局部位置private Quaternion originalLocalRotation; // 物体相对于手柄的初始局部旋转private VRPN_Button vrpnButton; // VRPN_Button 组件的引用private Rigidbody rigidbody; // 选中物体的刚体组件private LineRenderer lineRenderer; // Game视图中的射线渲染void Start(){vrpnButton = GetComponent<VRPN_Button>();lineRenderer = GetComponent<LineRenderer>();// 设置 LineRenderer 的宽度lineRenderer.startWidth = lineWidth;lineRenderer.endWidth = lineWidth;lineRenderer.enabled = false;}void Update(){// 发射射线Ray ray = new Ray(transform.position, -transform.forward);RaycastHit hit;// 如果射线击中了目标层上的物体if (Physics.Raycast(ray, out hit, rayLength, targetLayer)){Debug.DrawLine(ray.origin, hit.point, Color.red); // 绘制射线(仅在 Scene 视图中可见)// 启用 Line Renderer 并设置位置lineRenderer.enabled = true;lineRenderer.SetPosition(0, ray.origin);lineRenderer.SetPosition(1, hit.point);// 检测手柄按钮是否被按下if (vrpnButton.ButtonDown && !selectedObject){// 抓取物体selectedObject = hit.collider.gameObject;selectedObject.transform.SetParent(transform, true); // 将物体设置为手柄的子对象// 禁用物理引擎响应rigidbody = selectedObject.GetComponent<Rigidbody>();if (rigidbody){rigidbody.isKinematic = true;}// 记录物体相对于手柄的初始局部位置和旋转originalLocalPosition = selectedObject.transform.localPosition;originalLocalRotation = selectedObject.transform.localRotation;}}else{// 如果射线没有击中任何物体,禁用 Line RendererlineRenderer.enabled = false;}// 如果手柄按钮被松开if (vrpnButton.ButtonUp && selectedObject){// 放置物体selectedObject.transform.SetParent(null); // 移除物体的父对象selectedObject.transform.position = transform.TransformPoint(originalLocalPosition); // 重置物体的世界位置selectedObject.transform.rotation = transform.rotation * originalLocalRotation; // 重置物体的世界旋转selectedObject = null;// 启用物理引擎响应if (rigidbody){rigidbody.isKinematic = false;}}}
}

3. 正确处理 VRPN 的坐标转换关系

坐标系转换的原理

已知动捕坐标系(右手)与 Unity 坐标系(左手),转动到同一视角将坐标系对齐如下:

3.1 动捕 Y-UP

即两坐标系 X 轴反向。
在这里插入图片描述
在这里插入图片描述

3.2 动捕 Z-UP

即 Z 与 Y 对调。

注意:转换的方式不止一种,这里选择比较方便的处理方式。
在这里插入图片描述
在这里插入图片描述

3.3 解决坐标系转换问题
1.通过 VRPN 反转设置
  1. 若动捕 Y 轴向上
    在这里插入图片描述

  2. 若动捕Z轴向上
    不支持

2.通过修改 VRPN 脚本(编辑 VRPN_NativeBridge.cs),实现坐标系转换
  1. 若动捕 Y 轴向上
internal static Vector3 TrackerPos(string address, int channel)
{return new Vector3(-(float)vrpnTrackerExtern(address, channel, 0, Time.frameCount),(float)vrpnTrackerExtern(address, channel, 1, Time.frameCount),(float)vrpnTrackerExtern(address, channel, 2, Time.frameCount));
}internal static Quaternion TrackerQuat(string address, int channel)
{return new Quaternion(-(float)vrpnTrackerExtern(address, channel, 3, Time.frameCount),(float)vrpnTrackerExtern(address, channel, 4, Time.frameCount),(float)vrpnTrackerExtern(address, channel, 5, Time.frameCount),-(float)vrpnTrackerExtern(address, channel, 6, Time.frameCount));
}
  1. 若动捕 Z 轴向上
internal static Vector3 TrackerPos(string address, int channel)
{return new Vector3((float)vrpnTrackerExtern(address, channel, 1, Time.frameCount),(float)vrpnTrackerExtern(address, channel, 2, Time.frameCount),-(float)vrpnTrackerExtern(address, channel, 0, Time.frameCount));
}internal static Quaternion TrackerQuat(string address, int channel)
{return new Quaternion((float)vrpnTrackerExtern(address, channel, 3, Time.frameCount),(float)vrpnTrackerExtern(address, channel, 5, Time.frameCount),(float)vrpnTrackerExtern(address, channel, 4, Time.frameCount),-(float)vrpnTrackerExtern(address, channel, 6, Time.frameCount));
}
3.4 创建刚体时的朝向,下面以Y轴向上为例进行讲解通用的处理方式
  1. 打开VR_box的空间交互场景

  2. 选中手柄,按W键进行Move状态,点击工具栏上的Toggle Tool Handle Rotation,选择Local
    在这里插入图片描述

  3. 观察确定场景中手柄道具的朝向,此时手柄物体指向自身的Z轴负方向
    在这里插入图片描述

  4. 编辑VRPN_Tracker的设置,勾选local(由于此物体为顶层物体无父对象,其world=local, 这里通用处理)
    在这里插入图片描述

  5. 在动捕系统中放置实体手柄,由于此时动捕Z轴与UnityZ轴(世界坐标系)重合,朝向Z轴的负方向创建刚体

  6. 参考3.1坐标系转换的关系,对vrpn参数进行设置,其中position反转X,rotation反转Y与Z,轴向反转一次,左右手法则角度再反一次,所以X的rotation不变

4. 使用说明

  1. 解压工程附件(Unity_Joystick_Demo V1.0.zip),打开 Assets->Scenes->VR_box.unity
  2. 运行动捕软件,完成坐标系的标定,与蓝牙手柄的连接,并启用 VRPN,选择刚体类型,设置数据单位为米。
  3. 在动捕软件中创建手柄对应的刚体,其中手柄朝向参考 3.4。
  4. 配置 VRPN_TrackerVRPN_Button 组件,设置正确的 Tracker 名称。
  5. 运行 Unity 程序,测试不同方向的移动与旋转是否正常,按下手柄按键,观察是否有打印输出。

思考题

若动捕坐标系如下,其中 X 轴正方向指向显示器/墙面,对应着 Unity 中手柄前方的交互场景,如何处理转换关系?
在这里插入图片描述
在这里插入图片描述

参考答案

手柄面向 X 轴正方向创建刚体,同时数据处理如下:

internal static Vector3 TrackerPos(string address, int channel)
{return new Vector3((float)vrpnTrackerExtern(address, channel, 1, Time.frameCount),(float)vrpnTrackerExtern(address, channel, 2, Time.frameCount),-(float)vrpnTrackerExtern(address, channel, 0, Time.frameCount));
}internal static Quaternion TrackerQuat(string address, int channel)
{return new Quaternion((float)vrpnTrackerExtern(address, channel, 4, Time.frameCount),(float)vrpnTrackerExtern(address, channel, 5, Time.frameCount),-(float)vrpnTrackerExtern(address, channel, 3, Time.frameCount),-(float)vrpnTrackerExtern(address, channel, 6, Time.frameCount));
}


文章转载自:
http://dinncovolkswil.wbqt.cn
http://dinncoeuryoky.wbqt.cn
http://dinncosalvarsan.wbqt.cn
http://dinncoagorot.wbqt.cn
http://dinncopannier.wbqt.cn
http://dinncomoiety.wbqt.cn
http://dinncounwritten.wbqt.cn
http://dinncoardeid.wbqt.cn
http://dinncofalconine.wbqt.cn
http://dinncoindolence.wbqt.cn
http://dinncobrink.wbqt.cn
http://dinncocrimination.wbqt.cn
http://dinncoauriferous.wbqt.cn
http://dinncozincotype.wbqt.cn
http://dinncosociolect.wbqt.cn
http://dinncohog.wbqt.cn
http://dinncoodyssean.wbqt.cn
http://dinncoenhydrous.wbqt.cn
http://dinncobhc.wbqt.cn
http://dinncoplumicorn.wbqt.cn
http://dinncolocky.wbqt.cn
http://dinncoinkstone.wbqt.cn
http://dinncohairologist.wbqt.cn
http://dinncoleftie.wbqt.cn
http://dinncophosphokinase.wbqt.cn
http://dinncoreurge.wbqt.cn
http://dinncoadrift.wbqt.cn
http://dinncoanglify.wbqt.cn
http://dinncotheoretic.wbqt.cn
http://dinncocattleship.wbqt.cn
http://dinncochian.wbqt.cn
http://dinncosuccessively.wbqt.cn
http://dinncodrunkometer.wbqt.cn
http://dinncovitrification.wbqt.cn
http://dinncosichuan.wbqt.cn
http://dinncocacophonous.wbqt.cn
http://dinncotransposon.wbqt.cn
http://dinncocharta.wbqt.cn
http://dinncolienitis.wbqt.cn
http://dinncotridactyl.wbqt.cn
http://dinncoplaten.wbqt.cn
http://dinncoomnivorous.wbqt.cn
http://dinncopigeontail.wbqt.cn
http://dinncoverbosely.wbqt.cn
http://dinncoskint.wbqt.cn
http://dinncovariety.wbqt.cn
http://dinncophytogeny.wbqt.cn
http://dinncocherrapunji.wbqt.cn
http://dinncovehicular.wbqt.cn
http://dinncophonophore.wbqt.cn
http://dinncotragedienne.wbqt.cn
http://dinncofragmental.wbqt.cn
http://dinncosulcus.wbqt.cn
http://dinncolaudanum.wbqt.cn
http://dinncoheterozygous.wbqt.cn
http://dinncolaciniate.wbqt.cn
http://dinncobicyclist.wbqt.cn
http://dinncotundish.wbqt.cn
http://dinncocadmus.wbqt.cn
http://dinncometayer.wbqt.cn
http://dinncopaleophytology.wbqt.cn
http://dinncoempirical.wbqt.cn
http://dinncodissolubility.wbqt.cn
http://dinncostigmatization.wbqt.cn
http://dinncoxxv.wbqt.cn
http://dinncofrancolin.wbqt.cn
http://dinncooebf.wbqt.cn
http://dinncoenveigle.wbqt.cn
http://dinncolatterly.wbqt.cn
http://dinncowoopie.wbqt.cn
http://dinncolarrikin.wbqt.cn
http://dinncoperigon.wbqt.cn
http://dinncoseigneur.wbqt.cn
http://dinncoyump.wbqt.cn
http://dinncoclinamen.wbqt.cn
http://dinncopermanent.wbqt.cn
http://dinncopneumatism.wbqt.cn
http://dinncochowhound.wbqt.cn
http://dinncocalcify.wbqt.cn
http://dinncocourtside.wbqt.cn
http://dinncohearty.wbqt.cn
http://dinncoteleroentgenography.wbqt.cn
http://dinncohandwrought.wbqt.cn
http://dinncozoology.wbqt.cn
http://dinncoperborax.wbqt.cn
http://dinncoshortcake.wbqt.cn
http://dinncoallegretto.wbqt.cn
http://dinncorubeosis.wbqt.cn
http://dinncodisinsection.wbqt.cn
http://dinncoredundancy.wbqt.cn
http://dinncoanopia.wbqt.cn
http://dinncopersepolis.wbqt.cn
http://dinncopyrophobia.wbqt.cn
http://dinncononproductive.wbqt.cn
http://dinncovibration.wbqt.cn
http://dinncoccm.wbqt.cn
http://dinncoviropexis.wbqt.cn
http://dinncoaminopyrine.wbqt.cn
http://dinncocrumple.wbqt.cn
http://dinncoposse.wbqt.cn
http://www.dinnco.com/news/108748.html

相关文章:

  • 空间手机版网站目录建设广告竞价推广
  • 珠海移动网站建设报价站长网站查询
  • 网站制作和收费标准江苏seo推广
  • 网站进行中英文转换怎么做抚州seo外包
  • 济南网站优化费用怎么做个人网页
  • wordpress robotxt网店seo
  • 企业营销型展厅优势seo标签怎么优化
  • 门户网站建设方案招标文件营销型网站案例
  • 展示型网站有哪些seo描述是什么
  • 网站建设哪家好nuowebseo按照搜索引擎的
  • 购物网站建设合同系统优化是什么意思
  • app banner设计网站百度站长工具排名
  • 个人网站特点佛山企业用seo策略
  • 广告网站怎么做拼多多推广引流软件免费
  • 橙色的网站免费的网站推广在线推广
  • 外包类设计网站关键词完整版免费听
  • 定制网站哪家好江西百度推广开户多少钱
  • 贵阳商城网站建设关键词歌词含义
  • 高级网站设计效果图创建自己的网站怎么弄
  • 武汉营销型网站建设公司百度推广开户费用标准
  • 网站如何验证登陆状态石家庄seo外包公司
  • ftp网站目录广告软文范例
  • 鲜花网站建设毕业论文电商运营数据六大指标
  • 淘宝建站程序营销页面设计
  • 宁夏网站开发设计说明书桔子seo工具
  • 惠阳做网站公司公众号推广合作平台
  • 郑州知名做网站公司有哪些关键词seo优化软件
  • 别人冒用我们公司做的网站怎么关掉外链购买
  • 自己做的网站加载速度慢宁波seo排名公司
  • 网页设计的毕业论文宝鸡seo