赞
踩
嗨,大家好,我是新发。
看过我上一篇文章的同学应该知道,我最近自学了Blender
建模,感兴趣的同学可以看下我上一篇文章,《【游戏开发创新】当我学了Blender 建模,自制3D电脑桌面,回收站爆发了,把我做的模型都吐了出来(Blender | Unity | FBX)》。
马上要中秋节了,那我做一个放孔明灯的Demo
吧~
Demo
最终效果如下,
仰视视角:
高空平视视角:
月亮视角:
下面,我就讲下我这个Demo
的制作过程吧~
孔明灯的模型我是使用Blender
做的。
Blender
官网:https://www.blender.org/
Blender
中国社区:https://www.blendercn.org/
Blender
中文手册:https://docs.blender.org/manual/zh-hans/2.79/about/introduction.html
我使用的Blender
版本是2.93.4
,
注:关于
Blender
的教程网上蛮多的,这里我就不过多讲了,掌握基本操作和快捷键,很快就可以上手建模啦~
使用Blender
建一个简易的孔明灯模型,
先做灯罩,
接着做灯座,
再做灯线,
最终如下:
网格如下:
在Blender
中点击菜单File / Export / FBX
,将模型导出成FBX
格式,
如下:
将孔明灯的FBX
文件导入到Unity
工程中,
将模型拖到场景中,再拖到Prefabs
目录中,保存为预设文件,如下:
材质的Shader
我准备使用ShaderGraph
来制作。
我之前写过一篇ShaderGraph
的文章:《ShaderGraph使用教程与各种特效案例:Unity2020》,推荐先看下这篇文章。
先通过Package Manager
搜索universal rp
,点击Install
执行安装,
在Project
视图中右键鼠标,点击菜单Create / Rendering / Universal Render Pipeline / Pipeline Asset (Forward Renderer)
,
创建UniversalRenderPipelineAsset
,如下
点击菜单Edit / Project Settings...
,打开Project Settings
窗口
选择Graphics
分页,把UniversalRenderPipelineAsset
拖到Scriptable Render Pipeline Settings
中,
在Project
视图中右键鼠标,点击菜单Create / Shader / Universal Render Pipeline / Lit Shader Graph
,创建一个PBR
的ShaderGraph
,
重命名为LampshadeShader
,作为灯罩的shader
,
点击Open Shader Editor
打开编辑器,
我想要有一点半透明的效果,把Surface
改为Transparent
,设置一下基础色、自发光和透明度,如下:
设置好后,记得点击Save Asset
保存,
创建一个材质球,设置Shader
为刚刚的LampshadeShader
,
将材质球应用到模型灯罩上,如下:
效果如下:
我们加个点光,效果如下:
同理,把灯座和线的材质也做了,
效果如下:
我们需要在灯座上做一个火苗,可以使用粒子系统来做。
在PhotoShop中
新建一个1024 x 1024
的画布。
如下:
给画布填充黑色,
因为我们要在画布上画火焰的序列帧,为了不画偏了,建议创建参考线。比如我们要画2 x 2
的序列帧,那么画布就要分割成4
个格子,我们需要知道每个格子的中心点位置等等。
点击菜单 视图 / 新建参考线
,
如下,三条垂直参考线分别是256、512、768
,七条水平参考线分别是146、256、366、512、658、768、878
,我们在如下的4
个位置分别画火焰的序列帧图案即可。
新建一个图层,
在刚刚新建的图层上画火焰序列帧图,凭感觉自由发挥,我也是随便画的,
把黑色的底图图层隐藏掉,
点击菜单文件 / 存储为
,
选择存储格式为PNG
,保存图片为file.png
。
将刚刚的火焰序列帧图片file.png
拷贝到Unity
工程中,如下:
图片格式属性设置如下:
在Hierarchy
视图空白处右键鼠标,点击菜单Effects / ParticleSystem
,
此时场景中就会创建出一个粒子系统,如下:
创建一个材质球,重名名为fire
,设置Shader
为Mobile/Particles/Additive
,并设置贴图为刚刚的火苗序列帧,
选中场景中的粒子系统,展开Renderer
标签页,把材质球file
拖给粒子系统,如下:
此时可以看到,粒子喷射出来的图案变成序列帧图案了:
上面我们看到,虽然粒子喷出来的图案是火焰序列帧图案了,但是它喷出来的不是一帧一帧的图案,我们需要开启粒子的序列帧属性。
勾选Texture Sheet Animation
,设置Tiles
为 2 x 2
。
注,如果你的火焰序列帧图案是3 x 3的,则这里的
Tiles
要设置为3x 3
。
此时效果如下:
上面我们看到粒子拼命地往上飞,这是因为它的初始速度比较大。我们可以把Start Speed
调小,比如调整为0.2 ~ 0.3
,如下:
效果如下,现在温和很多了:
我们看到粒子喷得很散,这是因为粒子的喷射区域是一个圆锥体(Cone
),
我们可以把它的区域调小,展开Shape
标签页,把张开角度Angle
调整为20
,把半径Radius
调整为0.01
,
现在喷射区域很集中了,
我们希望每个粒子的生命周期时长是随机的,将Start Lifetime
设置为0.3 ~ 0.8
,
效果如下,到这里已经有点感觉了对不对。
现在给粒子设置一个随时间而变化的颜色,勾选Color over Lifetime
,设置一个渐变色。
效果如下:
上面的这个效果,每个粒子会独立得更新帧,为了方便观察,我们先把Max Particles
调整为1
,
这样就看的出来了,一个粒子在它的生命周期内独立地更新它的图像帧,
我们希望每个粒子是固定的某一帧,展开Texture Sheet Animation
标签页,设置Time Mode
为Lifetime
,设置Frame over Time
为0 ~ 3
。
再观察一下效果,现在每个粒子是固定的某一帧啦,
把Max Particles
调整成50
,效果如下:
火焰燃烧的时候,是会有那种忽大忽小的效果的,我们希望粒子的大小随时间而变化,勾选Size over Lifetime
,我编辑了一个曲线,
效果如下:
PhotoShop
再画个火星的图案,
导入Unity
中,对应地做一个材质球,
在火焰粒子节点下再创建一个粒子系统作为火星,
与火焰粒子一样调整相关参数,火星的参数就不展开讲了,上面的火焰效果如果能做出来,火星基本就没问题的了。
效果如下:
将火苗粒子保存为预设,并放入孔明灯预设中,效果如下:
月球模型,简单处理,一个球体,
纹理贴图我是在Texture Haven
下载的,地址:https://polyhaven.com/textures
这上面的纹理都是免费下载并且可直接商用的,良心网站!
我找了一个岩石纹理,
月球材质的Shader
我也使用ShaderGraph
来做,节点如下:
应用到材质球中,预览效果如下:
把月球放入场景中,放到一个比较高的位置,
找一个天空盒的资源,我用的是这个星空天空盒,可以在AssetStore
上免费下载,地址:https://assetstore.unity.com/packages/2d/textures-materials/sky/stellar-sky-99558
下载下来导入Unity
中,点击菜单Window / Rendering /Lighting
,
打开Lighting
窗口,进入Environment
分页,设置天空盒材质球,设置环境光渐变色,如下:
星空效果有了,
我想要一开始在空中生成很多个孔明灯,写GenKongming.cs
脚本,
先声明一些变量
/// <summary> /// 孔明灯预设 /// </summary> public GameObject lanternObj; private Transform selfTrans; /// <summary> /// 主摄像机的Transform /// </summary> private Transform camTrans; /// <summary> /// 主摄像机 /// </summary> private Camera cam;
在Start
函数中创建50
个孔明灯,
void Start()
{
selfTrans = transform;
cam = Camera.main;
camTrans = cam.transform;
//初始创建50个孔明灯
for (int i = 0; i < 50; ++i)
{
var go = Instantiate(lanternObj);
go.transform.position = new Vector3(Random.Range(-100, 100), Random.Range(50, 100), Random.Range(-100, 100));
go.transform.SetParent(selfTrans, false);
}
}
我们还想让它每隔一个时间间隔就生成一个孔明灯,无限生成,写一个协程,并在Start
函数中启动这个协程,
void Start() { // ... // 协程无限循环创建孔明灯 StartCoroutine(StartGen()); } private IEnumerator StartGen() { while (true) { var go = Instantiate(lanternObj); go.transform.position = new Vector3(Random.Range(-100, 100), 0, Random.Range(-100, 100)); go.transform.SetParent(selfTrans, false); yield return new WaitForSeconds(1); } }
另外,我们希望点击鼠标右键的时候,在鼠标的位置生成一个孔明灯,
private void Update()
{
// 点击鼠标右键,在鼠标位置处生成一个孔明灯
if (Input.GetMouseButtonDown(1))
{
var go = Instantiate(lanternObj);
var pos = cam.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 3f));
go.transform.SetParent(selfTrans, false);
go.transform.position = pos;
}
}
为了可以从多个视角观察,我们加上摄像机旋转控制的逻辑,
private void Update()
{
// ...
// 鼠标左键拖动,旋转摄像机
if(Input.GetMouseButton(0))
{
float inputX = Input.GetAxis("Mouse X")*1.5f;
camTrans.Rotate(Vector3.up, inputX, Space.World);
}
}
我们还可以在高空再创建一个摄像机,通过按空白键
来控制这个高空摄像机的激活,
/// <summary>
/// 高空摄像机
/// </summary>
public GameObject cam2;
private void Update()
{
// ...
// 高空摄像机的激活控制
if(Input.GetKeyDown(KeyCode.Space))
{
cam2.gameObject.SetActive(!cam2.activeSelf);
}
}
在场景中创建一个空物体,重命名为GenKongming
,挂上GenKongming
脚本,设置成员变量,
我们希望场景中的孔明灯自身有一个升空的逻辑,创建一个KongmingLamp.cs
脚本,代码很简单,如下:
using UnityEngine; public class KongmingLamp : MonoBehaviour { private Transform trans; private Vector3 speed; void Start() { trans = transform; // 随机一个升空速度 speed = new Vector3(Random.Range(-0.5f, 0.5f), Random.Range(1, 3), Random.Range(-0.5f, 0.5f)); } void Update() { // 沿着速度方向升空 trans.position += speed * Time.deltaTime; // 高度达到500,自我销毁 if (trans.position.y > 500) { Destroy(gameObject); } } }
将其挂到孔明灯预设上,
运行Unity
,效果如下。
仰视视角:
高空平视视角:
加上屏幕后处理,
效果非常棒,
仰视视角:
高空平视视角:
月亮视角:
本工程我已上传到CODE CHINA
,感兴趣的同学可自行下载学习。
地址:https://codechina.csdn.net/linxinfa/UnityMidAutumnDemo
注:我使用的Unity版本为Unity 2021.1.9f1c1 (64-bit)
。
好了,就到这里吧,提前祝大家中秋快乐,愿新年,胜旧年!
我是林新发:https://blog.csdn.net/linxinfa
原创不易,若转载请注明出处,感谢大家~
喜欢我的可以点赞、关注、收藏,如果有什么技术上的疑问,欢迎留言或私信,我们下期见~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。