3D游戏编程实践——粒子光环

2024-01-25 01:20

本文主要是介绍3D游戏编程实践——粒子光环,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

编程实践——粒子光环

github地址:https://github.com/ctlchild/SYSU-unity3d-learning/tree/master/hw7

实验过程

首先创建空对象,命名为Particle,然后创建其子对象,命名为Clockwise_outer

在这里插入图片描述

Clockwise_outer中点击Add Component,输入Particle System,添加粒子系统

在这里插入图片描述

接下来是代码部分

我们需要一个CirclePosition类,规定了粒子的半径,角度和时间。

public class CirclePosition
{public float radius = 0f, angle = 0f, time = 0f;public CirclePosition(float radius, float angle, float time){this.radius = radius;   // 半径this.angle = angle;     // 角度this.time = time;       // 时间}
}

定义粒子系统的变量。

private ParticleSystem particleSys;  // 粒子系统
private ParticleSystem.Particle[] particleArr;  // 粒子数组
private CirclePosition[] circle; // 极坐标数组
public int count = 10000;       // 粒子数量
public float size = 0.03f;      // 粒子大小
public float minRadius = 5.0f;  // 最小半径
public float maxRadius = 12.0f; // 最大半径
public bool clockwise = true;   // 顺时针|逆时针
public float speed = 2f;        // 速度
public float pingPong = 0.02f;  // 游离范围
public Gradient colorGradient;

Start函数中对粒子系统进行初始化。

void Start (){   // 初始化粒子数组particleArr = new ParticleSystem.Particle[count];circle = new CirclePosition[count];// 初始化粒子系统particleSys = this.GetComponent<ParticleSystem>();particleSys.startSpeed = 0;            // 粒子位置由程序控制particleSys.startSize = size;          // 设置粒子大小particleSys.loop = false;particleSys.maxParticles = count;      // 设置最大粒子量particleSys.Emit(count);               // 发射粒子particleSys.GetParticles(particleArr);// 初始化梯度颜色控制器GradientAlphaKey[] alphaKeys = new GradientAlphaKey[5];alphaKeys[0].time = 0.0f; alphaKeys[0].alpha = 1.0f;alphaKeys[1].time = 0.4f; alphaKeys[1].alpha = 0.4f;alphaKeys[2].time = 0.6f; alphaKeys[2].alpha = 1.0f;alphaKeys[3].time = 0.9f; alphaKeys[3].alpha = 0.4f;alphaKeys[4].time = 1.0f; alphaKeys[4].alpha = 0.9f;GradientColorKey[] colorKeys = new GradientColorKey[2];colorKeys[0].time = 0.0f; colorKeys[0].color = Color.white;colorKeys[1].time = 1.0f; colorKeys[1].color = Color.white;colorGradient.SetKeys(colorKeys, alphaKeys);// 初始化各粒子位置for (int i = 0; i < count; ++i){   // 随机每个粒子距离中心的半径,同时希望粒子集中在平均半径附近float midRadius = (maxRadius + minRadius) / 2;float minRate = Random.Range(1.0f, midRadius / minRadius);float maxRate = Random.Range(midRadius / maxRadius, 1.0f);float radius = Random.Range(minRadius * minRate, maxRadius * maxRate);// 随机每个粒子的角度float angle = Random.Range(0.0f, 360.0f);float theta = angle / 180 * Mathf.PI;// 随机每个粒子的游离起始时间float time = Random.Range(0.0f, 360.0f);circle[i] = new CirclePosition(radius, angle, time);particleArr[i].position = new Vector3(circle[i].radius * Mathf.Cos(theta), 0f, circle[i].radius * Mathf.Sin(theta));}particleSys.SetParticles(particleArr, particleArr.Length);   }

Update函数中为了使得粒子看起来更加分散和动态性,对粒子进行了分层,一共分为10层,每一层的角度会有所不同。

private int tier = 10;  // 速度差分层数
void Update ()
{for (int i = 0; i < count; i++){if (clockwise)  // 顺时针旋转circle[i].angle -= (i % tier + 1) * (speed / circle[i].radius / tier);else            // 逆时针旋转circle[i].angle += (i % tier + 1) * (speed / circle[i].radius / tier);// 保证angle在0~360度circle[i].angle = (360.0f + circle[i].angle) % 360.0f;circle[i].time += Time.deltaTime;circle[i].radius += Mathf.PingPong(circle[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;particleArr[i].color = colorGradient.Evaluate(circle[i].angle / 360.0f);float theta = circle[i].angle / 180 * Mathf.PI;particleArr[i].position = new Vector3(circle[i].radius * Mathf.Cos(theta), 0f, circle[i].radius * Mathf.Sin(theta));}particleSys.SetParticles(particleArr, particleArr.Length);
}

最后我们创建另一个子对象,命名为Anticlockwise_inner。将代码拖进这两个子对象中。Anticlockwise_inner将代码选项中的clockwise选项去掉。
在这里插入图片描述

最后调整两个环半径大小就可以实现粒子光环了。

效果图:

在这里插入图片描述

这篇关于3D游戏编程实践——粒子光环的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/641650

相关文章

Redis实现分布式锁全解析之从原理到实践过程

《Redis实现分布式锁全解析之从原理到实践过程》:本文主要介绍Redis实现分布式锁全解析之从原理到实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景介绍二、解决方案(一)使用 SETNX 命令(二)设置锁的过期时间(三)解决锁的误删问题(四)Re

Python开发文字版随机事件游戏的项目实例

《Python开发文字版随机事件游戏的项目实例》随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型,在这篇博文中,我们将使用Python开发一款文字版随机事件游戏,通过这个项目,读者不仅能够... 目录项目概述2.1 游戏概念2.2 游戏特色2.3 目标玩家群体技术选择与环境准备3.1 开发环境3

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

Spring Boot 整合 SSE的高级实践(Server-Sent Events)

《SpringBoot整合SSE的高级实践(Server-SentEvents)》SSE(Server-SentEvents)是一种基于HTTP协议的单向通信机制,允许服务器向浏览器持续发送实... 目录1、简述2、Spring Boot 中的SSE实现2.1 添加依赖2.2 实现后端接口2.3 配置超时时

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的