【unity实现】在Unity使用TrailRenderer、LineRenderer两种方式实现水果忍者切水果的刀痕效果教程
本文介绍了在Unity中实现水果忍者刀痕效果的两种方法:使用TrailRenderer和LineRenderer组件。TrailRenderer通过控制物体移动自动生成拖尾效果,而LineRenderer需要手动计算每个点的坐标。文章详细讲解了资源准备、材质球制作以及两种实现方式的代码逻辑,并提供了GitHub项目地址供参考学习。两种方法最终都能实现流畅的刀痕效果,开发者可根据需求选择适合的方案。
文章目录
一、前言
相信很多人都玩过水果忍者,在屏幕上滑手指头切水果,效果如下:
这个手指头滑来滑去的刀痕效果,如果使用Unity
如何实现呢?
今天我就来讲讲两种实现方式:
方式一:TrailRenderer
;
方式二:LineRenderer
。
最终两种方式的效果如下。
本Demo
工程我已上传到GitHub
,感兴趣的同学可以自行下载学习(注:我使用的Unity
版本为:2019.4.17f1c1
)GitHub
地址:https://github.com/linxinfa/UnityLineRendererAndTrailRendererDemo
二、资源准备
先把必要的资源导入到Unity
工程中。两张刀痕素材图。
(注:两种刀痕素材图会分别用作用于下文中要说的TrailRenderer
和LineRenderer
)。
如下,
注意图片设置勾选Alpha Is Transparency
。
三、制作材质球
创建trail
和trail_2
材质球,使用的shader
为Mobile/Particles/Additive
。
四、刀痕的实现,方式一:TrailRenderer
TrailRenderer
组件可以很方便地实现一个拖尾效果,我们只需控制所挂的物体的移动即可出现拖尾效果。
1、创建物体挂TrailRenderer组件
首先,在场景中创建一个空物体,重命名为trailrenderer
。
挂上TrailRenderer
组件。并设置一下各个参数:Width
:线段宽度;Time
:线段持续时间;Min Vertex Distance
:点与点之间的最小距离;Color
:线段颜色;Texture Mode
:线段贴图填充模式;Materials
:材质球;
2、编写TrailRendererBehaviour脚本
接着就是使用脚本来获取鼠标的位置并控制物体的移动。
创建一个脚本:TrailRendererBehaviour
,挂到物体上,
代码如下:
// TrailRendererBehaviour.cs
using UnityEngine;
public class TrailRendererBehaviour : MonoBehaviour
{
public TrailRenderer trailrenderer;
Transform mSelfTrans;
/// <summary>
/// 线段的z轴坐标
/// </summary>
const float LINE_POS_Z = 10;
void Awake()
{
mSelfTrans = transform;
}
void Update()
{
if(Input.GetMouseButtonDown(0))
{
// 停止划线,防止坐标瞬移导致出现一个拖尾
trailrenderer.emitting = false;
var mousPos = Input.mousePosition;
mSelfTrans.position = Camera.main.ScreenToWorldPoint(new Vector3(mousPos.x, mousPos.y, LINE_POS_Z));
return;
}
if(Input.GetMouseButton(0))
{
trailrenderer.emitting = true;
var mousPos = Input.mousePosition;
mSelfTrans.position = Camera.main.ScreenToWorldPoint(new Vector3(mousPos.x, mousPos.y, LINE_POS_Z));
}
}
}
3、运行测试
运行Unity
,测试效果如下:
五、刀痕的实现,方式二:LineRenderer
LineRenderer
组件可以很方便地实现划线功能,不过,不像TrailRenderer
那样可以自动根据物体移动划出拖尾痕迹,需要我们自己去计算划痕的每个点的坐标并赋值给LineRenderer
的点。
1、创建物体挂LineRenderer组件
首先,创建一个空物体,重命名为linerenderer
。
挂上LineRenderer
组件,并设置Positions
的Size
为10
,即:我们使用10
个点来画线。
记得设置一下材质球:
2、编写LineRendererBehaviour脚本
创建一个LineRendererBehaviour
脚本,挂到物体上。
我们在LineRendererBehaviour
脚本中去获取鼠标移动的位置并设置给LineRenderer
组件的各个点的坐标。
代码如下,基本我都写了清晰的注释,大家应该能看懂。
// LineRendererBehaviour.cs
using UnityEngine;
public class LineRendererBehaviour : MonoBehaviour
{
public LineRenderer linerenderer;
/// <summary>
/// 线段的z轴坐标
/// </summary>
const float LINE_POS_Z = 10;
/// <summary>
/// 线段的点的数量
/// </summary>
const int LINE_POS_CNT = 10;
/// <summary>
/// 坐标点的数组
/// </summary>
Vector3[] mLinePosList = new Vector3[LINE_POS_CNT];
/// <summary>
/// 鼠标的屏幕坐标
/// </summary>
Vector3 mMouseScreenPos;
/// <summary>
/// 是否是按下
/// </summary>
bool mFire = false;
/// <summary>
/// 上一次是否是按下
/// </summary>
bool mFirePre = false;
/// <summary>
/// 是否是刚按下
/// </summary>
bool mFireDown = false;
/// <summary>
/// 是否是抬起
/// </summary>
bool mFireUp = false;
/// <summary>
/// 坐标的起始和终止坐标点
/// </summary>
Vector2 mStart, mEnd;
/// <summary>
/// 坐标点索引
/// </summary>
int mLinePosIndex = 0;
/// <summary>
/// 线段的alpha通道值
/// </summary>
float mTrailAlpha = 0f;
void Update()
{
// 鼠标的位置
mMouseScreenPos = Input.mousePosition;
mFireDown = false;
mFireUp = false;
mFire = Input.GetMouseButton(0);
if (mFire && !mFirePre) mFireDown = true;
if (!mFire && mFirePre) mFireUp = true;
mFirePre = mFire;
// 画线
DrawLine();
// 设置线段颜色,主要是设置alpha值,慢慢变淡
SetLineColor();
}
void SetLineColor()
{
if (mTrailAlpha > 0)
{
// 黄色
linerenderer.startColor = new Color(1, 1, 0, mTrailAlpha);
// 红色
linerenderer.endColor = new Color(1, 0, 0, mTrailAlpha);
// 慢慢变透明
mTrailAlpha -= Time.deltaTime * 2;
}
}
/// <summary>
/// 画线
/// </summary>
void DrawLine()
{
// 鼠标按下
if (mFireDown)
{
mStart = mMouseScreenPos;
mEnd = mMouseScreenPos;
mLinePosIndex = 0;
mTrailAlpha = 1;
AddTrailPoint();
}
// 鼠标滑动中
if (mFire)
{
mEnd = mMouseScreenPos;
var pos1 = Camera.main.ScreenToWorldPoint(new Vector3(mStart.x, mStart.y, LINE_POS_Z));
var pos2 = Camera.main.ScreenToWorldPoint(new Vector3(mEnd.x, mEnd.y, LINE_POS_Z));
// 滑动距离超过0.1才算作一次有效的滑动
if (Vector3.Distance(pos1, pos2) > 0.01f)
{
mTrailAlpha = 1;
++mLinePosIndex;
// 添加坐标点到数组中
AddTrailPoint();
}
mStart = mMouseScreenPos;
}
// 将坐标数组赋值给LineRenderer组件
SetLineRendererPos();
}
/// <summary>
/// 添加坐标点到数组中
/// </summary>
void AddTrailPoint()
{
if (mLinePosIndex < LINE_POS_CNT)
{
for (int i = mLinePosIndex; i < LINE_POS_CNT; ++i)
{
mLinePosList[i] = Camera.main.ScreenToWorldPoint(new Vector3(mEnd.x, mEnd.y, LINE_POS_Z));
}
}
else
{
for (int i = 0; i < LINE_POS_CNT - 1; ++i)
{
mLinePosList[i] = mLinePosList[i + 1];
}
mLinePosList[LINE_POS_CNT - 1] = Camera.main.ScreenToWorldPoint(new Vector3(mEnd.x, mEnd.y, LINE_POS_Z));
}
}
/// <summary>
/// 将坐标数组赋值给LineRenderer组件
/// </summary>
void SetLineRendererPos()
{
for (int i = 0; i < LINE_POS_CNT; ++i)
{
linerenderer.SetPosition(i, mLinePosList[i]);
}
}
}
3、运行测试
运行Unity
,测试效果如下:
专栏推荐
完结
好了,我是向宇
,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
更多推荐
所有评论(0)