Unity基础学习(十)LineRender绘制相关
本文简单介绍了LineRender组件
·
目录
一、什么是LineRender
LineRenderer是Unity引擎提供的一个核心渲染组件,主要用于在3D/2D场景中绘制连续的线段。相比Debug.DrawLine的调试用途,LineRenderer可以实现更复杂的可视化效果,并支持材质、光照等高级渲染特性。就是你可以认为是,画一条可看见线条。我们仅从代码角度来考虑一些常用的属性或者API,并不会着重讲解该组件的面板参数
主要特点有:
可绘制任意形状的多边形线段
支持动态修改顶点位置
可调整线宽、颜色、材质等视觉属性
支持世界空间/局部空间坐标系
可与物理系统配合实现碰撞效果
二、LineRender的参数介绍
基础参数表
| 参数 | 联想 | 作用 | 取值范围 | 示例值 |
|---|---|---|---|---|
| Positions | 珍珠项链的珍珠 | 定义线段的每个顶点坐标 | Vector3数组 | new Vector3(0,0,0) |
| Position Count | 珍珠数量 | 控制线段的分段数量 | ≥2 | 4 |
| Loop | 项链扣环 | 是否首尾相连形成闭环 | bool | true |
标系与光照参数
| 参数 | 联想 | 作用 | 代码示例 | 注意事项 |
|---|---|---|---|---|
| Use World Space | 地球仪 vs 桌面地球模型 | 控制线段顶点坐标的参考系: - true:使用世界坐标系(绝对位置)- false:使用局部坐标系(相对父物体) |
lr.useWorldSpace = false; |
移动物体上的线段建议使用局部坐标系 |
| Generate Lighting Data | 日光灯 vs 自发光灯管 | 是否受场景光照影响: - true:接受光照着色计算- false:保持材质原始颜色 |
lr.generateLightingData = true; |
需要材质支持光照着色器 |
颜色控制对比表
| 参数 | 适用场景 | 性能消耗 | 示例效果 |
|---|---|---|---|
单色模式startColor/endColor |
简单颜色变化(如激光) | 低 | 从红色渐变到透明红色 |
渐变模式colorGradient |
复杂颜色过渡(如彩虹) | 中 | 红→蓝→绿的多色渐变 |
| 贴图控制 材质纹理 |
动态纹理效果(如流动岩浆) | 高 | 沿线段运动的纹理图案 |
视觉参数表
| 参数 | 联想 | 作用 | 代码示例 |
|---|---|---|---|
| Start Width | 毛笔起笔力度 | 线段起始端宽度 | lr.startWidth = 0.1f |
| End Width | 毛笔收笔力度 | 线段末端宽度 | lr.endWidth = 0.5f |
| Color Gradient | 彩虹渐变 | 颜色过渡效果 | lr.colorGradient = myGradient |
高级参数表
| 参数 | 类比说明 | 效果演示 |
|---|---|---|
| Corner Vertices | 折纸的圆角处理 | 值=5时折角更圆滑 |
| End Cap Vertices | 笔尖的形状修饰 | 值=3时端点呈三角锥形 |
| Texture Mode | 桌布铺贴方式 | Tile/Stretch两种模式 |
三、怎么使用LineRender
完整LineRenderer使用示例
Step 1:基础对象创建
// ░▒▓ 创建线对象 ▓▒░
GameObject lineObj = new GameObject("DynamicLine");
lineObj.transform.SetParent(this.transform); // 设置为当前物体的子物体
LineRenderer line = lineObj.AddComponent<LineRenderer>();

看起来像个面片一样。
Step 2:基础参数配置
// ░▒▓ 线段形态设置 ▓▒░
//line.loop = true; // 闭环路径 这个闭环用起来有时候会非常奇怪 注意使用
line.positionCount = 5; // 5个顶点
line.startWidth = 0.5f; // 起始宽度
line.endWidth = 0.1f; // 结束宽度
//line.numCornerVertices = 3; // 转角圆滑度
//line.numCapVertices = 2; // 端点圆滑度

Step 3:材质与光照
// ░▒▓ 材质加载(需提前准备m.mat)▌
Material lineMat = Resources.Load<Material>("m");
line.material = lineMat;
// ░▒▓ 高级材质属性 ▓▒░
lineMat.EnableKeyword("_EMISSION"); // 启用自发光
lineMat.SetColor("_EmissionColor", Color.cyan * 0.8f); // 自发光颜色
// ░▒▓ 光照交互配置 ▓▒░
line.generateLightingData = false; // 受场景光照影响
line.shadowCastingMode = ShadowCastingMode.Off; // 不投射阴影
line.receiveShadows = true; // 接受其他物体阴影
看改掉了人家的材质,同时不受光.高级材质属性这个不会用,一般也很少使用。
Step 4:坐标系与顶点设置
// ░▒▓ 坐标系模式 ▓▒░
line.useWorldSpace = false; // 使用局部坐标系(随父物体移动)
// ░▒▓ 初始化顶点位置 ▓▒░
Vector3[] points = new Vector3[5] {
new Vector3(0, 0, 0),
new Vector3(2, 0, 0),
new Vector3(3, 2, 0),
new Vector3(1, 3, 0),
new Vector3(0, 0, 0) // 闭环终点
};
line.SetPositions(points);
// ░▒▓ 动态修改单个顶点 ▓▒░
line.SetPosition(2, new Vector3(2, 5, 0)); // 修改第三个点位置
这个点,一般来说一两个点就够了,起点和终点,没必要太多的点。
一般不会修改 难以控制
实现一个渐变色:
// ░▒▓ 在Update中实现 ▓▒░
void Update()
{
float pingPong = Mathf.PingPong(Time.time * 2, 1);
// 颜色渐变控制
Gradient gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[] {
new GradientColorKey(Color.red, 0),
new GradientColorKey(Color.blue, pingPong)
},
new GradientAlphaKey[] {
new GradientAlphaKey(1, 0),
new GradientAlphaKey(0.5f, 1)
}
);
lr.colorGradient = gradient;
// 自发光强度控制
lr.material.SetColor("_EmissionColor", Color.Lerp(Color.red, Color.blue, pingPong));
}
这个其实是渐变的 可以去试试
四、实战
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using UnityEngine;
using Color = UnityEngine.Color;
public class LineRenderFollow : MonoBehaviour
{
[Header("光束设置")]
public float beamLength = 3f; // 光束长度
public float beamWidthStart = 0.2f; // 起始宽度
public float beamWidthEnd = 0.05f; // 结束宽度
[Header("碰撞检测")]
public LayerMask collisionMask; // 碰撞层过滤
public Color collisionColor = Color.yellow; // 碰撞时的颜色
private LineRenderer lineRenderer;
private Gradient originalGradient;
private bool isColliding = false;
void Start() {
InitializeLineRenderer();
CreateColorGradient();
}
void Update() {
UpdateBeam();
HandleCollisionDetection();
}
// 初始化线段渲染器
void InitializeLineRenderer() {
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.useWorldSpace = true;
// 基本参数设置
lineRenderer.positionCount = 2;
lineRenderer.startWidth = beamWidthStart;
lineRenderer.endWidth = beamWidthEnd;
// 材质设置(使用默认材质)
lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
}
// 创建颜色渐变
void CreateColorGradient() {
originalGradient = new Gradient();
originalGradient.SetKeys(
new GradientColorKey[] {
new GradientColorKey(Color.blue, 0f),
new GradientColorKey(Color.red, 1f)
},
new GradientAlphaKey[] {
new GradientAlphaKey(1f, 0f),
new GradientAlphaKey(1f, 1f)
}
);
lineRenderer.colorGradient = originalGradient;
}
// 更新光束状态
void UpdateBeam() {
Vector3 startPoint = transform.position;
Vector3 endPoint = transform.position + transform.forward * beamLength;
lineRenderer.SetPosition(0, startPoint);
lineRenderer.SetPosition(1, endPoint);
}
// 处理碰撞检测
void HandleCollisionDetection() {
RaycastHit hit;
Vector3 direction = transform.forward;
float maxDistance = beamLength;
if (Physics.Raycast(transform.position, direction, out hit, maxDistance, collisionMask)) {
if (!isColliding) {
OnCollisionStart(hit);
}
UpdateCollisionVisual(hit.point);
} else {
if (isColliding) {
OnCollisionEnd();
}
}
}
// 碰撞开始处理
void OnCollisionStart(RaycastHit hit) {
isColliding = true;
Debug.Log("碰撞对象: " + hit.collider.name);
// 调整线段终点到碰撞点
lineRenderer.SetPosition(1, hit.point);
// 改变颜色为警告色
Gradient newGradient = new Gradient();
newGradient.SetKeys(
new GradientColorKey[] {
new GradientColorKey(collisionColor, 0f),
new GradientColorKey(collisionColor, 1f)
},
originalGradient.alphaKeys
);
lineRenderer.colorGradient = newGradient;
}
// 碰撞结束处理
void OnCollisionEnd() {
isColliding = false;
lineRenderer.colorGradient = originalGradient;
}
// 更新碰撞视觉效果
void UpdateCollisionVisual(Vector3 collisionPoint) {
lineRenderer.SetPosition(1, collisionPoint);
}
}
LineRenderer 参数与API完整参考表
一、基础属性
| 属性/API | 类型/参数 | 返回值 | 示例 | 说明 | 常用度 |
|---|---|---|---|---|---|
| positionCount | int |
- | lr.positionCount = 4; |
设置线段顶点数量 | ★★★★★ |
| loop | bool |
- | lr.loop = true; |
是否首尾相连 | ★★★★☆ |
| useWorldSpace | bool |
- | lr.useWorldSpace = false; |
使用世界/局部坐标系 | ★★★★☆ |
| startWidth | float |
- | lr.startWidth = 0.2f; |
线段起始宽度 | ★★★★★ |
| endWidth | float |
- | lr.endWidth = 0.05f; |
线段末端宽度 | ★★★★★ |
| widthCurve | AnimationCurve |
- | lr.widthCurve = myCurve; |
通过曲线控制宽度 | ★★★☆☆ |
| startColor endColor |
Color |
- | lr.startColor = Color.blue; |
起始/结束颜色 | ★★★★☆ |
| colorGradient | Gradient |
- | lr.colorGradient = myGradient; |
颜色渐变控制 | ★★★★★ |
| material | Material |
- | lr.material = myMat; |
设置渲染材质 | ★★★★★ |
二、高级属性
| 属性/API | 类型/参数 | 返回值 | 示例 | 说明 | 常用度 |
|---|---|---|---|---|---|
| numCornerVertices | int |
- | lr.numCornerVertices = 5; |
折角圆滑顶点数 | ★★★☆☆ |
| numCapVertices | int |
- | lr.numCapVertices = 3; |
端点圆滑顶点数 | ★★★☆☆ |
| textureMode | LineTextureMode |
- | lr.textureMode = LineTextureMode.Tile; |
贴图映射模式 | ★★☆☆☆ |
| shadowCastingMode | ShadowCastingMode |
- | lr.shadowCastingMode = ShadowCastingMode.Off; |
阴影投射设置 | ★★☆☆☆ |
| generateLightingData | bool |
- | lr.generateLightingData = true; |
是否接受光照 | ★★★☆☆ |
| alignment | LineAlignment |
- | lr.alignment = LineAlignment.View; |
线段对齐方式 | ★☆☆☆☆ |
三、核心API方法
| 方法 | 参数 | 返回值 | 示例 | 说明 | 常用度 |
|---|---|---|---|---|---|
| SetPosition | (int index, Vector3 position) |
- | lr.SetPosition(0, transform.position); |
设置单个顶点位置 | ★★★★★ |
| GetPosition | int index |
Vector3 |
Vector3 pos = lr.GetPosition(2); |
获取顶点位置 | ★★★★☆ |
| SetPositions | Vector3[] positions |
- | lr.SetPositions(pointsArray); |
批量设置顶点 | ★★★★★ |
| Simplify | (float tolerance) |
- | lr.Simplify(0.1f); |
简化线段顶点 | ★★★☆☆ |
| BakeMesh | (Mesh mesh, bool useTransform) |
- | lr.BakeMesh(myMesh, true); |
生成线段网格 | ★★☆☆☆ |
四、材质相关属性
| 属性 | 类型 | 示例 | 说明 | 常用度 |
|---|---|---|---|---|
| material.mainTexture | Texture |
lr.material.mainTexture = myTex; |
主贴图设置 | ★★★★☆ |
| material.mainTextureScale | Vector2 |
lr.material.mainTextureScale = new Vector2(2,1); |
贴图缩放 | ★★★☆☆ |
| material.mainTextureOffset | Vector2 |
lr.material.mainTextureOffset += Vector2.right * Time.deltaTime; |
贴图偏移 | ★★★☆☆ |
五、性能相关属性
| 属性 | 类型 | 示例 | 说明 | 常用度 |
|---|---|---|---|---|
| allowOcclusionWhenDynamic | bool |
lr.allowOcclusionWhenDynamic = true; |
动态遮挡优化 | ★★☆☆☆ |
| lightProbeUsage | LightProbeUsage |
lr.lightProbeUsage = LightProbeUsage.Off; |
光照探针设置 | ★☆☆☆☆ |
| receiveShadows | bool |
lr.receiveShadows = false; |
是否接收阴影 | ★★☆☆☆ |
这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!
更多推荐


所有评论(0)