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

相关文章

SpringBoot简单整合ElasticSearch实践

《SpringBoot简单整合ElasticSearch实践》Elasticsearch支持结构化和非结构化数据检索,通过索引创建和倒排索引文档,提高搜索效率,它基于Lucene封装,分为索引库、类型... 目录一:ElasticSearch支持对结构化和非结构化的数据进行检索二:ES的核心概念Index:

Python数据验证神器Pydantic库的使用和实践中的避坑指南

《Python数据验证神器Pydantic库的使用和实践中的避坑指南》Pydantic是一个用于数据验证和设置的库,可以显著简化API接口开发,文章通过一个实际案例,展示了Pydantic如何在生产环... 目录1️⃣ 崩溃时刻:当你的API接口又双叒崩了!2️⃣ 神兵天降:3行代码解决验证难题3️⃣ 深度

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

MySQL存储过程实践(in、out、inout)

《MySQL存储过程实践(in、out、inout)》文章介绍了数据库中的存储过程,包括其定义、优缺点、性能调校与撰写,以及创建和调用方法,还详细说明了存储过程的参数类型,包括IN、OUT和INOUT... 目录简述存储过程存储过程的优缺点优点缺点存储过程的创建和调用mysql 存储过程中的关键语法案例存储

Java 的ArrayList集合底层实现与最佳实践

《Java的ArrayList集合底层实现与最佳实践》本文主要介绍了Java的ArrayList集合类的核心概念、底层实现、关键成员变量、初始化机制、容量演变、扩容机制、性能分析、核心方法源码解析、... 目录1. 核心概念与底层实现1.1 ArrayList 的本质1.1.1 底层数据结构JDK 1.7

JDK21对虚拟线程的几种用法实践指南

《JDK21对虚拟线程的几种用法实践指南》虚拟线程是Java中的一种轻量级线程,由JVM管理,特别适合于I/O密集型任务,:本文主要介绍JDK21对虚拟线程的几种用法,文中通过代码介绍的非常详细,... 目录一、参考官方文档二、什么是虚拟线程三、几种用法1、Thread.ofVirtual().start(

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

springboot依靠security实现digest认证的实践

《springboot依靠security实现digest认证的实践》HTTP摘要认证通过加密参数(如nonce、response)验证身份,避免明文传输,但存在密码存储风险,相比基本认证更安全,却因... 目录概述参数Demopom.XML依赖Digest1Application.JavaMyPasswo