Создание линии, нарисованной с помощью LineRender, кликабельной - PullRequest
0 голосов
/ 14 апреля 2020

Я рисую динамические c линии, используя LineRender в Unity3d. И теперь мне нужно удалить эти строки, нажав правую кнопку мыши на строке. Но я не могу получить клик по линии. Есть ли способ сделать это, или я должен использовать что-то вместо 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;
    }

1 Ответ

0 голосов
/ 15 апреля 2020

Решение для уничтожения независимых линий

Таким образом, вы хотите уничтожить независимые линии одним щелчком мыши. Вероятно, причина, по которой у вас возникает проблема щелчка в любом месте и уничтожения последней строки, заключается в том, что вы оставляете EdgeCollider2D с данными по умолчанию, поэтому все линии имеют краевой коллайдер в одинаковых точках; и каким-то образом ваша Сцена и Камера находятся в положении, где, независимо от того, где вы нажимаете, Raycast2D поражает их всех, и вы удаляете только одну, первую, которую нажимаете.

Теперь лучшее решение - это использовать Метод BakeMe sh, но как правильно его реализовать.

Сначала при создании строки вместо _line.gameObject.AddComponent<EdgeCollider2D>(); добавьте MeshCollider.

Затем, после создания строки и отпустите кнопку в else if (Input.GetMouseButtonUp(0) && _line), вам нужно испечь линию me sh и прикрепить ее к коллайдеру me sh.

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 с присоединенным MeshCollider, где MeshCollider - это запеченный me sh LineRenderer .

Наконец, как их уничтожить, это почти то же самое, что вы делали ранее, но вместо Raycast2d используйте обычный метод 3d ( Physics.Raycast ), потому что MeshCollider из трехмерной физики. .

Пожалуйста, прочитайте больше о:

Решение, если вы хотите только одну строку

Проблема в том, что вы каждый раз создаете новые независимые строки (LineRenderer), поэтому, когда вы хотите удалить полную строку, вы удаляете только одну из них, а не все.

Вы можете продолжить действуя таким образом, но вам нужно каким-то образом сохранить каждую независимую линию в списке, а затем удалить все игровые объекты, которые завершают всю линию.

Но лучшее решение - использовать LineRenderer, чтобы добавить больше точек к вашей линии. каждый раз, когда вы хотите новую точку, вы должны увеличить _line.positionCount = line.positionCount + 1; вашего LineRendere, а затем сохранить позицию в этой точке, например _line.SetPosition(line.positionCount-1, _mousePos);

Теперь используя BakeMe sh (как @ Игги предложил) будет работать, потому что у вас есть только один LineRe Что бы со всеми точками, вам просто нужно использовать Me sh, который вы получили на MeshCollider , и использовать его как в этом примере .

РЕДАКТИРОВАТЬ: после прочтения все комментарии и код я понимаю, чего хотел @vviolka, поэтому я добавляю новое решение.

...