Unity 社区
0
1

XR交互_3D操控杆

阅读 93
2023年10月15日
啪布里克
打好基础,搞点花活
游戏操控杆给我们的体验是非常直观沉浸的,这种强交互性在XR应用中可以给用户很好的体验感。 下面是我实现3D交互操纵杆的方法_通过屏幕操纵3D操纵杆(VRAR中同样适用)



思路拆解

首先,操控杆是三部分组成的。
头:手去摇动头 ——(改变位置)
杆:上面连接头和下面连接底部 ——(连接)
底:保证固定不让整体呗移动() ——(确定相对位置)

这里复现操纵杆可以分为两部分

改变头部的位置。注意点:移动的位置在底部为中心的半径x的范围圈内
杆底部长在底座上,头部始终跟着头部走

我们改变一下思路

让头和杆实体统称杆,唯一功能就是始终指向头部位置
头部的就是一个不被可见的碰撞体,唯一的功能就是在范围内移动

代码前先看结构


下面是代码与解释

先说杆始终朝向球切不发生杆乱转问题
using UnityEngine; public class Joystick : MonoBehaviour { public Transform 头Obj_A; public Transform stable_Y_Object; void Update() { //Z轴就时刻看着摇杆 头Obj_B,Y轴看着Obj_C transform.LookAt(头Obj_A.transform, stable_Y_Object.transform.localPosition); } }
在说头移动的问题
1.在头原本点的XZ平面上跟随鼠标移动
2.移动范围要现在在原出生点位的一定半径内
3.手离开以后还得自动回到原位。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class JoystickHandleController : MonoBehaviour { public Transform anchorPoint; //考虑到整体摇杆会移动翻转,如在战斗机上。使用使用一个不变的点位充当摇杆头的初始点位 public float initialRadius = 0.15f; // 初始圆圈的半径 private float maxRadius; // 圆圈的半径 private bool isDragging; public float moveTime = 0.5f; private Coroutine iEBackJoystick; private void Start() { maxRadius = initialRadius; // 初始化圆圈的半径 } private void Update() { // 检测鼠标左键是否按下 if (Input.GetMouseButtonDown(0)) { // 创建一条射线从摄像机到鼠标位置 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // 设置射线碰撞检测 RaycastHit hit; if (Physics.Raycast(ray, out hit)) { // 检查是否点击到了手柄 if (hit.collider.gameObject == gameObject) { isDragging = true; StopBack(); } } } // 检测鼠标左键是否释放 else if (Input.GetMouseButtonUp(0)) { isDragging = false; StartBack(); } //1.在头原本点的XZ平面上跟随鼠标移动----------------------------------- if (isDragging) { // 根据鼠标位置计算射线与手柄所在平面的交点 Plane plane = new Plane(transform.up, transform.position); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); float distance; if (plane.Raycast(ray, out distance)) { Vector3 intersectionPoint = ray.GetPoint(distance); // 将交点限制在手柄所在平面内 Vector3 constrainedPosition = anchorPoint.InverseTransformPoint(intersectionPoint); // 计算交点与初始位置之间的偏移向量 Vector3 offset = constrainedPosition - anchorPoint.localPosition; offset.y = anchorPoint.localPosition.y; // 2.移动范围要现在在原出生点位的一定半径内 将偏移向量限制在圆圈范围内----------- if (offset.magnitude > maxRadius) { offset = offset.normalized * maxRadius; offset.y = anchorPoint.localPosition.y; } // 将手柄移动到偏移向量与初始位置之和的位置 transform.localPosition = offset; } } } //3.松手的时候回到原位用一个携程函数来实现--------------------------------------------- private IEnumerator JoystickBack() { Vector3 startPosition = transform.localPosition; float elapsedTime = 0f; while (elapsedTime < moveTime) { // 使用线性插值函数将物体逐渐移动到目标位置 transform.localPosition = Vector3.Lerp(startPosition, anchorPoint.localPosition, elapsedTime / moveTime); // 等待一帧 yield return null; elapsedTime += Time.deltaTime; } } public void StartBack() { if (iEBackJoystick == null&& transform.localPosition!= anchorPoint.localPosition) { iEBackJoystick = StartCoroutine(JoystickBack()); } } public void StopBack() { if (iEBackJoystick != null) { StopCoroutine(iEBackJoystick); iEBackJoystick = null; } } }

知识点可以注意一下

一是携程储存-开始与终止
二是根据鼠标位置计算射线与手柄所在平面的交点的
首先,通过Plane plane = new Plane(transform.up, transform.position)创建了一个新的平面。此平面的方向向量是 transform.up,这表明平面是垂直于Y轴的,通过物体的位置定义其位置。
然后,创建一个从鼠标的屏幕位置发出的射线 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition)。这是一个从主相机朝向鼠标光标的射线。
然后,它用刚刚创建的射线与平面进行相交,并用 out 关键字得到射线与平面的交点距离。这是通过 if (plane.Raycast(ray, out distance)) 实现的。如果射线与平面相交,该函数返回true,并计算出射线与平面的交点距离。
然后,通过 Vector3 intersectionPoint = ray.GetPoint(distance), 计算出射线和平面的交点。
紧接着,通过 Vector3 constrainedPosition = anchorPoint.InverseTransformPoint(intersectionPoint),将得到的交点限制在了手柄所在的平面内。
然后,通过 Vector3 offset = constrainedPosition - anchorPoint.localPosition,计算出交点与手柄初始位置间的向量偏移量,然后限制了这个偏移量的y分量等于初始位置的y分量( offset.y = anchorPoint.localPosition.y ),这主要是为了保证交点仍在手柄所在的平面内。
最后,通过transform.localPosition = offset,将手柄移动到偏移向量与初始位置之和的位置。 这样,可以观测到鼠标移动时,手柄同时在其所在平面内移动。
设计师搞开发
期待你的想法与方案


XRUX
摇杆
发布于 新手答疑
推荐阅读
UDP-在Unity中的简单用法
啪布里克
2023-12-18
阅读 288
TCP网络通信-在C#/Unity中的编程实际知识
啪布里克
2023-12-08
阅读 1142
Unity用法-23章状态模式
啪布里克
2023-12-03
阅读 100
状态模式实践与应用
啪布里克
2023-11-07
阅读 153
名词解释-状态模式
啪布里克
2023-11-05
阅读 87
状态模式
啪布里克
2023-11-01
阅读 439
1条评论
App 内打开
分享到微博

深圳坪山网站建设公司移动端网站怎么做优化常州海外网站优化龙华网站建设优化技术寮步网站优化的方案其他网站推广优化郑州网站优化报价王者官方网站貂蝉优化汇川区网站优化营销中山网站推广优化方案书杨浦区百度网站优化平台网站优化收费方式路北区网站优化多少钱宁陵专业网站seo优化多少钱好的珠宝行业网站优化电话多少乐山企业网站优化服务东莞正规网站seo优化推广河源网站优化方案书网站优化技术视频揭阳网站优化哪家快开封网站优化推广渠道厦门网站优化体验温县资讯网站搭建优化网站排名优化金手指11吉林广电网站优化耗材辽宁网站关键词优化定制北京出名的服装行业网站优化永安网站优化公司南城网站优化哪儿好泰州网站seo优化服务项城外贸网站优化哪个好香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

深圳坪山网站建设公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化