在2个游戏对象之间拖放

时间:2015-07-01 15:56:30

标签: unity3d drag-and-drop unityscript unity5

我的场景中有2个球体。我希望能够将鼠标从一个球体拖放到另一个球体,并在拖动时有一个指示器(例如一条直线)。释放鼠标按钮后,我想在第一个球体中存储另一个球体(作为GameObject)。

我在UnityScript中需要这个,但我可以接受C#的想法。

到目前为止,我已经考虑了第一个球体上的onMouseDown事件,然后onMouseEnter到另一个球体,我会将数据存储在某个全局变量中(我不知道怎么做) )并且在onMouseExit的情况下,我将把全局变量设为null。

然后在第一个球体上onMouseUp我会将全局变量存储在按下的对象(球体)中。

有关如何操作的提示和技巧吗?

1 个答案:

答案 0 :(得分:1)

Click and drag functionality demonstration

<强>假设/设置

  1. 您正在2D世界空间工作;拖拽这部分解决方案的对象的逻辑需要改变。

  2. 点击拖动后设置父级,参考设置您没有点击的对象是您点击的父级的子级。

  3. 相机应该是正交相机;使用透视摄像头会导致拖动与您认为应该的位置不对齐。

  4. 为了进行拖动工作,我创建了一个用作&#39;背景&#39;到2D场景,并把它放在一个名为&background;&#39; background&#39;的新图层上。然后将layermask字段设置为仅使用背景图层。

  5. 为线条渲染器创建和设置材质(我在上面的示例中使用粒子/添加着色器),以及线条渲染器的参数I& #39; m使用Start Width: 0.75End Width: 0,并确保勾选Use World Space

  6. enter image description here

    <强>解释

    首先将otherSphere字段设置为指向场景中的另一个球体。 OnMouseDownOnMouseUp切换mouseDown bool,用于确定是否应更新线条渲染器。这些也用于打开/关闭线条渲染器,并设置/删除两个球体的父变换。

    要获取要拖动的位置,我使用方法ScreenPointToRay在屏幕上获取基于鼠标位置的光线。如果要为此拖动功能创建添加平滑,则应在底部启用if (...) else语句,并将lerpTime设置为值(0.25对我来说效果很好)。

    请注意;释放鼠标时,会立即设置父项,因此两个对象最终都会被拖动,但是孩子 将返回到它以前的位置。

    [RequireComponent(typeof(LineRenderer))]
    public class ConnectedSphere : MonoBehaviour
    {
        [SerializeField]
        private Transform       m_otherSphere;
        [SerializeField]
        private float           m_lerpTime;
        [SerializeField]
        private LayerMask       m_layerMask;
    
        private LineRenderer    m_lineRenderer;
        private bool            m_mouseDown;
        private Vector3         m_position;
        private RaycastHit      m_hit;
    
        public void Start()
        {
            m_lineRenderer          = GetComponent<LineRenderer>();
            m_lineRenderer.enabled  = false;
            m_position              = transform.position;
        }
    
        public void OnMouseDown()
        {
            //Un-parent objects
            transform.parent        = null;
            m_otherSphere.parent    = null;
    
            m_mouseDown             = true;
            m_lineRenderer.enabled  = true;
        }
    
        public void OnMouseUp()
        {
            //Parent other object
            m_otherSphere.parent    = transform;
    
            m_mouseDown             = false;
            m_lineRenderer.enabled  = false;
        }
    
        public void Update()
        {
            //Update line renderer and target position whilst mouse down
            if (m_mouseDown)
            {
                //Set line renderer
                m_lineRenderer.SetPosition(0, transform.position);
                m_lineRenderer.SetPosition(1, m_otherSphere.position);
    
                //Get mouse world position
                if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out m_hit, m_layerMask))
                {
                    m_position.x    = m_hit.point.x;
                    m_position.y    = m_hit.point.y;
                }
            }
    
            //Set position (2D world space)
            //if (m_lerpTime == 0f)
                transform.position = m_position;
            //else
                //transform.position = Vector3.Lerp(transform.position, m_position, Time.deltaTime / m_lerpTime);
        }
    }
    

    希望这有助于某人。