Unity基础-Line Renderer

Unity基础-Line Renderer

六、Line Renderer

概述

LineRenderer是Unity提供的一个用于划线的组件。
可以使用它在场景中绘制线段,一般可用于 绘制攻击范围、武器红外线、辅助线段等。

1. LineRenderer常用代码

// 动态添加一个线段(创建一个包含LineRenderer的GameObject)
GameObject lineGameObject = new GameObject("LineObject");
LineRenderer lineRenderer = lineGameObject.AddComponent<LineRenderer>();

// 设置线段的名字
lineGameObject.name = "Line";

// 首尾相连(是否闭合线条)
lineRenderer.loop = true;

// 设置线段的起始和结束宽度
lineRenderer.startWidth = 0.1f; // 设置线条起点的宽度
lineRenderer.endWidth = 0.1f;   // 设置线条结束点的宽度

// 设置线段的起始和结束颜色
lineRenderer.startColor = Color.red;   // 设置线条起点的颜色
lineRenderer.endColor = Color.yellow;  // 设置线条结束点的颜色

// 设置材质(LineRenderer需要材质才能正确渲染)
// 需要在Unity项目中创建一个材质,并将其Shader设置为Unlit/Color或Standard等
// 例如:创建一个名为 "LineMaterial" 的材质,并将其Shader设置为 "Sprites/Default"
// lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
// 如果有现有材质,可以拖拽赋值或通过Resources.Load加载
// lineRenderer.material = Resources.Load("Materials/LineMaterial");

// 设置点(定义线条的形状,至少需要两个点)
// 设置线条的顶点数量
lineRenderer.positionCount = 2; 
// 设置第一个点的位置
lineRenderer.SetPosition(0, new Vector3(0, 0, 0));
// 设置第二个点的位置
lineRenderer.SetPosition(1, new Vector3(5, 5, 0));

// 是否使用世界坐标系
// 如果为true,线条的顶点坐标是世界坐标;如果为false,则是相对于GameObject的本地坐标
lineRenderer.useWorldSpace = true;

// 决定了是否随对象移动而移动 (useWorldSpace为false时生效,即使用本地坐标)
// 如果useWorldSpace为false,LineRenderer的线条会跟随其所在的GameObject一起移动、旋转和缩放。
// 如果useWorldSpace为true,LineRenderer的线条位置是固定的世界坐标,不随GameObject的Transform变化。

2. LineRenderer组件参数

参数作用详细解释:

  • Loop(循环)

    • 如果启用,线条的起点和终点会连接起来,形成一个闭合的循环。
  • Positions(位置)

    • 这个展开项包含定义线条形状的一系列点。通常通过代码设置这些点。
    • Width(宽度)
      • 控制线条在不同位置的宽度。它是一个曲线编辑器,水平轴代表线条的长度(从0.0到1.0),垂直轴代表宽度乘数。图片中显示为均匀宽度1.0。
  • Color(颜色)

    • 控制线条在不同位置的颜色。它是一个渐变编辑器,可以设置线条从起点到终点的颜色变化。
  • Corner Vertices(拐角顶点)

    • 设置在线条拐角处生成的顶点数量。值越高,拐角越平滑。
  • End Cap Vertices(末端顶点)

    • 设置在线条两端(起始和结束)生成的顶点数量。值越高,线条末端越平滑。
  • Alignment(对齐)

    • 定义线条宽度如何对齐。例如,View 表示始终面向摄像机,Transform Z 表示始终与线条Transform的Z轴对齐。
  • Texture Mode(纹理模式)

    • 控制纹理如何应用到线条上。常见的模式有:Tile(平铺)、Stretch(拉伸)、Repeat Per Segment(每段重复)、Repeat Per Length(每长度重复)。
  • Shadow Bias(阴影偏移)

    • 用于防止线条自身产生阴影瑕疵的一个偏移量。
  • Generate Lighting Data(生成光照数据)

    • 如果启用,Line Renderer 将为光照贴图生成数据。
  • Use World Space(使用世界空间)

    • 如果启用,线条的点位置将被解释为世界坐标。如果禁用,则为本地坐标(相对于Line Renderer所在的GameObject)。
  • Materials(材质)

    • 这个展开项用于指定 Line Renderer 使用的材质。材质决定了线条的外观(颜色、纹理、着色器等)。
  • Lighting(光照)

    • 这是一个光照相关的设置展开项。
    • Cast Shadows(投射阴影)
      • 设置线条是否投射阴影。
    • Receive Shadows(接收阴影)
      • 设置线条是否接收来自其他物体的阴影。
  • Probes(探头)

    • 这是一个探头相关的设置展开项。

    • Light Probes(光照探头)

      • 控制线条如何与光照探头交互,以在非静态光照下获得环境光照信息。
    • Reflection Probes(反射探头)

      • 控制线条如何与反射探头交互,以在表面模拟反射效果。
  • Additional Settings(附加设置)

    • 这是一个高级设置展开项。

    • Motion Vectors(运动矢量)

      • 如果启用,会为线条生成运动矢量,这对于实现运动模糊等后期效果很有用。
    • Dynamic Occlusion(动态遮挡)

      • 控制线条是否参与动态遮挡剔除。
    • Sorting Layer(排序层)

      • 指定线条所在的渲染层,用于控制渲染顺序(例如,确保UI在游戏对象之上)。
    • Order in Layer(层内顺序)

      • 在同一排序层内,通过此值可以进一步控制渲染顺序,值越大越靠前渲染。

3. LineRenderer应用示例:绘制圆形和鼠标轨迹

习题要求
  1. 请写一个方法,传入一个中心点,传入一个半径,用 LineRenderer 画一个圆出来。
  2. 请实现,在 Game 窗口长按鼠标用 LineRenderer 画出鼠标移动的轨迹。
解决方案概述

本解决方案通过 LineRenderer 组件来实现两种绘制功能:

  1. 绘制圆形:通过计算圆周上等分的点,并将其设置为 LineRenderer 的位置点来绘制一个圆形。
  2. 绘制鼠标轨迹:在鼠标按下时创建或重置 LineRenderer,并在鼠标按住拖动时不断添加鼠标的世界坐标点到 LineRenderer 中,从而绘制出鼠标的移动轨迹。

核心思想:

  • LineRenderer 组件:Unity中用于绘制线段或曲线的组件,通过设置一系列顶点来定义线的形状。
  • 坐标转换:将屏幕坐标(鼠标位置)转换为世界坐标,以便在3D场景中正确绘制。
  • 数学计算:利用三角函数或四元数来计算圆周上的点位置。
代码实现 (Lea40.cs)
点击展开/折叠 Lea40.cs 代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lea40 : MonoBehaviour
{
    // 用于绘制线条的LineRenderer组件
    private LineRenderer lineRenderer;
    // 用于存储当前鼠标的世界坐标
    private Vector3 nowPos;

    void Start()
    {
        // 在游戏开始时,调用DrawCircle方法绘制一个圆
        // 中心点为当前GameObject的位置,半径为5,圆由360个点构成(形成一个近似的圆)
        DrawCircle(this.transform.position, 5, 360);
    }

    void Update()
    {
        // 检测鼠标左键是否按下(只在按下的第一帧触发)
        if(Input.GetMouseButtonDown(0))
        {
            // 创建一个新的GameObject来承载LineRenderer
            GameObject g = new GameObject("MouseTrail");
            // 为新创建的GameObject添加LineRenderer组件
            lineRenderer = g.AddComponent<LineRenderer>();
            // 设置LineRenderer不循环,即线条起点和终点不连接
            lineRenderer.loop = false;
            // 设置LineRenderer的起始点数量为0,准备开始绘制新轨迹
            lineRenderer.positionCount = 0;
        }

        // 检测鼠标左键是否按住(每帧触发)
        if(Input.GetMouseButton(0))
        {
            // 增加LineRenderer的点数量
            lineRenderer.positionCount += 1;
            // 获取当前鼠标在屏幕上的位置
            nowPos = Input.mousePosition;
            // 设置鼠标Z坐标,使其在摄像机前方10个单位,以便ScreenToWorldPoint正确转换
            nowPos.z = 10;
            // 将屏幕坐标转换为世界坐标,并将其设置为LineRenderer的最后一个点
            lineRenderer.SetPosition(lineRenderer.positionCount - 1, Camera.main.ScreenToWorldPoint(nowPos));
        }
    }

    /// 
    /// 绘制一个圆。
    /// 
    /// 圆的中心点。
    /// 圆的半径。
    /// 构成圆的线段数量(点数量),值越大圆越平滑。
    private void DrawCircle(Vector3 centerPos, float r, int num)
    {
        // 创建一个新的GameObject来承载LineRenderer
        GameObject gameObject = new GameObject("Circle");
        // 为新创建的GameObject添加LineRenderer组件
        LineRenderer line = gameObject.AddComponent<LineRenderer>();
        // 设置LineRenderer的点数量
        line.positionCount = num;
        // 设置LineRenderer循环,形成一个闭合的圆
        line.loop = true;
        
        // 计算每个点之间的角度间隔
        // 这里原本的 num/360 应该是 360f / num,表示每个点的角度增量
        // 如果num是360,anglePerPoint就是1度
        float anglePerPoint = 360f / num;

        // 遍历所有点,计算每个点在圆周上的位置
        for(int i = 0; i < num; i++)
        {
            // 计算当前点的角度
            float currentAngle = anglePerPoint * i;
            // 使用四元数旋转一个初始向量(例如Vector3.forward),然后乘以半径并加上中心点
            // 这样可以得到圆周上每个点在世界空间的位置
            // Quaternion.AngleAxis(currentAngle, Vector3.up) 创建一个绕Y轴旋转的四元数
            // Vector3.forward * r 得到半径为r,方向为Z轴正方向的向量
            line.SetPosition(i, centerPos + Quaternion.AngleAxis(currentAngle, Vector3.up) * Vector3.forward * r);
        }
    
    }
}

你可能感兴趣的:(Unity基础,unity,游戏引擎,c#,全文检索,开发语言)