使使用LineRender绘制的线可单击



我正在Unity3d中使用LineRender绘制动态线。现在我需要通过点击鼠标右键删除这行。但我无法点击在线。有什么方法可以做到这一点吗?或者我必须使用某些东西而不是LineRender?

我试着把EdgeCollider添加到行中,然后像这样点击鼠标RaycastHit2D hit=Physics2D.Raycast(Camera.main.ScreenToWorldPoint(新Vector3(Input.mousePosition.x,Input.mousePosition.y,0((,Vector2.zero(;

if (hit.collider != null)
{
Destroy(hit.collider.gameObject);
}

但通过这种方式,我只能删除最后一条绘制的

以下是我创建线条的方法:

void Update(){
if (Input.GetMouseButtonDown(0))
{
if (_line == null)
CreateLine(material);
_mousePos = (Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, 
Input.mousePosition.y, -transform.position.z)));
_line.SetPosition(0, _mousePos);
_line.SetPosition(1, _mousePos);
}
else if (Input.GetMouseButtonUp(0) && _line)
{
_mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y,
-transform.position.z));
_line.SetPosition(1, _mousePos);
_line = null;
}
else if (Input.GetMouseButton(0) && _line)
{
_mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y,
-transform.position.z));
_line.SetPosition(1, _mousePos);
}
}

private void CreateLine(Material material)
{
_line = new GameObject("wall" + walls.Count).AddComponent<LineRenderer>();
_line.material = material;
_line.gameObject.AddComponent<EdgeCollider2D>();
_line.positionCount = 2;
_line.startWidth = 0.15f;
_line.endWidth = 0.15f;
_line.numCapVertices = 50;
}

销毁独立线路的解决方案

所以你想通过鼠标点击来破坏独立的线条。您遇到在任何位置单击并破坏最后一行的问题的原因可能是,您将EdgeCollider2D保留为默认数据,因此所有行在相同的点上都有边缘碰撞器;不知怎的,你的场景和相机处于这样一个位置,无论你点击哪里,Raycast2D都会点击它们,而你只删除一个,它点击的第一个。

现在最好的解决方案是使用BakeMesh方法,但如何正确实现它。

首先,当您创建行而不是_line.gameObject.AddComponent<EdgeCollider2D>();时,添加一个MeshCollider

然后,在创建线并在else if (Input.GetMouseButtonUp(0) && _line)中按下按钮后,需要烘焙线网格并将其附加到网格碰撞器。

else if (Input.GetMouseButtonUp(0) && _line)
{
_mousePos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y,
-transform.position.z));
_line.SetPosition(1, _mousePos);
//Bake the mesh
Mesh lineBakedMesh = new Mesh(); //Create a new Mesh (Empty at the moment)
_line.BakeMesh(lineBakedMesh, true); //Bake the line mesh to our mesh variable
_line.GetComponent<MeshCollider>().sharedMesh = lineBakedMesh; //Set the baked mesh to the MeshCollider
_line.GetComponent<MeshCollider>().convex = true; //You need it convex if the mesh have any kind of holes
_line = null;
}

此外,根据场景的设置方式,您可以尝试使线不使用世界空间作为默认值,如_line.useWorldSpace = false;

在这一点上,我们应该有一个带有网格碰撞器的LineRenderer,其中网格碰撞器是LineRenderer的烘焙网格。

最后,如何摧毁它们,这几乎和你以前一样,但不要使用Raycast2d,而是使用普通的3d方法(Physics.Raycast(,因为MeshCollider来自3d物理。

请阅读更多关于:

  • 线渲染器的烘焙网格
  • 网格碰撞器
  • 网格碰撞器的凸
  • MeshCollider的sharedMesh示例

如果您只想要一行的解决方案

问题是,每次都要创建新的独立线(LineRenderer(,因此当要删除整条线时,只删除其中一条,而不是全部。

你可以继续这样做,但你需要以某种方式将每一条独立的线保存在一个列表中,然后删除所有完成你整条线的线游戏对象。

但最好的解决方案是使用LineRenderer向线添加更多点,每次您想要新点时,您都应该增加LineRenderer的_line.positionCount = line.positionCount + 1;,然后将位置保存到该点,如_line.SetPosition(line.positionCount-1, _mousePos);

现在使用BakeMesh(正如@Iggy建议的那样(会起作用,因为你只有一个具有所有点的LineRenderer,你只需要使用网格碰撞器,并像本例一样使用它。

编辑:在阅读了所有的评论和代码后,我明白了@vviolka想要什么,所以我添加了一个新的解决方案。

最新更新