【问题标题】:Unity3d drawing with whitespaces带有空格的 Unity3d 绘图
【发布时间】:2018-06-05 20:59:37
【问题描述】:

我使用 LineRenderer 绘制线条。游戏是二维的。我现在想要的是创建与带有碰撞器的游戏对象上的行一致的空白。

这是我用于绘制和添加对撞机线的代码。我想要的不是在游戏对象上画一条线,比如圆圈(使用 CircleCollider2D)或正方形(使用 BoxCollider2D)。我想要两个不同的 LineRenderer:一个是在对撞机上完成,第二个是在它上面开始。 What I'm trying to achieve那个方格没有隐藏线。正方形所在的地方没有一条线。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class DrawLine : MonoBehaviour
{
    private LineRenderer line;
    private bool isMousePressed;
    public bool isLeftMousePressed = false;

    public List<Vector3> pointsList;

    private Vector3 mousePos;
    public float width = 0.05f;

    // Structure for line points
    struct myLine
    {
        public Vector3 StartPoint;
        public Vector3 EndPoint;
    };
    //    -----------------------------------    
    void Awake()
    {
        // Create line renderer component and set its property
        line = gameObject.AddComponent<LineRenderer>();
        line.material = (Material)Resources.Load("Materials/LineMat");

        line.startWidth = width;
        line.endWidth = width;

        line.useWorldSpace = true;
        isMousePressed = false;
        pointsList = new List<Vector3>();

    }
    //    -----------------------------------    
    void Update()
    {
        if (Input.GetMouseButtonDown(1))
        {
           isLeftMousePressed = true;
        }

        if (isLeftMousePressed||Game.currentLevel == 0) return;

        if (Input.GetMouseButton(0))
        {
            isMousePressed = true; 
        }

        // Drawing line when mouse is moving(pressed)
        if (isMousePressed)
        {
            if (Input.GetMouseButtonUp(0))
            {
                isMousePressed = false;

                GameObject curve = (GameObject)Instantiate(Resources.Load("Curve"), transform.parent);
                curve.GetComponent<DrawLine>().width = width;

                if (line.GetPosition(line.positionCount - 1).z == 1) Destroy(gameObject);
                else enabled = false;
            }

            mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousePos.z = 0;

            if (!pointsList.Contains(mousePos))
            {
                pointsList.Add(mousePos);
                line.positionCount = pointsList.Count;
                line.SetPosition(pointsList.Count - 1, (Vector3)pointsList[pointsList.Count - 1]);

                try
                {
                    AddColliderToLine(line, (Vector3)pointsList[pointsList.Count - 2], (Vector3)pointsList[pointsList.Count - 1]);
                }
                catch(Exception e)
                {

                }
            }   
        }
    }

    //    -----------------------------------    
    //    Following method checks whether given two points are same or not
    //    -----------------------------------    
    private bool checkPoints(Vector3 pointA, Vector3 pointB)
    {
        return (pointA.x == pointB.x && pointA.y == pointB.y);
    }

    private void AddColliderToLine(LineRenderer line, Vector3 startPoint, Vector3 endPoint)
    {
        //create the collider for the line
        GameObject lcObject = new GameObject("LineCollider");
        BoxCollider2D lineCollider = lcObject.AddComponent<BoxCollider2D>();

        lcObject.layer = 2; // ignore raycast

        //set the collider as a child of your line
        lineCollider.transform.parent = line.transform;
        // get width of collider from line 
        float lineWidth = line.endWidth;
        // get the length of the line using the Distance method
        float lineLength = Vector3.Distance(startPoint, endPoint);
        // size of collider is set where X is length of line, Y is width of line
        //z will be how far the collider reaches to the sky
        lineCollider.size = new Vector3(lineLength, lineWidth);
        // get the midPoint
        Vector3 midPoint = (startPoint + endPoint) / 2;

        // move the created collider to the midPoint
        lineCollider.transform.position = midPoint;


        //heres the beef of the function, Mathf.Atan2 wants the slope, be careful however because it wants it in a weird form
        //it will divide for you so just plug in your (y2-y1),(x2,x1)
        float angle = Mathf.Atan2((endPoint.y - startPoint.y), (endPoint.x - startPoint.x));

        // angle now holds our answer but it's in radians, we want degrees
        // Mathf.Rad2Deg is just a constant equal to 57.2958 that we multiply by to change radians to degrees
        angle *= Mathf.Rad2Deg;

        //were interested in the inverse so multiply by -1
        //angle *= -1;
        // now apply the rotation to the collider's transform, carful where you put the angle variable
        // in 3d space you don't wan't to rotate on your y axis
        lineCollider.transform.Rotate(0, 0, angle);
    }
}

【问题讨论】:

  • 你能否提供更多的信息,比如你的代码的sn-p,你想要达到的效果的图纸或图片

标签: c# unity3d game-physics


【解决方案1】:

如果要打虚线,可以看2D Dotted LineRenderer

并在你想要的部分添加对撞机

 gameObject.AddComponent<PolygonCollider2D>();

编辑:

通过光线投射检查鼠标是否在正方形内

if (isMousePressed)
{
    var stopDrawing = false;  
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    if (Physics.Raycast(ray, out hit))
    {
        if(hit.transform.tag == "square" || hit.transform.tag == "circle") {
            stopDrawing  = true;
        }
    }
    if(stopDrawing) 
    {
        // Stop current line, prepare a new List<Vector3> for next line
    }
    else{
        // Continue draw current line
    }
}

【讨论】:

  • 不完全是。我写了更多细节。谢谢你的回答!
  • Tnx。但我还有一个问题。如果我高速绘制,曲线(线)将在它接触到对象之前完成。因为线的最后一点在正方形上,我们不画这个点和最后一点和上一点之间的线。因为更新功能太少了。所以我需要在直线接触正方形边界的地方添加点
  • 你是对的。我们应该涉及到最后一个点来延长曲线。Collision.contact可以帮你计算接触点
猜你喜欢
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
  • 2018-11-25
相关资源
最近更新 更多