简单粒子制作
实现要求
制作一个粒子系统魔法球,点击魔法球,产生特效,特效粒子沿着一定的轨迹运动
实现过程
制作魔法球和特效粒子
- 魔法球又分为光晕与星光两个粒子系统,这个粒子系统的制作和资源是参考博客传送门。
- 特效粒子的Start Speed为0(因为之后的代码将会去设置速度,这里防止初始速度的影响),Shape使用的是Box,其他设置见完整项目。
实现沿路径移动
在游戏开始的时候,得到粒子将要经过的点的坐标,然后计算出粒子按照时间变化速度的向量应该怎样变化,并分别绘制成x轴,y轴,z轴的速度随时间变化曲线。这样就可以实现粒子沿着设定的路径移动。这里使用
AnimationCurve
来保存不同坐标轴的数值变化曲线,AnimationCurve
生成的曲线还可以用于曲线地形,曲线轨迹等。在该曲线中插入的关键帧是Keyframe
,构造函数参数中的float.PositiveInfinity
代表构造Keyframe
时候,帧与帧之间变化时曲线切线正切值为无穷大,也就是90度。
- 代码如下
public struct FrameDate
{
//方向
public Vector3 direction;
//距离
public float distance;
public FrameDate(Vector3 dir, float dis)
{
direction = dir;
distance = dis;
}
}
public class ParticlePath : MonoBehaviour
{
//粒子系统
public ParticleSystem particle;
//路径指定达到的点的坐标
public List<Vector3> points;
//每个坐标轴的速度变化曲线
private AnimationCurve curveX = new AnimationCurve();
private AnimationCurve curveY = new AnimationCurve();
private AnimationCurve curveZ = new AnimationCurve();
//关键帧所需要保存的信息
private Queue<FrameDate> frames = new Queue<FrameDate>();
void Start()
{
if (points.Count > 1)
{
//设置粒子发生点
particle.transform.position = points[0];
//路径的总长
float totalDistance = 0;
for (int i = 1; i < points.Count; i++)
{
//与下一个点距离
float dis = Vector3.Distance(points[i], points[i - 1]);
//向下一个点方向
Vector3 dir = points[i] - points[i - 1];
dir.Normalize();
frames.Enqueue(new FrameDate(dir, dis));
totalDistance += dis;
}
float time = 0;
while (frames.Count > 0)
{
//关键帧的数据
FrameDate data = frames.Dequeue();
//将当前时刻和坐标轴值作为关键帧添加进曲线
curveX.AddKey(new Keyframe(time, data.direction.x, float.PositiveInfinity, float.PositiveInfinity));
curveY.AddKey(new Keyframe(time, data.direction.y, float.PositiveInfinity, float.PositiveInfinity));
curveZ.AddKey(new Keyframe(time, data.direction.z, float.PositiveInfinity, float.PositiveInfinity));
//设置下一时刻的关键帧
time += (data.distance / totalDistance);
}
//设置粒子随着时间变化的速度
var velocity = particle.velocityOverLifetime;
velocity.enabled = true;
velocity.space = ParticleSystemSimulationSpace.Local;
//单位时间需要移动的长度
float distancePerTime = totalDistance / particle.startLifetime;
velocity.x = new ParticleSystem.MinMaxCurve(distancePerTime, curveX);
velocity.y = new ParticleSystem.MinMaxCurve(distancePerTime, curveY);
velocity.z = new ParticleSystem.MinMaxCurve(distancePerTime, curveZ);
}
}
}
- 绘制的轨迹如下
实现效果
小结
用代码控制粒子,就是控制粒子的属性,让粒子的行为达到我们想要的效果。让粒子沿着特定路线移动因为绘制的曲线变化时候都是90度,所以轨迹有些生硬,有博客写了可视化编辑曲线,而不是在游戏运行时候生成曲线,这样更容易调整变化的轨迹,博客链接,本次作业也是参考该博客。在运行时候改变粒子的方向也不一定先绘制速度变化曲线,可以在运行时候根据时间来实时改变粒子的速度。
完整项目请点击传送门