0

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

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

到目前为止,我已经考虑过onMouseDown第一个球体上的事件,然后onMouseEnter到另一个球体,我会将数据存储在一些全局变量中(我还不知道如何做),如果 onMouseExit我只是把全局变量为空。

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

关于如何做到这一点的任何提示和技巧?

4

1 回答 1

1

点击拖拽功能演示

假设/设置

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

  2. 点击拖拽后设置父对象,是指将你没有点击的对象设置为你点击的父对象的子对象。

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

  4. 为了使拖动工作,我创建了一个四边形用作 2D 场景的“背景”,并将其放在一个名为“背景”的新图层上。然后将图层蒙版字段设置为仅使用背景图层。

  5. 为线渲染器创建和设置材质(我在上面的示例中使用粒子/附加着色器),并为我正在使用的线渲染器的参数创建和设置材质Start Width: 0.75End Width: 0并确保Use World Space勾选。

在此处输入图像描述

解释

首先将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);
    }
}

希望这对某人有所帮助。

于 2016-03-04T13:08:47.897 回答