【问题标题】:Rotating an object at which I am looking (ARFoundation)旋转我正在查看的对象(ARFoundation)
【发布时间】:2019-09-04 13:58:13
【问题描述】:

2 个项目放置在 AR 中。我想在其中一项位于屏幕中间时旋转其中一项(使用触控和 Raycast)。

我希望在相机注视物体时执行代码的所有旋转部分。

这是我在场景中放置的对象上使用的脚本,移动功能有效,因为只有当您点击对象所在的屏幕并将其拖走(Raycast 到对撞机)时才会激活。但是,当我在任何地方滑动时,我的旋转对场景中的所有对象都有效,因为如果我在对撞机上滑动,我会移动对象,所以为了旋转,我必须留在对撞机之外。

public class MoveObject : MonoBehaviour
{
    public bool holding;
    private Component rotator;
    int doubleTap = 0;

    void Start()
    {
        holding = false;
    }

    void Update()
    {
        if (holding)
        {
            Move();
        }

        // One finger
        if (Input.touchCount == 1)
        {
            // Tap on Object
            if (Input.GetTouch(0).phase == TouchPhase.Began)
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
                RaycastHit hitTouch;

                if (Physics.Raycast(ray, out hitTouch, 100f))
                {
                    if (hitTouch.transform == transform)
                    {
                        holding = true;
                    }
                }
            }
            // Release
            if (Input.GetTouch(0).phase == TouchPhase.Ended)
            {
                holding = false;
            }
        }

        if (Input.touchCount == 1 && !holding) //THIS is the rotation part
        {
            // GET TOUCH 0
            Touch touch0 = Input.GetTouch(0);

            // APPLY ROTATION
            if (touch0.phase == TouchPhase.Moved)
            {
                transform.Rotate(0f, touch0.deltaPosition.x * 0.5f, 0f);
            }
        }
    }

    void Move()
    {
        RaycastHit hit;
        Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
        // The GameObject this script attached should be on layer "Surface"
        if (Physics.Raycast(ray, out hit, 30.0f, 
        LayerMask.GetMask("Surface")))
        {
            transform.position = new Vector3(hit.point.x,
                                             transform.position.y,
                                             hit.point.z);
        }
    }
}

【问题讨论】:

  • 不,那是为了轮换。如果我按照您的建议进行操作,我的对象将同时移动和旋转。 (我知道这是因为我之前忘记了“!”)

标签: c# android unity3d augmented-reality


【解决方案1】:

您可能需要另一个类似于holding 的标志,以确保在滑动过程中不会旋转屏幕中心经过的对象,例如当相机移动并且对象通过屏幕中心。

您可以使用Camera.ViewportPointToRaynew Vector3(0.5f, 0.5f, 0) 输入来创建来自屏幕中心的射线。从那里开始,该过程类似于您的持有代码。

另外,通过重新排列,您可以重新使用已经用于检查此对象是否被触摸的光线投射,因为它还会检查是否有任何对象被触摸。仅在第一次光线投射没有接触任何东西时检查开始旋转,以避免在此对象位于屏幕中心但另一个对象被触摸的情况下旋转(以及不必要的光线投射)。

作为旁注,它是recommended to cache the result of Camera.main,因为每次您引用它时它都会在内部执行FindGameObjectsWithTag,这会增加额外的计算时间。

总而言之,它可能看起来像这样:

private bool rotating;
private Camera cam;

void Start()
{
    holding = false;
    rotating = false;
    cam = Camera.main;
}

void Update()
{
    // One finger
    if (Input.touchCount == 1)
    {
        Touch touch0 = Input.GetTouch(0);

        if (touch0.phase == TouchPhase.Began)
        {
            Ray ray;
            RaycastHit hitTouch;

            // test hold start
            ray = cam.ScreenPointToRay(touch0.position);
            if (Physics.Raycast(ray, out hitTouch, 100f))
            {
                if (hitTouch.transform == transform)
                {
                    holding = true;
                }
            }
            else  // avoid rotating/raycasting again in situation 
                  // where this object may be in center of screen 
                  // but this or other object was touched.
            {
                // test rotate start
                ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
                if (Physics.Raycast(ray, out hitTouch, 100f)))
                {
                    if (hitTouch.transform == transform)
                    {
                        rotating = true;
                    }
                }
            } 
        }
        else if (touch0.phase == TouchPhase.Moved)
        {
            if (holding)
            {
                Move();
            }
            else if (rotating)
            {
                transform.Rotate(0f, touch0.deltaPosition.x * 0.5f, 0f);
            }
        }
        // Release
        else if (touch0.phase == TouchPhase.Ended)
        {
            holding = false;
            rotating = false;
        }
    }
}

【讨论】:

  • 谢谢,当我在电脑上工作时,我会立即更改它(星期一,会通知你)。谢谢你的努力:)
猜你喜欢
  • 1970-01-01
  • 2014-11-18
  • 1970-01-01
  • 1970-01-01
  • 2016-03-25
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多