我正在Unity3d中使用LineRender绘制动态线。现在,我需要通过单击行上的鼠标右键来删除此行。但我无法点击在线。有没有办法做到这一点,或者我必须使用某些东西代替LineRender?
我试图添加到EdgeCollider行中,然后像RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(new 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;
至此,我们应该有一个带有MeshCollider的LineRenderer,其中MeshCollider是LineRenderer的烘焙网格。
最后,如何销毁它们,与以前几乎一样,但是请使用常规的3d方法(Physics.Raycast)代替Raycast2d,因为MeshCollider来自3d物理学。
请阅读更多有关:
如果您只想一行的解决方案
问题是您每次都创建新的独立行(LineRenderer),因此,当您要删除整行时,您将仅删除其中一行而不是全部。
您可以继续这样做,但是您需要以某种方式将每条独立线保存在列表中,然后删除所有完成整行的线游戏对象。
但是最好的解决方案是使用LineRenderer向您的线中添加更多的点,每次您想要一个新点时,都应增加LineRendere的_line.positionCount = line.positionCount + 1;
,然后将位置保存到该点,例如_line.SetPosition(line.positionCount-1, _mousePos);
现在使用BakeMesh(如@Iggy建议)将起作用,因为您只有一个LineRenderer包含所有点,您只需要使用到达MeshCollider的网格,并像this example一样使用它。
编辑:阅读所有注释和代码后,我了解@vviolka想要什么,所以我添加了一个新的解决方案。