
假设/设置
您在 2D 世界空间中工作;为这部分解决方案拖动对象的逻辑需要更改。
点击拖拽后设置父对象,是指将你没有点击的对象设置为你点击的父对象的子对象。
相机应该是正交相机;使用透视相机会导致拖动与您认为应该在的位置不对齐。
为了使拖动工作,我创建了一个四边形用作 2D 场景的“背景”,并将其放在一个名为“背景”的新图层上。然后将图层蒙版字段设置为仅使用背景图层。
为线渲染器创建和设置材质(我在上面的示例中使用粒子/附加着色器),并为我正在使用的线渲染器的参数创建和设置材质Start Width: 0.75
,End Width: 0
并确保Use World Space
勾选。

解释
首先将otherSphere
场设置为指向场景中的另一个球体。OnMouseDown
并OnMouseUp
切换 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);
}
}
希望这对某人有所帮助。