Нарисуйте линию с помощью Edge collider 2D с помощью LineRenderer программно, но коллайдер находится в неправильном месте в Unity - PullRequest
1 голос
/ 30 марта 2019

Я хочу, чтобы игрок нарисовал линию с помощью мыши, и у этой линии есть коллайдер, но этот коллайдер появляется не в том месте.

Я пробовал эти методы с ScreenToWorldPoint, ScreenToViewportPoint и ScreenPointToRay, ноэти результаты не то, что я хочу.

public class DrawLine : MonoBehaviour
{
    public GameObject linePrefab;
    public GameObject currentLine;

    public LineRenderer lineRenderer;
    public EdgeCollider2D edgeCollider;
    public List<Vector2> fingerPositions;
    public List<Vector2> fingerWorldPositions;

    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            CreateLine();
        }
        if (Input.GetMouseButton(0))
        {
            Vector2 tempFingerPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            if (Vector2.Distance(tempFingerPos, fingerPositions[fingerPositions.Count - 1]) > .1f)
            {
                UpdateLine(tempFingerPos);
            }
        }
    }

    void CreateLine()
    {
        currentLine = Instantiate(linePrefab, Vector2.zero, Quaternion.identity);
        lineRenderer = currentLine.GetComponent<LineRenderer>();
        edgeCollider = currentLine.GetComponent<EdgeCollider2D>();
        fingerPositions.Clear();
        Vector3 tempMousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        fingerPositions.Add(tempMousePosition);
        fingerPositions.Add(tempMousePosition);
        lineRenderer.SetPosition(0, fingerPositions[0]);
        lineRenderer.SetPosition(1, fingerPositions[1]);
        edgeCollider.points = fingerPositions.ToArray();
    }

    void UpdateLine(Vector2 newFingerPos)
    {
        fingerPositions.Add(newFingerPos);
        lineRenderer.positionCount++;
        lineRenderer.SetPosition(lineRenderer.positionCount - 1, newFingerPos);
        edgeCollider.points = fingerPositions.ToArray();
     }
}

Черная линия нарисована с помощью мыши, а зеленая линия - это Edge collider 2D.Sample

1 Ответ

0 голосов
/ 30 марта 2019

У меня была точно такая же проблема в моем проекте. Я исправил это, настроив transform.position объекта linerenderer к местоположению следующей точки. И после установки точек я бы сбросил положение игрового объекта на ноль (последняя строка кода). Это сработало для меня, потому что мой игровой объект всегда должен быть на абсолютном нуле. Но если это не так, просто измените его на относительное положение и присвойте ему игровой объект, если это еще не сделано.

Вот мой код, надеюсь, он вам поможет.

public GameObject LineDrawPrefab;

private LineRenderer lineRenderer;
private EdgeCollider2D edgeCollider;
private List<Vector2> edgePoints;
private GameObject activeLineGameObject;
private List<GameObject> lineGameObjects;

    private void StartLine(Vector3 start, Color color)
    {
        var targetPos = new Vector3 { x = start.x, y = start.y, z = 0.1f };

        drawing = true;
        activeLineGameObject = Instantiate(LineDrawPrefab, Vector3.zero, Quaternion.identity);
        lineGameObjects.Add(activeLineGameObject);

        lineRenderer = activeLineGameObject.GetComponent<LineRenderer>();
        edgeCollider = activeLineGameObject.GetComponent<EdgeCollider2D>();
        lineRenderer.sortingOrder = 1;
        lineRenderer.material = LineRendererMaterial;
        lineRenderer.startColor = color;
        lineRenderer.endColor = color;
        lineRenderer.startWidth = 0.3f;
        lineRenderer.endWidth = 0.3f;
        lineRenderer.SetPosition(0, targetPos);
        lineRenderer.SetPosition(1, targetPos);

        edgePoints.Clear();
        edgePoints.Add(targetPos);
        edgeCollider.points = edgePoints.ToArray();
    }

    private void ExtendLine(Vector3 nextpoint)
    {
        if (lineRenderer == null))
        {
            StartLine(Camera.main.ScreenToWorldPoint(Input.mousePosition), color);
            return;
        }
        var targetPos = new Vector3 { x = nextpoint.x, y = nextpoint.y, z = 0.1f };

        lineRenderer.positionCount += 1;
        lineRenderer.SetPosition(lineRenderer.positionCount - 1, lineRenderer.transform.position = targetPos); // manipulate position to avoid the collider from spawning out of the object.

        edgePoints.Add(nextpoint);
        edgeCollider.points = edgePoints.ToArray();
        activeLineGameObject.transform.position = Vector3.zero; // reset position
    }

Редактировать: дополнительный совет. Я (и ты) использовал Camera.main здесь. Это не эффективно, потому что каждый раз вызывается дорогой поиск. (GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>())

Я предлагаю кэшировать его при запуске или пробуждении, а затем повторно использовать эту переменную. Это может потенциально привести к значительному увеличению производительности.

private Camera mainCamera;

private void Start()
{
    mainCamera = Camera.main;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...