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<Material>("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应用示例:绘制圆形和鼠标轨迹
习题要求
- 请写一个方法,传入一个中心点,传入一个半径,用
LineRenderer
画一个圆出来。 - 请实现,在 Game 窗口长按鼠标用
LineRenderer
画出鼠标移动的轨迹。
解决方案概述
本解决方案通过 LineRenderer
组件来实现两种绘制功能:
- 绘制圆形:通过计算圆周上等分的点,并将其设置为
LineRenderer
的位置点来绘制一个圆形。 - 绘制鼠标轨迹:在鼠标按下时创建或重置
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来承载LineRendererGameObject 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));}}/// <summary>/// 绘制一个圆。/// </summary>/// <param name="centerPos">圆的中心点。</param>/// <param name="r">圆的半径。</param>/// <param name="num">构成圆的线段数量(点数量),值越大圆越平滑。</param>private void DrawCircle(Vector3 centerPos, float r, int num){// 创建一个新的GameObject来承载LineRendererGameObject 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);}}
}