Unity组件 — LineRenderer动态添加碰撞

基础知识:

选中要添加组件的gameObject,在Inspector面板,点击“Add Component”按钮,选中LineRenderer组件,添加。

cast Shadows : 蒙上阴影

Receive Shadows : 是否接受阴影

Dynamic Occludee : 是否动态遮罩

Materials 中的属性:

size : 材质球的数量

Element : 具体的材质球

Positions 中的属性:

size : 位置的数量

Element : 具体的位置

Use World Space : 是否使用世界坐标系,还是使用相对坐标系

Width : 线条的宽度

Color : 线条的颜色,注:如果没有赋值材质,无论怎样改变Color的值,颜色都不会有改变。

Corner Vertices : 可形成线条的圆角效果

End Cap Vertices : 影响线条的两端的圆角效果。

注:当line Renderer拥有了材质,可以通过修改Color来改变颜色。当时当修改了Color后,line的颜色没有改变,应该是Material和Color属性结合不好。将Material修改为Sprites/Default,Color的颜色就可以成功的显示在line上面了。

动态添加碰撞器(Polygon Collider2D)

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

public class MouseTrack : MonoBehaviour
{

    /// <summary>
    /// 获取LineRenderer组件
    /// </summary>
    [Header("获得LineRenderer组件")]
    public LineRenderer lineRenderer;
    //获得鼠标跟踪位置
    private Vector3[] mouseTrackPositions = new Vector3[20];

    private Vector3 headPosition;   //头位置
    private Vector3 lastPosition;   //尾位置
    private int positionCount = 0;  //位置计数

    [Header("设置多远距离记录一个位置")]
    public float distanceOfPositions = 0.01f;
    private bool firstMouseDown = false;    //第一次鼠标点击
    private bool mouseDown = false;     //鼠标点击

    PolygonCollider2D polygonCollider;   //添加多边形碰撞

    void Start()
    {
        polygonCollider = gameObject.GetComponent<PolygonCollider2D>();
    }

    void Update()
    {

        //鼠标点击的时候
        if (Input.GetMouseButtonDown(0))
        {
            polygonCollider.enabled = true;
            lineRenderer.positionCount = 20;
            firstMouseDown = true;
            mouseDown = true;
        }
        if (Input.GetMouseButtonUp(0))
        {
            mouseDown = false;

            //ClearColliderAndLineRenderer();
        }
        OnDrawLine();
        firstMouseDown = false;
    }

    //画线
    private void OnDrawLine()
    {
        if (firstMouseDown == true)
        {
            positionCount = 0;
            //头坐标
            headPosition = Camera.main.ScreenToViewportPoint(Input.mousePosition + new Vector3(0, 0, 11));
            lastPosition = headPosition;
        }

        if (mouseDown == true)
        {
            headPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition + new Vector3(0, 0, 11));
            //判断头坐标到尾坐标的距离是否大于记录点位
            if (Vector3.Distance(headPosition, lastPosition) > distanceOfPositions)
            {
                //用于保存位置
                SavePosition(headPosition);
                positionCount++;
            }
            lastPosition = headPosition;
        }

        //设置线性渲染器的位置
        SetLineRendererPosition(mouseTrackPositions);
    }

    //保存位置
    private void SavePosition(Vector3 pos)
    {
        pos.z = 0;
        if (positionCount <= 19)
        {
            for (int i = positionCount; i < 20; i++)
            {
                mouseTrackPositions[i] = pos;
            }
        }
        else
        {
            for (int i = 0; i < 19; i++)
            {
                mouseTrackPositions[i] = mouseTrackPositions[i + 1];
            }
        }
        mouseTrackPositions[19] = pos;

        //创建碰撞路径
        List<Vector2> colliderPath = GetColliderPath(mouseTrackPositions);
        polygonCollider.SetPath(0, colliderPath.ToArray());
    }

    //计算碰撞体轮廓
    float colliderWidth;
    List<Vector2> pointList2 = new List<Vector2>();
    List<Vector2> GetColliderPath(Vector3[] pointList3)
    {
        //碰撞体宽度
        colliderWidth = lineRenderer.startWidth;
        //Vector3转Vector2
        pointList2.Clear();
        for (int i = 0; i < pointList3.Length; i++)
        {
            pointList2.Add(pointList3[i]);
        }

        //碰撞体轮廓点位
        List<Vector2> edgePointList = new List<Vector2>();
        //以LineRenderer的点位为中心, 沿法线方向与法线反方向各偏移一定距离, 形成一个闭合且不交叉的折线
        for (int j = 1; j < pointList2.Count; j++)
        {
            //当前点指向前一点的向量
            Vector2 distanceVector = pointList2[j - 1] - pointList2[j];
            //法线向量
            Vector3 crossVector = Vector3.Cross(distanceVector, Vector3.forward);
            //标准化, 单位向量
            Vector2 offectVector = crossVector.normalized;
            //沿法线方向与法线反方向各偏移一定距离
            Vector2 up = pointList2[j - 1] + 0.5f * colliderWidth * offectVector;
            Vector2 down = pointList2[j - 1] - 0.5f * colliderWidth * offectVector;
            //分别加到List的首位和末尾, 保证List中的点位可以围成一个闭合且不交叉的折线
            edgePointList.Insert(0, down);
            edgePointList.Add(up);
            //加入最后一点
            if (j == pointList2.Count - 1)
            {
                up = pointList2[j] + 0.5f * colliderWidth * offectVector;
                down = pointList2[j] - 0.5f * colliderWidth * offectVector;
                edgePointList.Insert(0, down);
                edgePointList.Add(up);
            }
        }
        //返回点位
        return edgePointList;
    }

    //设置线条渲染器位置
    private void SetLineRendererPosition(Vector3[] position)
    {
        lineRenderer.SetPositions(position);
    }

    //用于清除碰撞和线性渲染
    void ClearColliderAndLineRenderer()
    {
        if (polygonCollider)
        {
            polygonCollider.enabled = false;
        }
        lineRenderer.positionCount = 0;
    }

}

效果图:

### 回答1: 使用Line Renderer碰撞检测来在物体上写字的方法大致如下: 1. 创建一个空物体,用于存储Line Renderer组件和Collider组件。 2. 在空物体上添加Line Renderer组件,设置需要的参数,如颜色、宽度、材质等。 3. 在空物体上添加Collider组件,设置为Mesh Collider,并将其碰撞体的Mesh设置为需要写字的物体的Mesh。 4. 编写脚本,在脚本中获取Line Renderer组件和Collider组件。 5. 在脚本中监听鼠标或触摸事件,根据事件的位置在Line Renderer添加新的点。 6. 每当添加新的点时,使用Collider.Raycast方法来检测当前点是否与物体相交,如果相交,则将新的点的位置调整为相交点的位置。 7. 当需要清除写字时,清空Line Renderer的点数组即可。 示例代码如下: ```csharp using UnityEngine; public class WritingOnObject : MonoBehaviour { private LineRenderer lineRenderer; private Collider collider; private void Start() { lineRenderer = GetComponent<LineRenderer>(); collider = GetComponent<Collider>(); } private void Update() { if (Input.GetMouseButton(0)) { Vector3 mousePosition = Input.mousePosition; mousePosition.z = Camera.main.transform.position.z - transform.position.z; Vector3 point = Camera.main.ScreenToWorldPoint(mousePosition); // 将点添加Line RendererlineRenderer.positionCount++; lineRenderer.SetPosition(lineRenderer.positionCount - 1, point); // 检测碰撞 RaycastHit hit; if (collider.Raycast(new Ray(point + Vector3.forward * 100, Vector3.back), out hit, 200)) { lineRenderer.SetPosition(lineRenderer.positionCount - 1, hit.point); } } if (Input.GetMouseButton(1)) { // 清除写字 lineRenderer.positionCount = 0; } } } ``` ### 回答2: 使用UnityLine Renderer组件碰撞检测可以实现在物体上写字的效果。下面是一种实现的方法: 首先,在Unity中创建一个空物体,将其命名为“WritingObject”。添加一个Line Renderer组件,并调整其属性,例如设置宽度、材质等。 接下来,创建一个脚本“WritingScript”并附加到“WritingObject”上。在脚本中定义一个List类型的变量来存储用于绘制的点的坐标。 然后,根据需要,可以通过更改Line Renderer的位置和旋转来确保其在正确的位置和朝向。 在脚本中,通过使用Raycast或触发等方法进行碰撞检测,以获取需要绘制字母的物体的位置坐标。通常,物体上可以附加一个Collider组件来进行简单的碰撞检测。 一旦检测到碰撞,将碰撞点的坐标添加到之前定义的List中。可以使用Add方法将坐标添加到List中。 随后,在Update方法中,开始绘制字母。使用Line Renderer的SetPosition方法来设置每个点的位置。在一个循环中,根据List的每个点来设置Line Renderer的位置。 最后,根据需要,可以在脚本中添加其他的字母和字体效果,如改变颜色、字体大小等。 总结起来,使用UnityLine Renderer组件碰撞检测,可以在物体上实现写字的效果。首先创建一个Line Renderer组件,并在脚本中定义一个List来存储绘制点的坐标。然后,通过碰撞检测获取需要绘制的物体的坐标,并将其添加到List中。在Update方法中,使用Line Renderer的SetPosition方法根据List的每个点的坐标来绘制字母。 ### 回答3: 在Unity中使用Line Renderer碰撞检测来在物体上写字是可行的。以下是一种实现方法: 首先,在场景中创建一个空游戏对象,命名为"WritingController"。将其作为脚本的容,并将以下脚本附加到该游戏对象上: ```c# using UnityEngine; public class WritingController : MonoBehaviour { public GameObject textPrefab; public float distanceThreshold = 0.1f; private LineRenderer lineRenderer; private Vector3 lastPoint; private void Start() { lineRenderer = GetComponent<LineRenderer>(); lineRenderer.startWidth = 0.1f; lineRenderer.endWidth = 0.1f; lastPoint = transform.position; } private void Update() { if (Vector3.Distance(lastPoint, transform.position) > distanceThreshold) { DrawText(); } } private void DrawText() { GameObject textObject = Instantiate(textPrefab, lastPoint, Quaternion.identity); TextMesh textMesh = textObject.GetComponent<TextMesh>(); textMesh.text = "写字内容"; lastPoint = transform.position; lineRenderer.positionCount++; lineRenderer.SetPosition(lineRenderer.positionCount - 1, lastPoint); } } ``` 接下来,创建一个3D文本,命名为"TextPrefab"。设置适当的大小、字体和其他属性。 然后,在场景中创建一个具有碰撞组件的物体,例如一个3D物体或一个2D Sprite。将该物体的位置移动到你想写字的地方。 最后,将"TextPrefab"和"WritingController"拖放到你的对象中的相应字段中。确保将"WritingController"游戏对象的脚本视图中的"distanceThreshold"属性设置为适当的值,以控制写字的间隔。 运行游戏后,当你移动物体时,它将在物体轨迹上创建一条线,并在每个点上生成一个显示所写文字的3D文本。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值