unity中的特效管理器(特效缓存池)
2018-02-02 10:57
399 查看
游戏中普遍都有大量的特效,为了便于管理,写了一个简单的特效管理器。
此管理器用到了一个配置表管理器,之前的文章中有介绍,传送门
我们的配置文件的内容应该是这样:
这里是excel的样子,如果使用我前面提供的配置表管理器还需要把它转成xml格式。
此管理器借鉴了缓存池的设计思路,使用一个字典用来存放所有特效对象。在初始化此管理器时,会根据配置表中配置的同时存在数量来创建特效,并加入到缓存池中。
使用特效时,根据配置表中的id在缓存池中寻找空闲的特效,如果没有找到会新新创建一个。
下面是管理器的代码:
public class GameEffectManager {
//特效池
Dictionary<int ,List<GameEffect>> effectPool = new Dictionary<int ,List<GameEffect>>();
public GameEffectManager(){
//创建特效,加入到池里
List<conf_effect> _conf = ConfigManager.confEffectManager.datas;
for(int i = 0 ; i < _conf.Count ; i ++){
conf_effect conf = _conf[i];
for(int j = 0 ; j < conf.repeat_count ; j++){
CreateEffect(conf);
}
}
}
/// <summary>
/// 添加特效到世界
/// </summary>
/// <returns>The world effect.</returns>
/// <param name="effectid">配置表中的id.</param>
/// <param name="pos">出生位置.</param>
/// <param name="scale">特效的尺寸.</param>
public GameEffect AddWorldEffect(int effectid,Vector3 pos, float scale){
GameEffect ge = GetEffect(effectid,pos);
if(ge == null) return null;
ge.transform.position = pos;
ge.Play(scale);
return ge;
}
/// <summary>
/// 添加特效到指定物体
/// </summary>
/// <returns>The effect.</returns>
/// <param name="effectid">配置表中的id.</param>
/// <param name="obj">跟随物体,如果此物体不为空,特效会跟随此体移动,直到父物体变为null.</param>
/// <param name="pos">特效在obj中的相对坐标(偏移).</param>
/// <param name="scale">特效的尺寸.</param>
public GameEffect AddEffect(int effectid, GameObject obj, Vector3 pos, float scale){
if(obj == null){
return AddWorldEffect(effectid,pos,scale);
}
GameEffect ge = GetEffect(effectid,obj.transform.position + pos);
if(ge == null) return null;
ge.SetParent(obj);
ge.Play(scale);
return ge;
}
GameEffect GetEffect(int effectid ,Vector3 worldPos){
//对应池是否存在
if(!effectPool.ContainsKey(effectid)){
return null;
}
//寻找空闲特效
List<GameEffect> pool = effectPool[effectid];
GameEffect ret = null;
for(int i = 0 ; i < pool.Count ; i ++){
GameEffect eff = pool[i];
if(eff.gameObject.activeSelf){
continue;
}
ret = eff;
break;
}
//如果没有可用特效,则创建一个新的
if(ret == null){
conf_effect conf = ConfigManager.confEffectManager.GetData(effectid);
if(conf != null) ret = CreateEffect(conf);
}
return ret;
}
//添加一个特效到缓存池
GameEffect CreateEffect(conf_effect effect){
Object obj = Resources.Load(effect.file_path);
if(obj == null){
Debug.LogError("cant find file ! : " + effect.file_path);
}
if(effect.res_type == 1){
GameObject go = (GameObject)MonoBehaviour.Instantiate(obj);
GameEffect ge = go.AddComponent<GameEffect>();
ge.Init(effect);
if (!effectPool.ContainsKey(effect.id))
{
effectPool.Add(effect.id, new List<GameEffect>());
}
effectPool[effect.id].Add(ge);
return ge;
}
return null;
}
}
这里只对外提供了2个创建特效的方法,一种是添加到世界的特效,特效播放完即隐藏,另一种是跟随父物体的特效,特效会一直存在直到父物体消失。
这里在创建特效时还会自动赋给特效一个脚本,来控制特效自身的逻辑,该脚本的代码如下:
public class GameEffect : MonoBehaviour {
//配置文件
public conf_effect conf{get;private set;}
//粒子系统
ParticleSystem ps ;
//播放时间
float playTime;
//跟随物体,如果此物体不为空,特效会跟随父物体移动,直到父物体变为null
public GameObject parent;
public void Init(conf_effect conf){
this.conf = conf;
ps = transform.GetComponent<ParticleSystem>();
gameObject.SetActive(false);
}
public void Play(float scale){
playTime = 0;
gameObject.SetActive(true);
ps.Play();
SetScale(transform, scale);
}
public void SetScale(Transform t, float scale){
for (int i = 0; i < t.childCount; i ++){
SetScale(t.GetChild(i),scale);
}
t.localScale = new Vector3(scale, scale, scale);
}
void Update(){
playTime += Time.deltaTime;
if (parent != null)
{
transform.position = parent.transform.position;
return;
}
if(playTime > ps.main.duration){
Die();
}
}
public void SetParent(GameObject obj){
this.parent = obj;
}
public void Die(){
gameObject.SetActive(false);
}
void OnDestroy(){
}
}
使用方法
游戏开始时我们需要先创建管理器:
GameEffectManager gameEffectManager = new GameEffectManager();我们只需要调用创建方法就可以使用特效了:
gameEffectManager.AddEffect(60010010,ojb,pos,1.0);
这样我们不用关心特效的创建和消失的细节,使用起来还是很方便的。在实际的项目开发中,可能还需要根据项目的不同需求进行一些修改。
此管理器用到了一个配置表管理器,之前的文章中有介绍,传送门
我们的配置文件的内容应该是这样:
这里是excel的样子,如果使用我前面提供的配置表管理器还需要把它转成xml格式。
此管理器借鉴了缓存池的设计思路,使用一个字典用来存放所有特效对象。在初始化此管理器时,会根据配置表中配置的同时存在数量来创建特效,并加入到缓存池中。
使用特效时,根据配置表中的id在缓存池中寻找空闲的特效,如果没有找到会新新创建一个。
下面是管理器的代码:
public class GameEffectManager {
//特效池
Dictionary<int ,List<GameEffect>> effectPool = new Dictionary<int ,List<GameEffect>>();
public GameEffectManager(){
//创建特效,加入到池里
List<conf_effect> _conf = ConfigManager.confEffectManager.datas;
for(int i = 0 ; i < _conf.Count ; i ++){
conf_effect conf = _conf[i];
for(int j = 0 ; j < conf.repeat_count ; j++){
CreateEffect(conf);
}
}
}
/// <summary>
/// 添加特效到世界
/// </summary>
/// <returns>The world effect.</returns>
/// <param name="effectid">配置表中的id.</param>
/// <param name="pos">出生位置.</param>
/// <param name="scale">特效的尺寸.</param>
public GameEffect AddWorldEffect(int effectid,Vector3 pos, float scale){
GameEffect ge = GetEffect(effectid,pos);
if(ge == null) return null;
ge.transform.position = pos;
ge.Play(scale);
return ge;
}
/// <summary>
/// 添加特效到指定物体
/// </summary>
/// <returns>The effect.</returns>
/// <param name="effectid">配置表中的id.</param>
/// <param name="obj">跟随物体,如果此物体不为空,特效会跟随此体移动,直到父物体变为null.</param>
/// <param name="pos">特效在obj中的相对坐标(偏移).</param>
/// <param name="scale">特效的尺寸.</param>
public GameEffect AddEffect(int effectid, GameObject obj, Vector3 pos, float scale){
if(obj == null){
return AddWorldEffect(effectid,pos,scale);
}
GameEffect ge = GetEffect(effectid,obj.transform.position + pos);
if(ge == null) return null;
ge.SetParent(obj);
ge.Play(scale);
return ge;
}
GameEffect GetEffect(int effectid ,Vector3 worldPos){
//对应池是否存在
if(!effectPool.ContainsKey(effectid)){
return null;
}
//寻找空闲特效
List<GameEffect> pool = effectPool[effectid];
GameEffect ret = null;
for(int i = 0 ; i < pool.Count ; i ++){
GameEffect eff = pool[i];
if(eff.gameObject.activeSelf){
continue;
}
ret = eff;
break;
}
//如果没有可用特效,则创建一个新的
if(ret == null){
conf_effect conf = ConfigManager.confEffectManager.GetData(effectid);
if(conf != null) ret = CreateEffect(conf);
}
return ret;
}
//添加一个特效到缓存池
GameEffect CreateEffect(conf_effect effect){
Object obj = Resources.Load(effect.file_path);
if(obj == null){
Debug.LogError("cant find file ! : " + effect.file_path);
}
if(effect.res_type == 1){
GameObject go = (GameObject)MonoBehaviour.Instantiate(obj);
GameEffect ge = go.AddComponent<GameEffect>();
ge.Init(effect);
if (!effectPool.ContainsKey(effect.id))
{
effectPool.Add(effect.id, new List<GameEffect>());
}
effectPool[effect.id].Add(ge);
return ge;
}
return null;
}
}
这里只对外提供了2个创建特效的方法,一种是添加到世界的特效,特效播放完即隐藏,另一种是跟随父物体的特效,特效会一直存在直到父物体消失。
这里在创建特效时还会自动赋给特效一个脚本,来控制特效自身的逻辑,该脚本的代码如下:
public class GameEffect : MonoBehaviour {
//配置文件
public conf_effect conf{get;private set;}
//粒子系统
ParticleSystem ps ;
//播放时间
float playTime;
//跟随物体,如果此物体不为空,特效会跟随父物体移动,直到父物体变为null
public GameObject parent;
public void Init(conf_effect conf){
this.conf = conf;
ps = transform.GetComponent<ParticleSystem>();
gameObject.SetActive(false);
}
public void Play(float scale){
playTime = 0;
gameObject.SetActive(true);
ps.Play();
SetScale(transform, scale);
}
public void SetScale(Transform t, float scale){
for (int i = 0; i < t.childCount; i ++){
SetScale(t.GetChild(i),scale);
}
t.localScale = new Vector3(scale, scale, scale);
}
void Update(){
playTime += Time.deltaTime;
if (parent != null)
{
transform.position = parent.transform.position;
return;
}
if(playTime > ps.main.duration){
Die();
}
}
public void SetParent(GameObject obj){
this.parent = obj;
}
public void Die(){
gameObject.SetActive(false);
}
void OnDestroy(){
}
}
使用方法
游戏开始时我们需要先创建管理器:
GameEffectManager gameEffectManager = new GameEffectManager();我们只需要调用创建方法就可以使用特效了:
gameEffectManager.AddEffect(60010010,ojb,pos,1.0);
这样我们不用关心特效的创建和消失的细节,使用起来还是很方便的。在实际的项目开发中,可能还需要根据项目的不同需求进行一些修改。
相关文章推荐
- unity 2d利用shader 做闪光特效
- Unity Shader——夜晚视觉屏幕特效(night vision Screen Effect)
- 使用纹理制作特效 - 在Unity编辑器中创建程序纹理贴图
- 【Unity Shaders】使用Unity Render Textures实现画面特效——建立画面特效脚本系统
- Laya播放unity特效
- [Unity教程]unity 鼠标点击目的地生成特效
- 【Unity&Shader】高光资料总结&2D描边特效资料总结
- Unity5.x Shader设置受击特效 InnerGlow
- [Unity特效][Unity插件]World Space Fading Transitions物体渐隐特效插件以及相关问题解决
- Unity几个有用的游戏运动特效
- Unity 技能按钮触发特效
- unity挥动武器产生的剑痕特效
- 【Unity Shaders】使用Unity Render Textures实现画面特效——建立画面特效脚本系统
- 【Unity Shaders】使用Unity Render Textures实现画面特效——画面特效中的相似Photoshop的基本混合模式
- Unity 镜子反射特效
- [Unity&特效]使用Projector投影仪来制作角色脚下的特效圆环以及技能指示器skill indicator
- unity射击游戏:超萌射手(2)射击特效和EasyButton使用
- Unity 粒子特效预览工具
- Unity粒子特效详细属性说明
- Unity Shader之Logo流光特效