Unity中使用LineRenderer实现鼠标点击移动场景中画线

使用Unity原生LineRenderer+Edge  Collider2D实现在2D场景中画线并带碰撞体。

我们先来看看效果

实现思路,当鼠标点击的时候开始在当前位置实例化LineRenderer对象,然后移动的过程中记录移动的点并赋值给LineRenderer中的 Positions属性动态修改LineRenderer的形状和长度。碰撞器方面使用Edge Collider 2D 通过类似方式,记录点并赋值给碰撞器的Points。

OK看完了大概原理还是来看看具体的代码吧。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class DrawLineScripts : MonoBehaviour
{
    //得到带有LineRender物体对象
    [Tooltip("The GameObject of LineObject")]
    public GameObject lineRenderer;
 
    //定义一个公共类来存储初始化成成的物体对象
    [Tooltip("The number of instantiate LineObject")]
    public int preFabLineCount = 6;
 
    //初始化LineRenderer 物体对象的集合
    [HideInInspector]
    public List<GameObject> lineList;
 
    //存储鼠标移动过的点
    [HideInInspector]
    public List<Vector2> linePos;
 
    //移动点索引
    private int idx = 0;
 
    //全局线段对象变量
    private GameObject gameObj;
 
    void Awake()
    {
        //激活阶段生成固定数量的物体对象
        for (int i = 0; i < preFabLineCount; i++)
        {
            GameObject go = Instantiate(lineRenderer, new Vector3(0f, 0f, 0f), Quaternion.identity);
            //将生成的对象隐藏,当需要使用的时候修改位置并显示出来。
            go.SetActive(false);
            //设置实例化出来物体的父级对象
            go.transform.SetParent(gameObject.transform);
            //将对象添加到全局列表中
            lineList.Add(go);
        }
    }
    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(0)) //鼠标左键点击的时候
        {
            gameObj = GetLineRenderer();
            //得到鼠标移动的坐标并将屏幕坐标转换为世界坐标
            Vector3 ve3 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.z));
            //得到对象身上的LineRenderer组件
            LineRenderer lineRenderer = gameObj.GetComponent<LineRenderer>();
            //设置LineRenderer组件的起始位置
            lineRenderer.SetPosition(idx, new Vector3(ve3.x,ve3.y,0f));
            //设置LineRenderer的宽度
            lineRenderer.startWidth = 0.4f;
            //将二维坐标存到数组中
            Vector2 v2 = new Vector2(ve3.x, ve3.y);
            linePos.Add(v2);
        }
        else if(Input.GetMouseButton(0))    //鼠标左键移动或者静止的时候
        {
            ++idx;  //设置LineRenderer位置的索引每移动一次增加一次
            LineRenderer lineRenderer = gameObj.GetComponent<LineRenderer>();
            Vector3 ve3 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.z));
            lineRenderer.positionCount = idx + 1;
            lineRenderer.SetPosition(idx, new Vector3(ve3.x, ve3.y, 0f));
            Vector2 v2 = new Vector2(ve3.x, ve3.y);
            linePos.Add(v2);
        }
        else if(Input.GetMouseButtonUp(0))  //鼠标左键抬起的时候
        {
            Vector3 ve3 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.z));
            EdgeCollider2D edge = gameObj.GetComponent<EdgeCollider2D>();   //得到物体身上的EdgeCollider2D组件
            edge.points = linePos.ToArray();    //将存起来的二维向量点赋值到碰撞器实现碰撞器初始化
            linePos.Clear();    //清除点集合方便下次点击记录
            idx = 0;    //索引归零
        }
    }
    /// <summary>
    /// 获取LineRenderer对象,如果对象集合中有未激活对象则取出未激活对象并激活,否则生成新对象
    /// </summary>
    /// <returns></returns>
    private GameObject GetLineRenderer()
    {
        for (int i = 0; i < lineList.Count; i++)
        {
            if (lineList[i].activeInHierarchy == false)
            {
                lineList[i].SetActive(true);
                lineList[i].transform.position = new Vector3(0f, 0f, 0f);
                return lineList[i];
            }
        }
        GameObject go = Instantiate(lineRenderer,new Vector3(0f,0f,0f),Quaternion.identity);
        go.transform.SetParent(gameObject.transform);
        lineList.Add(go);
        return go;
    }
}
代码里面有详细的注释,大部分讲清了实现原理,我们看一下Inspector面板。

LineRenderer对象面板

 这里讲一下这个实现存在的问题,这个实现是基于2D场景的,如果要实现3D场景,只要修改其中的屏幕坐标转换成世界坐标的方法,然后LineRenderer设置点的时候直接使用三维向量坐标即可,但是在3D场景中Edge Collider 2D便不能使用了。具体使用什么碰撞器以后再研究。

猜你喜欢

转载自blog.csdn.net/a1191835397/article/details/102610197
今日推荐