【游戏开发创新】自学Blender建模,自制孔明灯,在Unity中点亮整个星空,愿新年,胜旧年(Unity | 建模 | 粒子系统 | 预设)

2021年9月15日 11点热度 0条评论 来源: 林新发

文章目录

一、前言

嗨,大家好,我是新发。
看过我上一篇文章的同学应该知道,我最近自学了Blender建模,感兴趣的同学可以看下我上一篇文章,《【游戏开发创新】当我学了Blender 建模,自制3D电脑桌面,回收站爆发了,把我做的模型都吐了出来(Blender | Unity | FBX)》
马上要中秋节了,那我做一个放孔明灯的Demo吧~
Demo最终效果如下,

仰视视角:


高空平视视角:

月亮视角:

下面,我就讲下我这个Demo的制作过程吧~

二、孔明灯Blender建模

孔明灯的模型我是使用Blender做的。

1、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的教程网上蛮多的,这里我就不过多讲了,掌握基本操作和快捷键,很快就可以上手建模啦~

2、孔明灯模型

使用Blender建一个简易的孔明灯模型,
先做灯罩,

接着做灯座,

再做灯线,


最终如下:

网格如下:

3、导出FBX

Blender中点击菜单File / Export / FBX,将模型导出成FBX格式,

如下:

三、孔明灯Unity部分

1、Unity导入FBX

将孔明灯的FBX文件导入到Unity工程中,

将模型拖到场景中,再拖到Prefabs目录中,保存为预设文件,如下:

2、制作材质

材质的Shader我准备使用ShaderGraph来制作。
我之前写过一篇ShaderGraph的文章:《ShaderGraph使用教程与各种特效案例:Unity2020》,推荐先看下这篇文章。

2.1、安装URP

先通过Package Manager搜索universal rp,点击Install执行安装,

2.2、创建UniversalRenderPipelineAsset

Project视图中右键鼠标,点击菜单Create / Rendering / Universal Render Pipeline / Pipeline Asset (Forward Renderer)

创建UniversalRenderPipelineAsset,如下

2.3、设置Scriptable Render Pipeline Settings

点击菜单Edit / Project Settings...,打开Project Settings窗口

选择Graphics分页,把UniversalRenderPipelineAsset拖到Scriptable Render Pipeline Settings中,

2.4、创建ShaderGraph

Project视图中右键鼠标,点击菜单Create / Shader / Universal Render Pipeline / Lit Shader Graph,创建一个PBRShaderGraph

重命名为LampshadeShader,作为灯罩的shader

2.5、创建ShaderGraph

点击Open Shader Editor打开编辑器,

我想要有一点半透明的效果,把Surface改为Transparent,设置一下基础色、自发光和透明度,如下:

设置好后,记得点击Save Asset保存,

2.6、创建材质球

创建一个材质球,设置Shader为刚刚的LampshadeShader

2.7、模型使用材质球

将材质球应用到模型灯罩上,如下:

效果如下:

我们加个点光,效果如下:

3、灯座与线的材质

同理,把灯座和线的材质也做了,

效果如下:

4、制作孔明灯火苗

我们需要在灯座上做一个火苗,可以使用粒子系统来做。

4.1、画火苗序列帧

PhotoShop中新建一个1024 x 1024的画布。

如下:

给画布填充黑色,

因为我们要在画布上画火焰的序列帧,为了不画偏了,建议创建参考线。比如我们要画2 x 2的序列帧,那么画布就要分割成4个格子,我们需要知道每个格子的中心点位置等等。
点击菜单 视图 / 新建参考线

如下,三条垂直参考线分别是256、512、768,七条水平参考线分别是146、256、366、512、658、768、878,我们在如下的4个位置分别画火焰的序列帧图案即可。

新建一个图层,

在刚刚新建的图层上画火焰序列帧图,凭感觉自由发挥,我也是随便画的,

把黑色的底图图层隐藏掉,


点击菜单文件 / 存储为

选择存储格式为PNG,保存图片为file.png

4.2、粒子系统制作火苗

将刚刚的火焰序列帧图片file.png拷贝到Unity工程中,如下:

图片格式属性设置如下:

Hierarchy视图空白处右键鼠标,点击菜单Effects / ParticleSystem

此时场景中就会创建出一个粒子系统,如下:


创建一个材质球,重名名为fire,设置ShaderMobile/Particles/Additive,并设置贴图为刚刚的火苗序列帧,

选中场景中的粒子系统,展开Renderer标签页,把材质球file拖给粒子系统,如下:

此时可以看到,粒子喷射出来的图案变成序列帧图案了:

上面我们看到,虽然粒子喷出来的图案是火焰序列帧图案了,但是它喷出来的不是一帧一帧的图案,我们需要开启粒子的序列帧属性。
勾选Texture Sheet Animation,设置Tiles2 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 ModeLifetime,设置Frame over Time0 ~ 3

再观察一下效果,现在每个粒子是固定的某一帧啦,

Max Particles调整成50,效果如下:

火焰燃烧的时候,是会有那种忽大忽小的效果的,我们希望粒子的大小随时间而变化,勾选Size over Lifetime,我编辑了一个曲线,

效果如下:

PhotoShop再画个火星的图案,

导入Unity中,对应地做一个材质球,

在火焰粒子节点下再创建一个粒子系统作为火星,

与火焰粒子一样调整相关参数,火星的参数就不展开讲了,上面的火焰效果如果能做出来,火星基本就没问题的了。

效果如下:

4.3、火苗放入孔明灯中

将火苗粒子保存为预设,并放入孔明灯预设中,效果如下:

四、制作月球

1、月球模型

月球模型,简单处理,一个球体,

2、月球纹理

纹理贴图我是在Texture Haven下载的,地址:https://polyhaven.com/textures

这上面的纹理都是免费下载并且可直接商用的,良心网站!
我找了一个岩石纹理,

3、月球材质

月球材质的Shader我也使用ShaderGraph来做,节点如下:

应用到材质球中,预览效果如下:

4、月球放入场景

把月球放入场景中,放到一个比较高的位置,

五、星空天空盒

1、天空盒资源

找一个天空盒的资源,我用的是这个星空天空盒,可以在AssetStore上免费下载,地址:https://assetstore.unity.com/packages/2d/textures-materials/sky/stellar-sky-99558

2、天空盒设置

下载下来导入Unity中,点击菜单Window / Rendering /Lighting

打开Lighting窗口,进入Environment分页,设置天空盒材质球,设置环境光渐变色,如下:

星空效果有了,

六、写脚本

1、孔明灯生成脚本:GenKongming.cs

我想要一开始在空中生成很多个孔明灯,写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脚本,设置成员变量,

2、孔明灯升空脚本:KongmingLamp.cs

我们希望场景中的孔明灯自身有一个升空的逻辑,创建一个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
原创不易,若转载请注明出处,感谢大家~
喜欢我的可以点赞、关注、收藏,如果有什么技术上的疑问,欢迎留言或私信,我们下期见~

    原文作者:林新发
    原文地址: https://blog.csdn.net/linxinfa/article/details/120261208
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。