使使用 LineRender 绘制的线条可点击
Making line drawn with LineRender clickable
我在 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;
}
此外,根据您的场景设置方式,您可以尝试使该行不使用世界 space 作为默认值,例如 _line.useWorldSpace = false;
至此,我们应该有一个带有 MeshCollider 的 LineRenderer,其中 MeshCollider 是 LineRenderer 的烘焙网格。
最后,如何销毁它们,它和你之前的几乎一样,但是不是Raycast2d,而是使用普通的3d方法(Physics.Raycast),因为MeshCollider来自3d物理。
请详细阅读:
只需要一行的解决方案
问题是你每次都创建新的独立行(LineRenderer),所以当你想删除整行时,你只是删除其中一个而不是全部。
您可以继续这样做,但您需要以某种方式将每条独立的线保存在列表中,然后删除完成整条线的所有线游戏对象。
但最好的解决方案是使用 LineRenderer 向你的线条添加更多点,每次你想要一个新点时你应该增加你的 LineRendere 的 _line.positionCount = line.positionCount + 1;
然后保存到那个点的位置,比如 _line.SetPosition(line.positionCount-1, _mousePos);
现在使用 BakeMesh(正如@Iggy 建议的那样)会起作用,因为您只有一个包含所有点的 LineRenderer,您只需要使用您获得的网格 MeshCollider,并像这个例子.
一样使用它
编辑:阅读所有评论和代码后,我明白了@vviolka 想要什么,所以我添加了一个新的解决方案。
我在 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;
}
此外,根据您的场景设置方式,您可以尝试使该行不使用世界 space 作为默认值,例如 _line.useWorldSpace = false;
至此,我们应该有一个带有 MeshCollider 的 LineRenderer,其中 MeshCollider 是 LineRenderer 的烘焙网格。
最后,如何销毁它们,它和你之前的几乎一样,但是不是Raycast2d,而是使用普通的3d方法(Physics.Raycast),因为MeshCollider来自3d物理。
请详细阅读:
只需要一行的解决方案
问题是你每次都创建新的独立行(LineRenderer),所以当你想删除整行时,你只是删除其中一个而不是全部。
您可以继续这样做,但您需要以某种方式将每条独立的线保存在列表中,然后删除完成整条线的所有线游戏对象。
但最好的解决方案是使用 LineRenderer 向你的线条添加更多点,每次你想要一个新点时你应该增加你的 LineRendere 的 _line.positionCount = line.positionCount + 1;
然后保存到那个点的位置,比如 _line.SetPosition(line.positionCount-1, _mousePos);
现在使用 BakeMesh(正如@Iggy 建议的那样)会起作用,因为您只有一个包含所有点的 LineRenderer,您只需要使用您获得的网格 MeshCollider,并像这个例子.
一样使用它编辑:阅读所有评论和代码后,我明白了@vviolka 想要什么,所以我添加了一个新的解决方案。