Simple sorting out of the problem of laser laser line dragging and dropping UI in the advanced AR/VR 3D space scene of Unity

Simple sorting out of the problem of laser laser line drag and drop UI implementation in the advanced AR/VR 3D scene of Unity

Table of contents

Simple sorting out of the problem of laser laser line drag and drop UI implementation in the advanced AR/VR 3D scene of Unity

1. Brief introduction

2. Implementation principle

3. Matters needing attention

4. Effect preview

Five, simple implementation steps

regular drag

The problem of the jumping position of the conventional drag and drop in the 3D space

A simple method to solve the problem of jumping drag position in 3D space by conventional dragging

6. Key code


1. Brief introduction

Some knowledge points in Unity are sorted out.

This section briefly introduces the development of Unity. In AR/VR development, sometimes it is necessary to drag and drop UI elements in 3D space, or drag and drop UI elements from one panel position to another panel position. Sometimes When the Laser ray drags the UI element and accidentally drags it out of the screen, the conventional dragging operation will cause a position error. If you have encountered a similar situation, here is a simple way of thinking and a reference. If you have a new You can also leave a message, thank you.

2. Implementation principle

1. For conventional UI drag and drop functions, generally use RectTransformUtility.ScreenPointToWorldPointInRectangle or RectTransformUtility.ScreenPointToLocalPointInRectangle to calculate the position

1、RectTransformUtility.ScreenPointToWorldPointInRectangle(this.gameObject.GetComponent<RectTransform>(), eventData.position, eventData.enterEventCamera, out pos);

2、RectTransformUtility.ScreenPointToLocalPointInRectangle(m_canvsGo.GetComponent<RectTransform>(), eventData.position, eventData.enterEventCamera, out pos);

2. For UI drag and drop in 3D space scenes (AR/VR), general routine functions can also be applied. Here we introduce the eventData.position obtained by using Laser ray interaction to convert the position of the world coordinates into the UI and use it to realize 3D space. UI drag and drop in the scene (AR/VR)

        Vector3 pos = eventData.position;
        pos.z = 1080;
        this.transform.position = Camera.main.ScreenToWorldPoint(pos) + m_OffsetPos;

3. Matters needing attention

1. When dragging the UI, in order to avoid abrupt movement, pay attention to add a movement offset value when starting to move, and add an offset when doing position assignment when officially moving, where the value of pos.z is , Canvas position z is relative to Camera position z (default camera position Vector.zero direction is forward z, Canvas is in z position)

1、移动开始时计算出移动偏差值
        Vector3 pos = eventData.position;
        pos.z = 1080;
        m_OffsetPos = this.transform.position - Camera.main.ScreenToWorldPoint(pos);
2、移动的时候添加上移动的偏差值
        Vector3 pos = eventData.position;
        pos.z = 1080;
        this.transform.position = Camera.main.ScreenToWorldPoint(pos) + m_OffsetPos;

4. Effect preview

Five, simple implementation steps

regular drag

1. Open Unity to create a scene and add a mobile UI -Image to the scene

2. Create a script to realize the conventional drag and drop function of Image

3. Mount the script to the scene Image

4. Run the scene, the effect is as shown in the figure

The problem of the jumping position of the conventional drag and drop in the 3D space

5. Switch to the 3D space scene, use the Laser ray instead of the mouse to interactively move the UI Image, the effect is as shown in the figure

(When the laser line interacts, if you accidentally move it out of the screen, the conventional method of dragging and moving the UI will cause position jumps)

A simple method to solve the problem of jumping drag position in 3D space by conventional dragging

6. According to the position jumping problem that occurs in conventional drag and drop, here we use the acquired eventData.position to convert it into world coordinates and assign it to the mobile UI - Image, the code is as follows

7. In the 3D space scene, use Laser laser line interaction, the effect is as follows

6. Key code

1、Drag.cs

using UnityEngine;
using UnityEngine.EventSystems;

public class Drag : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{
    private Vector3 m_OffsetPos;



    public void OnBeginDrag(PointerEventData eventData)
    {
        Debug.Log("OnBeginDrag");
        Vector3 pos;
        RectTransformUtility.ScreenPointToWorldPointInRectangle(gameObject.GetComponent<RectTransform>(), eventData.position, eventData.enterEventCamera, out pos);
        m_OffsetPos = this.gameObject.GetComponent<RectTransform>().position - pos;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        Debug.Log("OnEndDrag");
    }

    public void OnDrag(PointerEventData eventData)
    {
        Debug.Log("OnDrag");
        Vector3 pos;
        RectTransformUtility.ScreenPointToWorldPointInRectangle(this.gameObject.GetComponent<RectTransform>(), eventData.position, eventData.enterEventCamera, out pos);
        this.gameObject.GetComponent<RectTransform>().position = pos + m_OffsetPos;
    }
}

2、DragItem

using UnityEngine;
using UnityEngine.EventSystems;

public class DragItem : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{
    private Vector3 m_OffsetPos;

    public void OnBeginDrag(PointerEventData eventData)
    {
        Debug.Log("OnBeginDrag");
        // 方法一:
        //Vector3 pos;
        //RectTransformUtility.ScreenPointToWorldPointInRectangle(gameObject.GetComponent<RectTransform>(), eventData.position, eventData.enterEventCamera, out pos);
        //m_OffsetPos = this.gameObject.GetComponent<RectTransform>().position - pos;

        // 方法二:略有问题,暂时不用
        //Vector2 pos;
        //RectTransformUtility.ScreenPointToLocalPointInRectangle(gameObject.GetComponent<RectTransform>(), eventData.position, eventData.enterEventCamera, out pos);
        //Vector3 tmp = this.gameObject.GetComponent<RectTransform>().position;
        //m_OffsetPos.x = tmp.x - pos.x;
        //m_OffsetPos.y = tmp.y - pos.y;
        //m_OffsetPos.z = tmp.z;

        // 方法三:
        Vector3 pos = eventData.position;
        pos.z = 1080; // 根据 Canvas 与 Camera 实际距离赋值
        m_OffsetPos = this.transform.position - Camera.main.ScreenToWorldPoint(pos);

    }

    public void OnEndDrag(PointerEventData eventData)
    {
        Debug.Log("OnEndDrag");
    }

    public void OnDrag(PointerEventData eventData)
    {
        // 方法一:
        //Debug.Log("OnDrag eventData.position " + eventData.position.ToString());
        //Vector3 pos;
        //RectTransformUtility.ScreenPointToWorldPointInRectangle(this.gameObject.GetComponent<RectTransform>(), eventData.position, eventData.enterEventCamera, out pos);
        //this.gameObject.GetComponent<RectTransform>().position = pos + m_OffsetPos;

        // 方法二:略有问题,暂时不用
        //Vector2 pos;
        //RectTransformUtility.ScreenPointToLocalPointInRectangle(gameObject.GetComponent<RectTransform>(), eventData.position, eventData.enterEventCamera, out pos);
        //this.gameObject.GetComponent<RectTransform>().position = new Vector3(pos.x+m_OffsetPos.x,pos.y+m_OffsetPos.y,m_OffsetPos.z);

        // 方法三:
        Vector3 pos = eventData.position;
        pos.z = 1080;// 根据 Canvas 与 Camera 实际距离赋值
        this.transform.position = Camera.main.ScreenToWorldPoint(pos) + m_OffsetPos;

        Debug.Log("OnDrag pos " + pos.ToString());
    }
}

Guess you like

Origin blog.csdn.net/u014361280/article/details/128954064