使用LineRenderer以编程方式使用Edge Collider 2D画一条线,但是该碰撞器在Unity中的位置不正确

时间:2019-03-30 11:02:58

标签: c# unity3d

我希望玩家通过鼠标画一条线,并且这条线有一个对撞机,但是这个对撞机出现在错误的位置。

我已经用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 :(得分:0)

前段时间,在我的一个项目中,我遇到了完全相同的问题。我通过将线性渲染器对象的transform.position调整到下一个点的位置来修复它。设置完点后,我会将游戏对象的位置重置为零(代码的最后一行)。这对我有用,因为我的游戏对象应始终为绝对零。但是,如果没有,那么只需将其更改为使用相对位置,然后将其子类化为游戏对象(如果还没有)。

这是我的代码,希望对您有所帮助。

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;
}