今天来分享一下Untiy中实现闪电链的方法,实际在项目中使用,效果不错。
国际惯例:
来张会动的:
工程放在:https://github.com/aceyan/UnityEffects 使用unity5.4
场景是Scene/(3)ChainLightning
使用了unity的lineRender来模拟闪电的效果:
主要功能都在UVChainLightning这个脚本中:
using System;
using System.Collections.Generic;
using UnityEngine;
///
/// uv贴图闪电链
///
[RequireComponent(typeof(LineRenderer))]
[ExecuteInEditMode]
public classUVChainLightning :MonoBehaviour
{
//美术资源中进行调整
public float detail = 1;//增加后,线条数量会减少,每个线条会更长。
public float displacement = 15;//位移量,也就是线条数值方向偏移的最大值
public Transform target;//链接目标
public Transform start;
public float yOffset = 0;
private LineRenderer _lineRender;
private List _linePosList;
private void Awake()
{
_lineRender =GetComponent();
_linePosList = new List();
}
private void Update()
{
if(Time.timeScale != 0)
{
_linePosList.Clear();
Vector3 startPos =Vector3.zero;
Vector3 endPos =Vector3.zero;
if (target != null)
{
endPos =target.position + Vector3.up *yOffset;
}
if(start != null)
{
startPos =start.position + Vector3.up *yOffset;
}
CollectLinPos(startPos,endPos, displacement);
_linePosList.Add(endPos);
_lineRender.SetVertexCount(_linePosList.Count);
for (int i = 0, n = _linePosList.Count; i< n; i++)
{
_lineRender.SetPosition(i, _linePosList[i]);
}
}
}
//收集顶点,中点分形法插值抖动
private void CollectLinPos(Vector3 startPos,Vector3 destPos,float displace)
{
if (displace < detail)
{
_linePosList.Add(startPos);
}
else
{
float midX = (startPos.x + destPos.x) / 2;
float midY = (startPos.y + destPos.y) / 2;
float midZ = (startPos.z + destPos.z) / 2;
midX += (float)(UnityEngine.Random.value - 0.5) * displace;
midY += (float)(UnityEngine.Random.value - 0.5) * displace;
midZ += (float)(UnityEngine.Random.value - 0.5) * displace;
Vector3 midPos =newVector3(midX,midY,midZ);
CollectLinPos(startPos,midPos, displace / 2);
CollectLinPos(midPos,destPos, displace / 2);
}
}
}
代码十分简单,可以看到使用了一个递归的分治算法来生成闪电链各段的位置。然后设置lineRender的position集合来模拟闪电效果,加入uv动画效果更佳:) 也可以根据需要优化成迭代算法。
原理原文:http://krazydad.com/bestiary/bestiary_lightning.html
=。=好像原文挂掉了,记得原文是带flash演示的,莫非因为flash日薄西山了,作者就把原文“下架”了?为flash默哀…
下面搬运一下雷文顿大神对原文的翻译,原文:http://blog.csdn.net/u012945598/article/details/18862091
这部短片使用了中点位移法来模拟闪电。
中点位移法通常是用于生成分形地形的算法,你会发现闪电的形状类似于一个理想化的山脉的边缘。
下面节选的这段闪电递归程序可以帮你完成所有的工作。
function drawLightning(x1,y1,x2,y2,displace)
{
if (displace
graf.moveTo(x1,y1);
graf.lineTo(x2,y2);
}
else {
varmid_x = (x2+x1)/2;
varmid_y = (y2+y1)/2;
mid_x+= (Math.random()-.5)*displace;
mid_y+= (Math.random()-.5)*displace;
drawLightning(x1,y1,mid_x,mid_y,displace/2);
drawLightning(x2,y2,mid_x,mid_y,displace/2);
}
}
你可以通过传递一个线段的两个端点坐标(x1,y1,x2,y2)和一个位移量,计算出线段终点坐标(mid_x,mid_y),然后通过一个随机值替换它,该随机值按照每次划分线段时的位移值比例减少。
第一次划分会得到一个较大的位移线段,而之后随着位移值的减小位移线段也会逐渐减小(每次递归位移值都会除以2),如此便可以使一条线段"碎形"。
当位移值低于我们定义的最小值时(可使用"detail"滑动条修改),我们就将这条线绘制出来。也就是说满足条件if(displace 原文中的四个滑动条: 1.detail 增加后,线条数量会减少,每个线条会更长。 2.thickness 代表线条的粗细 3.number bolts 代表线条的数量 4.displacement 位移量,也就是线条数值方向偏移的最大值 Ps:之前在Untiy 的Asset Store还看到这么一个闪电效果的插件 https://www.assetstore.unity3d.com/en/#!/content/5141 看了代码发现是粒子系统模拟的,生成很多的粒子连接起来模拟闪电的效果。效果会比较”浓厚一些”。后来也模仿着在游戏中实现了一个,发现粒子少了容易穿帮,粒子多了性能成问题,所以这个粒子模拟的方式不推荐手游使用。