Unit 高效开发系列 - 第二章 代码自动化创建粒子特效预制体
前言
Uinty高效开发系列主要包含一系列的Unity开发实例,主要来源于笔者的一个3D游戏项目和一个手机APP项目,适合利用Unity开发游戏或手机APP场景。
一、代码自动化创建粒子特效预制体实现
1.通过代码创建基本粒子
- 点击示例工程”菜单"Tool“ -> "CreateParticle“ -> ”基本粒子“,启动通过代码创建基本粒子特效预制体。
- 通过代码创建基本粒子的代码实现,以"呼吸光点"为例:
CreateParticleBase 为C#封装的创建粒子系统基类,CreateParticleBase.CreateMaterial函数实现通过图片和Shader创建Material。
static void CreateBreathGlowParticle()
{
CreateParticleBase cp = new CreateParticleBase("BreathGlow", AssPath);
#region main
cp.main_duration = 1f;
cp.main_loop = true;
cp.main_prewarm = true;
cp.main_startLifetime = 1;
cp.main_startSpeed = 0;
cp.main_startSize = 5;
cp.main_simulationSpeed = 1;
cp.main_scalingMode = ParticleSystemScalingMode.Local;
cp.main_maxParticles = 2;
MinMaxGradient startColor = new MinMaxGradient();
startColor.mode = ParticleSystemGradientMode.Color;
startColor.color = new Color(229/225.0f, 204/255f, 8/255f, 130 / 255f);
cp.main_startColor = startColor;
#endregion
#region emission
cp.emission_enabled = true;
cp.emission_rateOverTime = 10;
#endregion
#region shape
cp.shape_enabled = false;
#endregion
#region colorOverLifetime
cp.colorOverLifetime_enabled = true;
MinMaxGradient minMaxGradient = new MinMaxGradient();
minMaxGradient.mode = ParticleSystemGradientMode.Gradient;
minMaxGradient.gradient = new Gradient();
minMaxGradient.gradient.mode = GradientMode.Blend;
minMaxGradient.gradient.colorKeys = new GradientColorKey[] {
new GradientColorKey(new Color(138/255f,186/255f,251/255f),0),
new GradientColorKey(new Color(75/255f,173/255f,255/255f),0.5f),
new GradientColorKey(new Color(132/255f,182/255f,251/255f),0.5f)};
cp.trails_colorOverLifetime = minMaxGradient;
#endregion
#region sizeOverLifetime
cp.sizeOverLifetime_enabled = true;
MinMaxCurve sizeMinMaxCure = new MinMaxCurve();
sizeMinMaxCure.mode = ParticleSystemCurveMode.Curve;
sizeMinMaxCure.curve = new AnimationCurve();
sizeMinMaxCure.curve.AddKey(0, 1f);
sizeMinMaxCure.curve.AddKey(0.5f, 0.75f);
sizeMinMaxCure.curve.AddKey(1, 1f);
sizeMinMaxCure.curveMultiplier = 1;
cp.sizeOverLifetime_size = sizeMinMaxCure;
#endregion
#region renderMode
cp.rd_renderMode = ParticleSystemRenderMode.VerticalBillboard;
cp.rd_material = CreateParticleBase.CreateMaterial("Glow_5", "Mobile/Particles/Additive");
cp.rd_sortingFudge = 6;
cp.rd_alignment = ParticleSystemRenderSpace.Local;
cp.rd_minParticleSize = 0;
cp.rd_maxParticleSize = 2;
cp.rd_sortingOrder = 2;
#endregion
cp.SaveToPrefab();
}
2.从网络收集的优秀粒子特效拆分出可用的基本粒子
- 笔记花了大量时间通过各种途径(有免费的,也有收费的)获取上几百个粒子特效工程,从中拆分出301个经典的基本粒子。
3.通过代码创建粒子特效预制体
- 点击示例工程”菜单"Tool“ -> "CreateParticle“ -> ”粒子预制体“,启动通过代码创建粒子特效预制体。
- 通过代码创建粒子特效预制体实现:
public struct ParticleProperty
{
public bool active;
public string prefabName;
public string parent;
public Vector3 pos;
public Vector3 rotation;
public float scale;
public Color color;
public List<SubEmitters> subEmitters;
public string script;
public SetPsPropertyCallBack callBack;
public int collisionLayer;
public ParticleProperty(bool _active, string _prefabName,string _parent,Vector3 _pos, Vector3 _rotation, float _scale, Color _color, List<SubEmitters> _subEmitters, string _script = "", SetPsPropertyCallBack _callBack = null,int _collisionLayer = 0)
{
active = _active;
prefabName = _prefabName;
parent = _parent;
pos = _pos;
rotation = _rotation;
scale = _scale;
color = _color;
subEmitters = _subEmitters;
script = _script;
callBack = _callBack;
collisionLayer = _collisionLayer;
}
}
static Dictionary<string, ParticleObjInfo> g_GlobalParticleObj = new Dictionary<string, ParticleObjInfo>()
{
{ "/Skill/StreamerArrow",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Arrow/Arrow","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ },"",StreamerArrow_Arrow), //子粒子放在主粒子之后
new ParticleProperty(true, "Deco/Deco","Arrow",new Vector3(0,0,0.3f), new Vector3(90,0,0),1f,Color.white,new List<SubEmitters>(){ },"",StreamerArrow_Deco), //子粒子放在主粒子之后
new ParticleProperty(true, "Trail/Trail","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ },""),
}
)
},
{ "/Skill/ArrowRain",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "ArrowRipple/ArrowRipple","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ }), //子粒子放在主粒子之后
new ParticleProperty(true, "Smoke/Smoke","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ }), //子粒子放在主粒子之后
new ParticleProperty(true, "ArrowRain/ArrowRain","",new Vector3(0,0,0), new Vector3(90,0,0),1f,Color.white,new List<SubEmitters>(){new SubEmitters(ParticleSystemSubEmitterType.Collision, "ArrowRipple"),new SubEmitters(ParticleSystemSubEmitterType.Collision, "Smoke") }),
}
)
},
{ "/Skill/StreamerArrowExplos",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Ice_Smoke/Ice_Smoke","",new Vector3(0,-0.8f,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ },"",StreamerArrow_Ice_Smoke), //子粒子放在主粒子之后
new ParticleProperty(true, "Ice_Sub/Ice_Sub","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ },"",StreamerArrow_Ice_Sub), //子粒子放在主粒子之后
}
)
},
{ "/Skill/IceBox",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "IceDeco/IceDeco","",new Vector3(0,-1f,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ },"",IceBox), //子粒子放在主粒子之后
}
)
},
{ "/Skill/IceRock",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "IceRock/IceRock","",new Vector3(0,-1f,0), new Vector3(0,0,0),0.25f,Color.white,new List<SubEmitters>(){ },"",IceRock), //子粒子放在主粒子之后
}
)
},
{ "/Skill/IceCapsule",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "IceDeco2/IceDeco2","",new Vector3(0,-1.2f,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ },"",IceCapsule), //子粒子放在主粒子之后
}
)
},
{ "/Skill/Upgrade",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Leaves/Leaves","",new Vector3(0,-1.3f,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ },"",Upgrade), //子粒子放在主粒子之后
}
)
},
{ "/Skill/DuYe",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Bubbles2/Bubbles2","",new Vector3(0,-1.9f,0), new Vector3(270,270,0),1f,Color.white,new List<SubEmitters>(){ },"",DuYe_Bubbles2),
new ParticleProperty(true, "Liquid/Liquid1","",new Vector3(0,-1.9f,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ },"",DuYe_Liquid1),
}
)
},
{ "/Skill/DuYe2",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Bubbles2/Bubbles2","",new Vector3(0,-1.9f,0), new Vector3(270,270,0),0.6f,Color.white,new List<SubEmitters>(){ },"",DuYe_Bubbles2),
new ParticleProperty(true, "BasePulse/BasePulse","",new Vector3(0,-1.9f,0), new Vector3(0,0,0),6f,Color.white,new List<SubEmitters>(){ },"",DuYe_Liquid1),
new ParticleProperty(true, "Liquid/Liquid1","",new Vector3(0,-1.9f,0), new Vector3(0,0,0),0.6f,Color.white,new List<SubEmitters>(){ },"",DuYe_Liquid1),
}
)
},
{ "/Skill/ZhuiSanShu",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Moutain/Moutain","",new Vector3(0,2f,0), new Vector3(270,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ZhuiSanShu_Moutain1),
//new ParticleProperty(true, "Moutain/Moutain","",new Vector3(0,2f,0), new Vector3(270,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ZhuiSanShu_Moutain2),
//new ParticleProperty(true, "Moutain/Moutain","",new Vector3(0,2f,0), new Vector3(270,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ZhuiSanShu_Moutain3),
}
)
},
{ "/Skill/ShanDianBao",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Lightning3/Lightning","",new Vector3(0,-0.85f,0), new Vector3(-90,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ShanDianBao_Lightning),
new ParticleProperty(true, "ExplosionSmoke2/ExplosionSmoke","",new Vector3(0,-0.85f,0), new Vector3(0,0,0),0.02f,Color.white,new List<SubEmitters>(){ },"",ShanDianBao_ExplosionSmoke2),
new ParticleProperty(true, "Fire2/Fire","",new Vector3(0,-0.85f,0), new Vector3(0,0f,0),1f,Color.white,new List<SubEmitters>(){ },"",ShanDianBao_Fire2),
//new ParticleProperty(true, "Moutain/Moutain","",new Vector3(0,2f,0), new Vector3(270,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ZhuiSanShu_Moutain2),
//new ParticleProperty(true, "Moutain/Moutain","",new Vector3(0,2f,0), new Vector3(270,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ZhuiSanShu_Moutain3),
}
)
},
{ "/Skill/LiuXingHuoYu",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Fire2/Fire","",new Vector3(0,2f,0), new Vector3(0,0,0),0.8f,Color.white,new List<SubEmitters>(){ },"",LiuXingHuoYu_ExplosionSmoke2),
new ParticleProperty(true, "Smoke/Smoke","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "DiLie1/DiLie1","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),30f,Color.white,new List<SubEmitters>(){ },"",LiuXingHuoYu_DiLie1),
new ParticleProperty(true, "Fire9/Fire","",new Vector3(0,-1.7f,0), new Vector3(90,0,0),0.2f,Color.white,new List<SubEmitters>(){ },""),
new ParticleProperty(true, "Fire3/Fire","",new Vector3(0,2f,0), new Vector3(90,0,0),0.4f,Color.white,new List<SubEmitters>(){ new SubEmitters(ParticleSystemSubEmitterType.Collision, "Fire"),new SubEmitters(ParticleSystemSubEmitterType.Collision, "Smoke")/*, new SubEmitters(ParticleSystemSubEmitterType.Collision, "DiLie1") */},"",LiuXingHuoYu_Fire3),
//new ParticleProperty(true, "Moutain/Moutain","",new Vector3(0,2f,0), new Vector3(270,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ZhuiSanShu_Moutain2),
//new ParticleProperty(true, "Moutain/Moutain","",new Vector3(0,2f,0), new Vector3(270,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ZhuiSanShu_Moutain3),
}
)
},
{ "/Skill/ShengJiGuangHuan",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "GlowStar/GlowStar","",new Vector3(0,-1.85f,0), new Vector3(-90,0,0),1.2f,Color.white,new List<SubEmitters>(){ },"",ShengJiGuangHuan_GlowStar),
// new ParticleProperty(true, "Leaves/Leaves_greenLeave1","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ShengJiGuangHuan_Leaves),
new ParticleProperty(true, "Rays2/Rays2","",new Vector3(0,-1.85f,0), new Vector3(90,0,0),1.5f,Color.white,new List<SubEmitters>(){ },"",ShengJiGuangHuan_Rays2),
new ParticleProperty(true, "Sparkles/Sparkles","",new Vector3(0,-1.85f,0), new Vector3(90,0,0),0.4f,Color.white,new List<SubEmitters>(){ },"",ShengJiGuangHuan_Sparkles),
new ParticleProperty(true, "RayRounded/RayRounded1","",new Vector3(0,-1.85f,0), new Vector3(-90,0,0),0.75f,Color.white,new List<SubEmitters>(){ },"",ShengJiGuangHuan_RayRounded1),
new ParticleProperty(true, "AuraRays/AuraRays","",new Vector3(0,-1.85f,0), new Vector3(-90,0,0),2f,Color.white,new List<SubEmitters>(){ },"",ShengJiGuangHuan_AuraRays),
//new ParticleProperty(true, "Moutain/Moutain","",new Vector3(0,2f,0), new Vector3(270,0,0),1f,Color.white,new List<SubEmitters>(){ },"",ZhuiSanShu_Moutain3),
}
)
},
{ "/Skill/HuoYanBaoLie",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "DiLie6/DiLie6","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),2f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "DiLie7/DiLie7","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),2f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "DiLie9/DiLie9","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),4f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "Flash/Flash1","",new Vector3(0,-1.85f,0), new Vector3(-90,0,0),0.1f,Color.white,new List<SubEmitters>(){ },"",HuoYanBaoLie_Flash1),
new ParticleProperty(true, "Flash1/Flash1","",new Vector3(0,-1.85f,0), new Vector3(-90,0,0),3f,Color.white,new List<SubEmitters>(){ }),
//new ParticleProperty(true, "BaoZha2/BaoZha2","",new Vector3(0,-1.85f,0), new Vector3(-90,0,0),3f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "ShockWave8/ShockWave8","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "Flame/Flame1","",new Vector3(0,-1.5f,0), new Vector3(90,0,0),0.5f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "Flame2/Flame2","",new Vector3(0,-1.5f,0), new Vector3(90,0,0),0.5f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "Smoke/Smoke","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),0.3f,Color.white,new List<SubEmitters>(){ }),
}
)
},
{ "/Skill/HuoYanBaoLie2",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "DiLie5/DiLie5","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),4f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "DiLie7/DiLie7","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),4f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "DiLie9/DiLie9","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),4f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "Fire1/Fire1","",new Vector3(0,-1.35f,0), new Vector3(0,0,0),0.5f,Color.white,new List<SubEmitters>(){ }),
new ParticleProperty(true, "Smoke/Smoke","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ }),
}
)
},
{ "/Skill/BaoZha",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "DiLie/DiLie","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),2f,Color.white,new List<SubEmitters>(){ },"",BaoZha_DiLie),
new ParticleProperty(true, "BaoZha/BaoZha","",new Vector3(0,-1.7f,0), new Vector3(0,0,0),0.3f,Color.white,new List<SubEmitters>(){ },"",BaoZha_BaoZha),
new ParticleProperty(true, "BaoZha2/BaoZha1","",new Vector3(0,-1.7f,0), new Vector3(0,0,0),2f,Color.white,new List<SubEmitters>(){ },"",BaoZha_BaoZha2),
new ParticleProperty(true, "Smoke/Smoke","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ }),
}
)
},
{ "/Skill/Icicles",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Icicles/Icicles","",new Vector3(0,-1.85f,0), new Vector3(-90,0,0),0.05f,Color.white,new List<SubEmitters>(){ },"",Icicles_Icicles),
new ParticleProperty(true, "IceFrost/IceFrost","",new Vector3(0,-1.7f,0), new Vector3(0,0,0),1.5f,Color.white,new List<SubEmitters>(){ },"",Icicles_IceFrost),
new ParticleProperty(true, "Smoke/Smoke","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ }),
}
)
},
{ "/Skill/SwordRain",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "SwordRain/SwordRain","",new Vector3(0,0f,0), new Vector3(90,0,0),1f,Color.white,new List<SubEmitters>(){ },"",SwordRain_SwordRain),
new ParticleProperty(true, "IceFrost/IceFrost","",new Vector3(0,-1.2f,0), new Vector3(0,0,0),1.5f,Color.white,new List<SubEmitters>(){ },"",Icicles_IceFrost),
}
)
},
{ "/Skill/ArrowRain2",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "ArrowRain2/ArrowRain","",new Vector3(0,0f,0), new Vector3(90,0,0),1f,Color.white,new List<SubEmitters>(){ },""),
// new ParticleProperty(true, "IceFrost/IceFrost","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),1.5f,Color.white,new List<SubEmitters>(){ },"",Icicles_IceFrost),
}
)
},
{ "/Skill/IceRock2",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "IceRock2/IceRock2","",new Vector3(0,-0,0), new Vector3(90,0,0),0.2f,Color.white,new List<SubEmitters>(){ },""),
//new ParticleProperty(true, "IceFrost/IceFrost","",new Vector3(0,-0,0), new Vector3(0,0,0),1.5f,Color.white,new List<SubEmitters>(){ },"",Icicles_IceFrost),
}
)
},
{ "/Skill/FireBall",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "ExplosionFire/ExplosionFire","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ }), //子粒子放在主粒子之后
new ParticleProperty(true, "FireBall/FireBall","",new Vector3(0,0,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){new SubEmitters(ParticleSystemSubEmitterType.Collision, "ExplosionFire") },"",null,ConstDef.Layer_NPC),
}
)
},
{ "/Skill/LineRender1",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "LineRender1/LineRender1","",new Vector3(0,0f,0), new Vector3(180,0,0),1f,Color.white,new List<SubEmitters>(){ }), //子粒子放在主粒子之后
}
)
},
{ "/Skill/LineRender2",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "LineRender2/LineRender","",new Vector3(0,0f,0), new Vector3(180,0,0),1f,Color.white,new List<SubEmitters>(){ }), //子粒子放在主粒子之后
}
)
},
{ "/Skill/LineRender3",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "LineRender3/LineRender","",new Vector3(0,0f,0), new Vector3(0,0,0),1f,Color.white,new List<SubEmitters>(){ }), //子粒子放在主粒子之后
}
)
},
{ "/Skill/Thorns",new ParticleObjInfo
(
new List<ParticleProperty>
{
new ParticleProperty(true, "Thorns/Thorns","",new Vector3(0,-1.85f,0), new Vector3(0,0,0),0.8f,Color.white,new List<SubEmitters>(){ }), //子粒子放在主粒子之后
}
)
},
4.来自网络的游戏粒子特效
- 笔记花了大量时间通过各种途径(有免费的,也有收费的)获取上几百个粒子特效工程,祛粕存菁,留存的优秀粒子特效工程中累计数千个经典例子特效全部集成到示例工程中
:
:
二、示例工程编译及运行
- 解压CreateParticlePrefab.zip文件,可得到如下目录结构
:
- 使用unity 2019.2.2f1版本打开CreateParticlePrefab\Assets文件夹:
- 点击菜单栏"Tool“ -> "CreateParticle“ -> ”基本粒子“ 创建各种基本粒子、点击"Tool“ ->
"CreateParticle“ -> ”粒子预制体“创建粒子预制体。
示例工作预置的粒子不太多,只是提供参考指导,用户可根据实际需求从各种基本粒子定制自己的粒子特效。
三、资源下载
-
获取示例工程资源
链接:https://pan.baidu.com/s/1gHVSo3zkDw2ZUN8sL8iwyQ?pwd=pt5n
提取码:pt5n