我正在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想要什么,所以我添加了一个新的解决方案。