GodZza

导航

统计

2021年8月2日 #

"反直觉" 的Unity粒子系统API

前几天一位实习生希望可以在脚本上控制粒子系统的粒子数,这个东西嘛 我当初也在试用期的时碰过一下。这些API都忘记的一干二净了。
所以搜了一下官方的API,经查后才发现,新版本的粒子系统API 都修改了,分成了不同的模块。UnityEngine.ParticleSystem - Unity 脚本 API

 

而事实上Unity官网也有实习生想要的效果(在EmissionModule.rateOverTime)

ParticleSystem-emission - Unity 脚本 API

 

但是我直接这样写发现会报错

void Update(){

    emissionRate += 1;

    ps.emission.rateOverTime = new ParticleSystem.MinMaxCurve(emissionRate);

}

因为ps.emssion 的类型是 EmissionModule, 而EmissionModule 是struct 而不是class。所以直接这样些就报错了。

过程中我也一直怀疑是不是Unity的文档太老旧了,抑或文档出错了?

因为按照直觉,因为 ps.emission 作为结构体,其已经是一个数据的副本。修改其数据再也不影响到粒子系统才对。

        //     Script interface for the EmissionModule of a Particle System.
        public struct EmissionModule
        {
            public bool enabled { get; set; }            
            public MinMaxCurve rateOverTime { get; set; }            
            public float rateOverTimeMultiplier { get; set; }           
            public MinMaxCurve rateOverDistance { get; set; }           
            public float rateOverDistanceMultiplier { get; set; }
            public int burstCount { get; set; }
            public Burst GetBurst(int index);
            public int GetBursts(Burst[] bursts);
            public void SetBurst(int index, Burst burst);
            public void SetBursts(Burst[] bursts);
            public void SetBursts(Burst[] bursts, int size);
            // ... Obsolete ... ignore
        }

但是Unity 就是这样,经过测试直接修改此emission 是可以控制粒子系统的。

 

其原理也很简单,估计在C++的部分还是隐藏了一个专门控制的句柄,只是在C#中没有显示出来。

例如

struct EmissionModule
{
    private int handle;
    public int rate;
    void SetRate(){
      var ps = GetPsInCpp(handle);
        ps.rate = this.rate;      
    }
}

 

在实际使用时,可以一直保存 emission, 在Update时不断调用也是可以的。

public class ParticleSystemController : MonoBehaviour
{
    [SerializeField]
    new ParticleSystem  particleSystem;

    [SerializeField]
    int emissionRate = 10;

    ParticleSystem.EmissionModule emissionModule;
    void Start(){
        //var rot = particleSystem.emission.rateOverTime;
        var emission = particleSystem.emission;
        this.emissionModule = emission;
    }
    void Update()
    {
        //var emission = particleSystem.emission;
        var emission = this.emissionModule;


        emission.rateOverTime = new ParticleSystem.MinMaxCurve(emissionRate);
    }
}

如果途中将Destroy(particleSystem)

此脚本会报错

NullReferenceException: Do not create your own module instances, get them from a ParticleSystem instance
UnityEngine.ParticleSystem+EmissionModule.set_rateOverTime (UnityEngine.ParticleSystem+MinMaxCurve value) (at <893f889776d241068c95ad83f5452958>:0)
ParticleSystemController.Update ()

可是看不出更深的调用堆栈。

 

 

那为什么不设计成class呢?我估计Unity 是希望不要存在太多的内存碎片。

posted @ 2021-08-02 17:11 GodZza 阅读(510) 评论(0) 推荐(0)

2021年7月26日 #

一个RingBuffer(C语言)

摘要: 也是用于STM32平台下. 通常用于串口通讯缓存. 之前看到一些其他项目写的Buffer缓存. 实在是太不简洁了, 而且还可能有bug. 例如 当处理数据不够快时, 缓存会直接被覆盖, 而不产生任何提示. 每次Update都判断 read指针 是否等于 write指针, 是的话又重新将 read和w 阅读全文

posted @ 2021-07-26 19:24 GodZza 阅读(781) 评论(0) 推荐(0)

一个极其简单(陋)的内存分配器

摘要: 在同事的帮助下,第一次尝试了STM32程序的编写. 当然仅仅是C语言的部分, 并没有涉及到电子/硬件的操作. 相关操作还是同事实现的. 当时使用了STM32 自带的 malloc, 后来发现程序运行久了会导致卡死. 其原因至今没有查清楚, 一来是因为能力不够,二是因为时间不足. 最终是写了一个超级简 阅读全文

posted @ 2021-07-26 19:10 GodZza 阅读(95) 评论(0) 推荐(0)

2020年5月18日 #

VPOS VS_POSITION ComputeScreenPos 使用场景

摘要: VPOS VPOS 是比较新的概念,在Unity2018中可以使用(估计Unity5开始的特性?),而在我的旧项目中(使用Unity4.6.4) 上会报错,所以我后来使用了SV_POSITION.xy但是经过测试 在Unity2018Build Android之后 放在低性能的安卓主板上(3188) 阅读全文

posted @ 2020-05-18 15:54 GodZza 阅读(463) 评论(0) 推荐(0)

2020年1月7日 #

理解Cookie Token 的区别

摘要: Cookie 是保存在客户端(或浏览器)的Session 是服务器上的概念 至于他们的详细的介绍网上一堆,就不细说了. 下面主要说下Cookie 和近期? 流行的Token 首先是Cookie,Cookie已经存在很长一段时间了,他主要的目的还是对应的是 在服务器端使用Session来区分不同用户. 阅读全文

posted @ 2020-01-07 16:36 GodZza 阅读(649) 评论(0) 推荐(0)

2019年6月9日 #

矩阵分解[提取Position/Rotation/Scale]

摘要: 基于Unity Matrix4x4的矩阵分解,当然不能将投影矩阵分解成 Position等,具体可以参考 XNA 的矩阵分解 夹带私货 一些常用的数学代码 阅读全文

posted @ 2019-06-09 01:37 GodZza 阅读(533) 评论(0) 推荐(0)

Unity 使用WWW读取本地文件出现 Cloudn't read a file

摘要: 之前一直在使用 Unity4 的版本,之后因为编写优化需要 写出了导致Unity Crash的代码。 所以升级到Unity5[Version 5.6.4]发现新版本上 MonoBehaviour 取消了很多直接读取 Component 的属性,顺带升级项目时 新版本会自动转换为GetComponen 阅读全文

posted @ 2019-06-09 01:27 GodZza 阅读(1071) 评论(0) 推荐(0)

2017年9月15日 #

图片去黑底

摘要: 前文【让粒子可以在白色背景显示 [BLENDING SHADER 实操]】说到最后的效果 有点BUG, 在一些过渡的地方有些黑边。 这个问题倒是和算法无关,是和图片本身有关系。 下面是效果对比图: 其原因是做图的时候,为了方便做图, 开始是不会直接用"透明"这个概念做图,而是将图做成黑色底,然后最后 阅读全文

posted @ 2017-09-15 17:04 GodZza 阅读(4352) 评论(1) 推荐(0)

2017年8月25日 #

让粒子可以在白色背景显示 [Blending Shader 实操]

摘要: Unity3D 提供了粒子特效的各种shader,今天要说的是 Additive(因为项目最初就是用了Additive 发生了问题.. ε=ε=ε=┏(゜ロ゜;)┛) Additive Particle Shader 其Blending 方式是 Blend SrcAlpha one。至于Blend 阅读全文

posted @ 2017-08-25 15:09 GodZza 阅读(2390) 评论(0) 推荐(0)

[转] Shader Blending

摘要: 引用:1.Unity3D shader Blending2.【风宇冲】Unity3D教程宝典之Shader篇:第十三讲 Alpha混合 混合(Blending)是计算机呈现渲染结果的最后阶段,每一个像素将被绘制到屏幕上。 混合的基本公式:Blend SrcFactor DstFactor 将前面各种 阅读全文

posted @ 2017-08-25 12:24 GodZza 阅读(895) 评论(0) 推荐(0)

点击右上角即可分享
微信分享提示