欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

unity 如何使用LineRenderer 动态划线

程序员文章站 2022-03-03 11:37:06
我就废话不多说了,大家还是直接看代码吧~private linerenderer line1; //画线line1 = this.gameobject.addcomponent

我就废话不多说了,大家还是直接看代码吧~

private linerenderer line1;        
//画线
line1 = this.gameobject.addcomponent<linerenderer>();
//只有设置了材质 setcolor才有作用
line1.material = new material(shader.find("particles/additive"));
line1.setvertexcount(2);//设置两点
line1.setcolors(color.yellow, color.red); //设置直线颜色
line1.setwidth(5f, 10f);//设置直线宽度      
//设置指示线的起点和终点
line1.setposition(0, a.transform.position);
line1.setposition(1, b.transform.position);
destroy(this.gameobject.getcomponent<linerenderer>());

补充:unity linerenderer绘制物体行走路线

我是用的角色控制器(character controller)+linerenderer做的

下面是代码

using system.collections;
using system.collections.generic;
using unityengine;
public class playertest : monobehaviour
{
    public gameobject clone;//这是个空物体  只添加了一个linerenderer组件
    public float speed = 5;
    public float jumpspeed = 10f;
    public float luodi = 15;
    private vector3 movepos = vector3.zero;
    public charactercontroller controller;
    private linerenderer line;
    vector3[] path;
    private float time = 0;
    list<vector3> pos=new list<vector3> ();
    void awake()
    {
              path = pos.toarray();//初始化
              line = clone.getcomponent<linerenderer>();//获得该物体上的linerender组件
              line.setcolors(color.blue, color.red);//设置颜色
              line.setwidth(0.2f, 0.1f);//设置宽度
    }
    void update()
    {
        time += time.deltatime;
        if (time>0.1)//每0.1秒绘制一次
        {
            time = 0;
            pos.add(transform.position);//添加当前坐标进链表
            path = pos.toarray();//转成数组
        }
        if (controller.isgrounded)//判断人物是否落地
        {
            movepos = new vector3(input.getaxis("horizontal"), 0, input.getaxis("vertical"));
            movepos = transform.transformdirection(movepos);
            movepos *= speed;
            if (input.getbutton("jump")) { 
                movepos.y = jumpspeed;
              }
        }
        movepos.y -= luodi * time.deltatime;
        controller.move(movepos * time.deltatime);
        if (path.length!=0)//有数据时候再绘制
        {
            line.setvertexcount(path.length);//设置顶点数      
            line.setpositions(path);//设置顶点位置
        }         
    }
}

补充:unity组件 — linerenderer动态添加碰撞

基础知识:

选中要添加组件的gameobject,在inspector面板,点击“add component”按钮,选中linerenderer组件,添加。

unity 如何使用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;
    } 
}

效果图:

unity 如何使用LineRenderer 动态划线

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。