跳至主要内容

[外文翻译] 在unity3d上建立运行重新着色和衰退的粒子系统

粒子系统是极好的系统,适应于各种各样的特效在游戏中,包括火焰,爆炸,烟雾,水,灯光,行星模拟,还有很多,unity伴随着一个建立在粒子系统上的library可以用来实施这些特效在你的或者3d游戏上,而且在unity上实施这个粒子系统有着额外的灵活性和允许你创造更神奇的特效,有时候你有些情况需要要求一些专用化,这些是不可以被建立的。此外,最近我尝试实现实现一个粒子效果让粒子分散开来像爆炸一样,然后停留在一个地方,最后缓慢的淡出不断循环。当粒子不断发散随着它们的生命周期可以熟练的用过build-in editor,等待它们的是终止。
这里可以看到一个粒子系统是我创建的,它使用build-in particle editor unity中:
 
 
暂停粒子系统
根据你们所看到的,它开始于一个随机放射方向的粒子系统,然后停止,,这个暂停特效比直着向前扩展要好,而且可以实现通过贴上一个代码在粒子系统中让它暂停然后继续
 
public class ParticleScript : MonoBehaviour {

    public float timeToPause = 2.0f;
   
    private ParticleSystem system;
    private float time;
   
    void Awake() {
        system = GetComponent();
    }
   
    void Update() {
        time += Time.deltaTime;
       
        if (!system.isPaused && time > timeToPause) {
            system.Pause();
        }
    }
}
我们开始通过定义一个public float 叫做timeToPause 表示多长时间这个粒子应该持续播放在暂停之前,在Update中,我们update timeTime.deltaTime和暂停这个粒子系统用pause()在粒子系统本身上
这些都很简单并且好用,但是我们仍然需要修改粒子的颜色在暂停的视乎,这个主意是一旦粒子系统被暂停,他就开始衰退直到它消失不可见。

重新着色粒子
我们将要做的是重新着色每一个单独的粒子,因为他们可能有同样的颜色取决于你的粒子系统怎样被配置。在这个粒子中,我们将会修改粒子的alpha在衰退的部分,但你可以应用同样的方法在任何合成的颜色中。
第一件事我们要做的是引用到当前的粒子在系统中当我们暂停的时候:
 
public class ParticleScript : MonoBehaviour {

    ...
    
    private ParticleSystem.Particle[] particles;
    
    ...
    
    void Update() {
        time += Time.deltaTime;
        
        if (!system.isPaused && time > timeToPause) {
            system.Pause();
            
            particles = new ParticleSystem.Particle[system.particleCount];
            system.GetParticles(particles);
        }
    }
}
我们定义一个队列中的粒子项目我们将会用使用储存粒子当我们暂停了系统。我们然后初始化它与当前数量的粒子在系统中用system.particleCount来作用到一个缓冲区,然后前往有粒子储存的缓冲区队列中用system.GetParticles
现在我们可以反复处理和修改这些粒子根据这个队列。在Update中,我们将要添加一些逻辑当系统被暂停来重新着色粒子像这样:
public class ParticleScript : MonoBehaviour {

    ...
    
    public float lifespan = 5.0f;
    
    ...
    
    
    void Update() {
        ...
        
        if (particles != null) {
            for (int p = 0; p < particles.Length; p++) {
                Color color = particles[p].startColor;
                color.a = ((lifespan - time + timeToPause) / lifespan);
                
                particles[p].startColor = color;
            }
            
            system.SetParticles(particles, particles.Length);
        }
    }
}
我们开始通过确定这个系统已经被暂停而且粒子已经被初始化,然后合并这些已经储藏的粒子当我们暂停这个系统的时候。对于单个粒子,我们抓住他们当前的颜色,并且更新alpha作为百分比的时间针对已经确认与总时间线对比过得粒子。同样需要注意的我们忽略了 timeToPause 添加到时间线来确认如何“淡出”之前的粒子

随着时间的推移这些粒子将会顺滑的淡出像这样:
 

表现
根 据这些粒子系统的数量,当你的粒子消散时,在每一个系统中的粒子,上面有一些规则有着基本的实施需要被标记,例如,你可能不想更新每一帧的粒子,而只更新 了第五帧,例如,你可能缓存当前的颜色,只更新粒子当这些变化非常重要时,列如,不要更新所有的粒子,在粒子系统中,当不同的alpha的差异是非常小的,甚至不会很明显。
如果你还想摧毁粒子系统,当它完全淡出识图(color.a <= 0f)而不是只是让它围绕。
这些表现的提升你选择的,如果有的话,将取决于你的案例,但是还是希望能给你一些启发对于一些特效你想要实现在你的游戏当中
完整的代码
最后,这里是完整的脚本,如下:
using UnityEngine;
using System.Collections;

public class ParticleScript : MonoBehaviour {
    
    public float lifespan = 5.0f;
    public float timeToPause = 2.0f;
    
    private ParticleSystem.Particle[] particles;
    private ParticleSystem system;
    private float time;
    
    void Awake() {
        system = GetComponent();
    }
    
    
    void Update() {
        time += Time.deltaTime;
        
        if (!system.isPaused && time > timeToPause) {
            system.Pause();
        
            particles = new ParticleSystem.Particle[system.particleCount];
            system.GetParticles(particles);
        }
        
        if (particles != null) {
            for (int p = 0; p < particles.Length; p++) {
                Color color = particles[p].startColor;
                color.a = ((lifespan - time + timeToPause) / lifespan);
                
                particles[p].startColor = color;
            }
        
            system.SetParticles(particles, particles.Length);
        }
    }
}
 
 
 
 

评论

此博客中的热门博文

[3D跑酷] AudioManager

Unity音频管理 游戏中的声音管理最常用的组件莫过于AudioSource和AudioClip,我的做法是建立是一个AudioManager类(单例类)管理各个音频,谈一下我的经验: 函数列表 Start函数:设置音频整体参数; 编辑器面板 拖拽文件赋值 AudioSource文档 逻辑实现代码 public void playSoundEffect(SoundEffects soundEffect) { AudioClip clip = null ; float pitch = 1; switch (soundEffect) { case SoundEffects.ObstacleCollisionSoundEffect: clip = obstacleCollision; break ; case SoundEffects.CoinSoundEffect: clip = coinCollection; pitch = 1.5f; break ; case SoundEffects.PowerUpSoundEffect: clip = powerUpCollection; break ; case SoundEffects.GameOverSoundEffect: clip = gameOver; break ; case SoundEffects.GUITapSoundEffect: clip = guiTap; break ; } soundEffectsAudio.pitch = pitch; //音调 so...

[3D跑酷] GUIManager UI管理

UI元素更新及界面跳转 继上篇日志《Unity开发之 GUIClickEventReceiver》,再谈一下我们如何管理游戏中的UI元素更新及界面跳转 UI绑定 图一:Inspector面板 Public GameObjectName与GameObject一一对应 UI结构及命名规范 图二:Hierarchy面板 UI父子结构及组件命名规范 UI枚举种类 图三:enum GUIState UI绑定代码 图四:public UI控件定义 与Hierarchy命名规范 UI主要方法及逻辑 图五:主要方法及逻辑 主要方法 1、隐藏Transform及子Transform #if !UNITY_3_5 private void activeRecursively(Transform obj, bool active) { foreach (Transform child in obj) { activeRecursively(child, active); } obj.gameObject.SetActive(active); } #endif private GameObject panelFromState(GUIState state) { switch (state) { case GUIState.MainMenu: return mainMenuPanel; case GUIState.InGame: return inGamePanel; case GUIState.EndGame: return endGamePanel; case GUIState.Store: return storePanel; case GUIState.Stats: return statsPanel; case GUISt...

谷歌Adsense广告代码异步加载解决谷歌联盟广告老卡的问题

最近一段时间,谷歌中国的服务器从香港撤走,导致很多朋友连谷歌也无法访问了,而像部落这样,在网站中投放了谷歌Adsense广告的,也经常会出 现网站打开,加载到谷歌广告位置时,网站就卡在那里了,估计一些网速慢的用户,可能就永远卡那里了。对于这种情况,我们可以利用异步加载的广告代码来解决 这个问题。 Google广告会因为各种原因经常打不开,如果不用异步加载的方法,会导致在您的网站中,google广告后面的代码显示被阻塞,这样的话,很影响用户体验。经常网页不能完全打开的话,必然会导致用户的在面积流失。 上图是部落的网站首页,在没有使用广告代码异步加载前,经常会出现这样的现像,首页右边的一个300X300的谷歌广告位无法正常显示了。 当然,使用谷歌Adsense广告代码异步加载,您的网站加载速度会明显提升,特别是对一些网速慢的用户来说,但有一点和我们站长相矛盾的,那就是上次谷歌承诺广告发布商的广告被有效浏览才收费,很明显,异步加载有可能会降低您站内广告的浏览量。 使用谷歌Adsense广告代码异步加载 其实使用方法很简单,我们进入自己的谷歌联盟后台,在“广告单元”中找到需要异步加载的广告位,点击“获取代码”,如下图: 我们在代码类型中选择“异步”,就能获得异步加载的广告位代码,将您之前在网站中投放的广告代码替换就行了。 之前传统的google广告异步加载代码 不知您有没有发现,之前传统的google广告异步加载代码之这次部落所说的有很大的不同了,例如部落之前同样是采用的广告代码同步加载,代码内容如下: --> 显然,以上代码会影响您的网站加载速度。而之前的异步加载代码,则是在后面加上了一段JS代码。内容就不放出了。 部落在谷歌官方找到一些异步加载说明:google广告在google服务器正常的情况下会及时的正常显示,google服务器不正常的情况下也不会影响后面页面的加载。 而自己正式体验后,才发现,谷歌联盟的广告加载速度真是超快,只是加载的内容,匹配性没之前那么好了,究其原因,部落猜想应该是在调用本地电脑数据的cookis时,就直接调用了其中的广告数据,只有这样,加载速度才会达到最快。当然,这纯粹只是个人猜想而已。