Unity学习笔记(4)—–粒子效果的实现

一.效果展示

下面用若干张张动图展示效果:

大概就是这样,并不是很难。 实际效果要比图中的好一点(顺畅得多)。

实现步骤

大致可以分为如下几个步骤,然后逐个实现就可以了:

  1. 生产粒子
  2. 设置粒子初始属性(位置, 颜色, 速度等)
  3. 控制粒子旋转
  4. 改变粒子颜色
  5. 让颜色均匀旋转

    下面分步骤说明。

1.生产粒子

首先我们需要一个ParticleSystem的组件来管理这个粒子系统。 再让组件附着在一个空对象上即可。结构如图:

如图中那样, 我们在这个含有particle System的对象上挂载脚本, 准备对这个粒子系统进行控制。

在写脚本之前, 先对Particle System 进行一些必要的设置, 这样可以在测试脚本的时候看起来更舒服 :), 如图:

嘛, 由于我们都是代码控制, 下面的属性几乎都可以不勾选, renderer除外。 记得给renderer设置一个好看的Material啊 : )

这些都是为粒子能够正常产生做准备。 这些做好后, 就可以开始写脚本控制了, 产生粒子的相关代码如下:(只是产生的话, 超简单!)

using UnityEngine;
using System.Collections;
public class ParticleSea : MonoBehaviour {public ParticleSystem particleSystem;private ParticleSystem.Particle[] particlesArray;public int seaResolution = 25;void Start() {particlesArray = new ParticleSystem.Particle[seaResolution * seaResolution];particleSystem.maxParticles = seaResolution * seaResolution;particleSystem.Emit(seaResolution * seaResolution);particleSystem.GetParticles(particlesArray);}
}

这些变量的含义:

particle System: 用来得到这个Object的particle System(在Inspector中记得把当前的Particle System 拖给脚本变量)
particlesArray: 用来存放粒子系统所产生的粒子的数组。
seaResolution: 粒子海洋的长度(实际粒子数是这个数的平方)。

Ps : 之所以不改为直接用粒子数表示有两个原因:

  1. 之前我参考的教程的粒子实现时用的这个, 我写这个的时候因为懒直接在那个的基础上做了 ~。~
  2. 事实上写完想改的时候发现这样可以给粒子简单的分层。有一定的可拓展性(好吧其实没有什么用)

In all, 这样做之后创建过程就完成了。

2.设置粒子初始属性

首先考虑我们需要粒子的哪些属性:

  1. 粒子速度 speed
  2. 粒子旋转的半径 radius
  3. 粒子当前旋转角度 angle
ps:粒子位置是可以通过 radius 和 angle 确定的。

考虑到这些, 创建一个类用于表示粒子的属性是个看起来不错的选择。代码如图:

public class particleSettings{public float angle { get; set; }public float radius{ get; set;}public float speed { get; set; }public particleSettings(float r) {this.radius = r;this.angle = Random.value * 2 * Mathf.PI;this.speed = Random.value * Mathf.Sqrt(radius);}public Vector3 getPosition() {return radius * new Vector3 (Mathf.Cos(angle), 0, Mathf.Sin(angle));}public void rotate() {this.angle += Time.deltaTime * speed / 10;if (this.angle > 2 * Mathf.PI)this.angle -= 2 * Mathf.PI;this.radius += Random.value * 0.2f - 0.1f;if (this.radius > ParticleSea.MaxRadius)this.radius = ParticleSea.MaxRadius;if (this.radius < ParticleSea.MinRadius)this.radius = ParticleSea.MinRadius;}
}

方法getPosition就是根据radius和angle计算当前位置, 而rotate则是计算经过一帧的rotate后,该粒子的新参数。这里设置了一个MaxRadius和MinRadius, 是保证粒子的活动范围在一个圆环内。

很明显这样写之后, 我们的主类代码要发生相应变化, 如下:

using UnityEngine;
using System.Collections;public class particleSettings{public float angle { get; set; }public float radius{ get; set;}public float speed { get; set; }public particleSettings(float r) {this.radius = r;this.angle = Random.value * 2 * Mathf.PI;this.speed = Random.value * Mathf.Sqrt(radius);}public Vector3 getPosition() {return radius * new Vector3 (Mathf.Cos(angle), 0, Mathf.Sin(angle));}public void rotate() {this.angle += Time.deltaTime * speed / 10;if (this.angle > 2 * Mathf.PI)this.angle -= 2 * Mathf.PI;this.radius += Random.value * 0.2f - 0.1f;if (this.radius > ParticleSea.MaxRadius)this.radius = ParticleSea.MaxRadius;if (this.radius < ParticleSea.MinRadius)this.radius = ParticleSea.MinRadius;}
}public class ParticleSea : MonoBehaviour {public ParticleSystem particleSystem;private ParticleSystem.Particle[] particlesArray;private particleSettings[] psetting;public int seaResolution = 25;public static float MaxRadius = 120f;public static float MinRadius = 50f;public float radius = 100.0f;public Gradient colorGradient;void Start() {particlesArray = new ParticleSystem.Particle[seaResolution * seaResolution];psetting = new particleSettings[seaResolution * seaResolution];particleSystem.maxParticles = seaResolution * seaResolution;particleSystem.Emit(seaResolution * seaResolution);particleSystem.GetParticles(particlesArray);setInitialPosition ();}void Update() {RotateParticles ();changeColor ();particleSystem.SetParticles(particlesArray, particlesArray.Length);}
}

这里我将整个代码结构贴出了。后续步骤就是对这个结构中功能函数实现。那么开始实现的第一步: 设置初始粒子的属性。这里对应代码中的 setInitialPosition () 函数
很明显, 我们只要把particleSetting按照写好的构造函数构建出来, 直接设置其位置就可以了。
函数实现如下:

    void setInitialPosition () {for (int i = 0; i < seaResolution; i++) {for (int j = 0; j < seaResolution; j++) {psetting[i * seaResolution + j] = new particleSettings(radius);particlesArray [i * seaResolution + j].position = psetting[i * seaResolution + j].getPosition();}}particleSystem.SetParticles(particlesArray, particlesArray.Length);}
ps: 在对数组中粒子修改之后记得要set到Particle System 中去 :)

第二步也就完成了。

3.控制粒子旋转

这一步就是补充上面代码中的 RotateParticles() 函数。
因为之前在particleSettings类中, 我们已经写好这个方法, 所以直接用就可以了。
代码如下:

    void RotateParticles () {for (int i = 0; i < seaResolution; i++) {for (int j = 0; j < seaResolution; j++) {psetting [i * seaResolution + j].rotate ();particlesArray [i * seaResolution + j].position = psetting [i * seaResolution + j].getPosition ();}}}

第三步也就完成了:) 做到这里差不多可以看一下效果了, 把update中的changeColor()先注释掉, 运行。

大概是这样的效果:

下面是加特效时间hh。

4.改变粒子颜色

这要用到类里面的 public Gradient colorGradient 这个成员。
首先到Inspector里, 看看这是个什么:

中央的这根色彩轴按照从左到右,Location值从小到大设置相应的色彩。在这里, Unity帮我们自动渐变了, 我们要做的就是设置那几个关键Location的色彩(和动画的关键帧的作用很像!)
上面那排红色箭头指的是当前Location的Alpha值(透明度), 下面黑色箭头是设置该Location的颜色。
在轴的上方或下方, 右键, 可以自行添加关键位置。(Alpha和Color可以分开设置关键位置)
做好了自己的调色板之后,点下方的“New”可以保存。

然后我们要做的, 就是写代码控制Gradient的行为就可以了。
主要通过 colorGradient.Evaluate(float)来得到相应的调色板的颜色。
先写这样的代码试试看颜色效果:

    void changeColor () {for (int i = 0; i < seaResolution; i++) {for (int j = 0; j < seaResolution; j++) {particlesArray [i * seaResolution + j].color = colorGradient.Evaluate (Random.value);}}}

如果, 之前的Gradient用的和我上面图中一样的话 大致应该是这样的效果:

黄色是红和绿混合的结果~ 这图让我想到显像管电视机…
接下来继续加特效~

5.让颜色均匀旋转

其实这步就是对刚才的changeColor ()函数改造就行了, 很明显 这样直接Random效果 不会很好.
这里其实就是让填入Evaluate的值, 显然一定和angle相关, 但是又不仅和Angle相关。 如果仅仅和angle相关, 那么其实是得到一圈固定的颜色, 而不能旋转。
我的做法是, 加入一个时间变量, 和angle值共同决定value。 一行代码胜千言:

    void changeColor () {for (int i = 0; i < seaResolution; i++) {for (int j = 0; j < seaResolution; j++) {float value = (Time.realtimeSinceStartup - Mathf.Floor (Time.realtimeSinceStartup));value+= psetting [i * seaResolution + j].angle / 2 / Mathf.PI;while (value > 1)value--;particlesArray[i * seaResolution + j].color = colorGradient.Evaluate(value);//particlesArray [i * seaResolution + j].color = colorGradient.Evaluate (Random.value);}}}

至此效果就都有了~ 如果调色板用的是上面那个Red-Green-Red, 那么效果如下:

通过Alpha值的组合, 可以产生更多的炫酷效果~ 例如只设置Alpha不改color, 两端alpha设置为255, 中间设置为0, 可以看到明显的明暗相间效果:)

最后填个坑,关于拓展性的问题。

事实上 seaResolution 相当于对粒子进行分层了, 但是简单的直接设置为粒子数然后之后用求余方法好像是等效的orz… 就简单举一个例子吧:
重写这个方法如下:

    void RotateParticles () {for (int i = 0; i < seaResolution; i++) {for (int j = 0; j < seaResolution; j++) {if(Random.Range(0, seaResolution) < 2 * i) psetting [i * seaResolution + j].rotate ();particlesArray [i * seaResolution + j].position = psetting [i * seaResolution + j].getPosition ();}}}  

比起之前加了个对i的判断,进一步操作罢了。 实用性不强。 估计还是要改成直接用粒子数好一点…

不过, 把刚才做好的这个做成prefab, 然后多弄几个到画面中来, 感觉还是挺棒的(只要修改radius和seaResolution值就好), 如下:

还是那句话: 真实效果更好看, 更流畅…

到这之后,然后大家就可以随意发挥了,自己设置好看的调色板, 应该效果还会更好一点。

The End.

Unity学习笔记(4)-----粒子效果的实现相关推荐

  1. unity学习笔记-特效篇

    unity学习笔记 传送门特效 火焰特效 传送门特效 由于动画师的动画制作遇到了一些小问题,只能先做其他功能的摸索了~ 本来想记录一下服务器搭建的,但是在消息传输的部分遇到了一些bug,可能是消息解析 ...

  2. unity学习笔记-番外(3d模型的动作设计以及导入-2018版)材质的替换以及动作穿模(自己的手穿模到自己的其他部位)

    unity学习笔记-番外(3d模型的动作设计以及导入) 动作设计白嫖方法 方法一:小k网 需要注意的地方 方法二:mixamo 需要注意的地方 材质的替换 一 动作的穿模 2021.5.13更新 -2 ...

  3. 【Unity学习笔记】b站Unity架构课Unity3D 商业化的网络游戏架构(高级/主程级别)

    [Unity学习笔记]b站Unity架构课Unity3D 商业化的网络游戏架构(高级/主程级别) 自己跟着学完了,写了不少代码,会放在CSDN代码库,因为老师并没有提供源码,录屏也不是完全连续,所以难 ...

  4. [Unity学习笔记:FPS游戏制作(3)]子弹拖尾,碰撞与枪口火焰效果

    往期博客[Unity学习笔记:FPS游戏制作(2)] 发射子弹----(2021.6.20学习笔记) 文章目录 一,实现思路 二,粒子效果的实现 (1)子弹拖尾特效的实现 (2)枪口火焰特效的实现 ( ...

  5. Unity学习笔记1 简易2D横版RPG游戏制作(一)

    这个教程是参考一个YouTube上面的教程做的,原作者的教程做得比较简单,我先参考着做一遍,毕竟我也只是个初学者,还没办法完全自制哈哈.不过我之前也看过一个2D平台游戏的系列教程了,以后会整合起来,做 ...

  6. 【Unity学习笔记】[Unity中文课堂教程] C#中级编程代码

    [Unity学习笔记][Unity中文课堂教程] C#中级编程代码 最近想补一补C#基础,Unity官方的C#中级编程教程质量很高,于是开个帖子把跟着敲+记录了部分价讲解和我自己的理解的代码存在这 原 ...

  7. Unity学习笔记:Unity 3D 飞机大战

    Unity学习笔记:Unity 3D 飞机大战 1.打开unity软件后,首先新建Quad作为背景,导入飞机模型,并为其添加刚体 然后创建C#脚本,挂载到飞机上. 2.给飞机创建子弹,让子弹成为预制体 ...

  8. Unity学习笔记—二次元日系游戏制作(实践篇-游戏初始化场景制作)

    原教程:siki:二次元日系游戏制作工具 - live2dSDK入门教程 http://www.sikiedu.com/my/course/282 (上)Unity学习笔记-二次元日系游戏制作(理论篇 ...

  9. unity学习笔记-text文本识别html富文本(待改进)

    unity学习笔记 text文本识别html富文本(待改进) 需求 逻辑 实现 xlua的安装 配置到unity 使用 改进优化(待改进) text文本识别html富文本(待改进) 需求 项目里需要将 ...

最新文章

  1. Introduction to the Service Provider Interfaces--官方文档
  2. ffmpeg+nginx+video实现rtsp流转hls流,通过H5查看监控视频
  3. 求n个数的最大公因数和最小公倍数(c)
  4. boost::ratio_greater相关的测试程序
  5. 学习笔记(54):Python实战编程-Scale
  6. mysql 插入中文 ERROR 1366 (HY000): Incorrect string value: '\xE7\x8E\x9E\x97' for column
  7. 【C语言进阶深度学习记录】五 C语言中变量的属性
  8. Qt 获取qrc文件列表
  9. Vue在Nginx的使用
  10. 应广单片机长按开关机_单键实现单片机开关机
  11. java实现T检验(Ttest)
  12. Linux软件安装失败问题,source.list用了bionic,实际上我的Linux是focal版本
  13. EasyPusher进行Android UVC外接摄像头直播推送实现方法
  14. 基于NRF52832蓝牙芯片的电子价签(电子墨水屏)
  15. 这篇 Linux 总结的很棒啊!
  16. 史上最全!234个财务数据分析数据指标归纳总结
  17. linux lamp源码安装包下载,Linux Lamp源码安装
  18. sql 导入linux问题:ASCII '\0' appeared in the statement, but this is not allowed unless option --binary-m
  19. Android 查看当前应用的线程数是否超限
  20. Java系列技术之Spring5框架-钟洪发-专题视频课程

热门文章

  1. iOS苹果内购详细步骤
  2. 股票交易日志3 12.15
  3. Day25 LeetCode 216. 组合总和 III 17. 电话号码的字母组合
  4. 林轩田机器学习基石Lecture 6: Theory of Generalization
  5. A40i使用笔记:时区设置
  6. 安卓UI图px标注适配攻略:批量转化px为dp
  7. html唯美登录+樱花落下实现(复制即用)
  8. 微信小程序转头条/抖音小程序的方法
  9. 试试这几个简单好用的手机小技巧吧
  10. 如何用今日头条来赚钱?那些闷声发大财的达人们都是这样做的