Unity中ARCore家具拖拽旋转功能实现求助(附ARKit等效代码)
嘿,作为ARCore新手遇到这个问题太正常了——毕竟ARKit和ARCore的平面检测API确实有差异,我直接给你对应实现代码,再拆解下关键逻辑,你就能快速上手啦!
ARCore 实现物体拖拽定位+双指旋转功能
先给你完整的等效实现代码,你可以直接放到Unity脚本里挂载到目标物体上(记得确保场景里有ARCore的Session和ARPlaneManager组件哦):
using UnityEngine; using GoogleARCore; public class ARCoreObjectManipulation : MonoBehaviour { // 控制是否允许拖拽物体 public bool allowDrag = true; // 控制是否允许旋转物体 public bool allowRotate = true; // 记录上一帧双指的夹角,用于计算旋转增量 private float lastFingerAngle; // 记录拖拽时是否已经命中平面 private bool isDragging = false; void Update() { if (Session.Status != SessionStatus.Tracking) { // ARCore未追踪到环境时不处理触摸操作 return; } switch (Input.touchCount) { case 1: if (!allowDrag) break; Touch touch = Input.GetTouch(0); HandleSingleTouch(touch); break; case 2: if (!allowRotate) break; Touch touch1 = Input.GetTouch(0); Touch touch2 = Input.GetTouch(1); HandleDoubleTouch(touch1, touch2); break; } } private void HandleSingleTouch(Touch touch) { switch (touch.phase) { case TouchPhase.Began: // 发射射线检测AR平面 TrackableHit hit; TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon; if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit)) { // 如果命中平面,标记开始拖拽 isDragging = true; } break; case TouchPhase.Moved: if (isDragging) { TrackableHit hit; TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon; if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit)) { // 将物体移动到射线命中的平面位置 transform.position = hit.Pose.position; // 保持物体的朝向和平面一致(可选,根据需求调整) transform.rotation = hit.Pose.rotation; } } break; case TouchPhase.Ended: case TouchPhase.Canceled: // 触摸结束,停止拖拽 isDragging = false; break; } } private void HandleDoubleTouch(Touch touch1, Touch touch2) { // 获取当前双指的位置 Vector2 touch1Pos = touch1.position; Vector2 touch2Pos = touch2.position; // 计算当前双指的夹角 float currentFingerAngle = Vector2.Angle(touch1Pos - touch2Pos, Vector2.right); // 只有当触摸处于移动阶段时才计算旋转增量 if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved) { // 计算夹角变化量,作为旋转增量 float angleDelta = currentFingerAngle - lastFingerAngle; // 将旋转增量应用到物体的Y轴(可以根据需求改成X或Z轴) transform.Rotate(Vector3.up, -angleDelta, Space.World); } // 更新上一帧的夹角记录 lastFingerAngle = currentFingerAngle; } }
关键逻辑拆解
- ARCore平面检测:用
Frame.Raycast替代ARKit的ScreenToViewportPoint+ARPoint逻辑,这个方法会直接检测ARCore识别到的平面,返回命中点的Pose(位置+旋转)。 - 拖拽功能:单指触摸开始时检测平面,移动时持续更新物体位置到命中点,触摸结束后停止拖拽。
- 双指旋转:通过计算双指之间的夹角变化,将增量应用到物体的旋转轴上(这里用的是世界空间的Y轴,你可以根据需求调整)。
注意事项
- 确保你的Unity项目已经导入了ARCore SDK,并且配置了正确的
ARSession和ARPlaneManager。 - 如果不需要物体和平面保持旋转一致,可以去掉
transform.rotation = hit.Pose.rotation这一行,让物体保持自身初始朝向。 - 可以根据需求调整旋转的轴(比如改成物体自身的Y轴,把
Space.World换成Space.Self)。
内容的提问来源于stack exchange,提问作者donhasan
相关产品推荐
相关产品推荐

