我是Unity的ARCore新手。我的同事已经在iOS上制作了这个应用程序。但我在拖动对象并将其设置在某个位置时遇到一些问题。你也可以用两根手指旋转它。在这里,我给出了拖动的ARKit等效代码。任何人都可以帮我在AR Core上做同样的事情
switch (Input.touchCount) {
case 1:
if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved) {
var screenPosition = Camera.main.ScreenToViewportPoint(touch.position);
ARPoint point = new ARPoint {
x = screenPosition.x,
y = screenPosition.y
};
// prioritize reults types
ARHitTestResultType[] resultTypes = {
//ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent,
// if you want to use infinite planes use this:
ARHitTestResultType.ARHitTestResultTypeExistingPlane,
ARHitTestResultType.ARHitTestResultTypeHorizontalPlane,
ARHitTestResultType.ARHitTestResultTypeFeaturePoint
};
foreach (ARHitTestResultType resultType in resultTypes) {
if (HitTestWithResultType(point, resultType)) {
return;
}
}
}
break;
case 2:
if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Ended) {
Vector2 direction = touch.deltaPosition;
float yAngleIncrementVal = touch.deltaPosition.magnitude;
Vector3 currentRotation = transform.rotation.eulerAngles;
if (direction.x > 0) {
currentRotation.y += (yAngleIncrementVal * rotationScale);
}
else {
currentRotation.y -= (yAngleIncrementVal * rotationScale);
}
transform.rotation = Quaternion.Euler(currentRotation);
}
break;
}
}
此脚本将附加到将在飞机上移动的游戏对象。如何拖动游戏对象并更新锚点以使其保持在平面上。谢谢
答案 0 :(得分:0)
我几乎都在做同样的事情,这是我自己代码的简化版本:
case 1:
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
touchOffset = ARCamera.WorldToScreenPoint(gameObject.position) - new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, 0);
}
RaycastHit hit;
LayerMask layers = (1 << LayerMask.NameToLayer(layersOfGroundObjects))
Ray ray = ARCamera.ScreenPointToRay(Input.GetTouch(0).position + new Vector2(mouseOffset.x, mouseOffset.y));
if (!ClickedOnUI && Physics.Raycast(ray, out hit, Mathf.Infinity, layers))
{
if(Input.GetTouch(0).phase == TouchPhase.Began)
{
touchOffset = hit.point - gameObject.position;
}
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
gameObject.position = hit.point - touchOffset ;
}
}
case 2:
float currentTouchDistance = Vector2.Distance(touches[0].position, touches[1].position);
float diff_y = touches[0].position.y - touches[1].position.y;
float diff_x = touches[0].position.x - touches[1].position.x;
float currentTouchAngle = Mathf.Atan2(diff_y, diff_x) * Mathf.Rad2Deg;
if (isFirstFrameWithTwoTouches)
{
cachedTouchDistance = currentTouchDistance;
cachedTouchAngle = currentTouchAngle;
isFirstFrameWithTwoTouches = false;
}
float angleDelta = currentTouchAngle - cachedTouchAngle;
float scaleMultiplier = (currentTouchDistance / cachedTouchDistance);
float scaleAmount = cachedAugmentationScale * scaleMultiplier;
float scaleAmountClamped = Mathf.Clamp(scaleAmount, scaleRangeMin, scaleRangeMax);
if (enableRotation)
{
gameObject.localEulerAngles = cachedAugmentationRotation - new Vector3(0, angleDelta * 3f, 0);
}
if (enableRotation && enableScaling)
{
gameObject.localScale = new Vector3(scaleAmountClamped, scaleAmountClamped, scaleAmountClamped);
}
我还使用了touchOffset,它距离用户点击开始拖动的对象的枢轴(位置)的距离。每次拖动时,我都会将该偏移量应用到最终位置。它使拖动感觉更加自然。我在自己的代码中也使用了它,因此对我来说非常重要,但这与这个问题无关,所以我删除了剩下的代码。
此外,我使用了许多层作为地面,因为我可以把我的家具放在除了ARCore履带平面之外的更多表面上。如果你只关心被跟踪的平面,那么要么为它分配一个层,要么使用ARCore的光线投射而不是Unity的一个。或者只使用我的Eazy ARCore Interface插件,它可以同时执行这两个操作(使用跟踪平面的图层,并通过多个曲面的光线投射使事情变得更容易)