Unity插件 - MeshEditor(四) 模型融化特效

现在的电影里有很多妖魔在死亡后身体逐渐融化并下滑最后化为一滩黑水的情景,本次出于兴趣大致研究了这个效果,原理是控制模型的顶点向一个方向坍塌,坍塌到最低点时再根据法线方向扩散形成黑水状。



第一步:


添加MeshMelt脚本,属性面板如下:


MeltDirection:融化的方向轴;

Melt Speed:融化速度;



第二步:


选择以Y轴融化为例。

首先,筛选出模型的最高点及最低点。

//获取目标网格
        _Mesh = _Target.GetComponent<MeshFilter>().mesh;
        //获取目标所有顶点
        _AllVertex = _Mesh.vertices;
        //记录目标融化至高点及至低点
        _DissolutionMaxPoint = _DissolutionMinPoint = _AllVertex[0];
        //获取目标融化至高点及至低点
        for (int i = 0; i < _AllVertex.Length; i++)
        {
            if (_MeltDirection == MeltDirection.x)
            {
                if (_AllVertex[i].x < _DissolutionMinPoint.x)
                    _DissolutionMinPoint = _AllVertex[i];
                else if (_AllVertex[i].x > _DissolutionMaxPoint.x)
                    _DissolutionMaxPoint = _AllVertex[i];
            }
            else if (_MeltDirection == MeltDirection.y)
            {
                if (_AllVertex[i].y < _DissolutionMinPoint.y)
                    _DissolutionMinPoint = _AllVertex[i];
                else if (_AllVertex[i].y > _DissolutionMaxPoint.y)
                    _DissolutionMaxPoint = _AllVertex[i];
            }
            else if (_MeltDirection == MeltDirection.z)
            {
                if (_AllVertex[i].z < _DissolutionMinPoint.z)
                    _DissolutionMinPoint = _AllVertex[i];
                else if (_AllVertex[i].z > _DissolutionMaxPoint.z)
                    _DissolutionMaxPoint = _AllVertex[i];
            }
        }
        IsCanMelt = true;


然后循环遍历所有点向着最低点的高度塌陷,已达到最低点位置的点开始以法线方向扩散,当最高点低于最低点时,融化结束。

if (_MeltDirection == MeltDirection.y && _DissolutionMaxPoint.y > _DissolutionMinPoint.y)
            {
                for (int i = 0; i < _AllVertex.Length; i++)
                {
                    //目标点开始塌陷
                    if (_AllVertex[i].y > _DissolutionMinPoint.y)
                    {
                        _AllVertex[i] = new Vector3(_AllVertex[i].x, _AllVertex[i].y - Time.deltaTime * _MeltSpeed, _AllVertex[i].z);
                    }
                    if (_AllVertex[i].y < _DissolutionMinPoint.y)
                    {
                        _AllVertex[i] = new Vector3(_AllVertex[i].x, _DissolutionMinPoint.y, _AllVertex[i].z);
                    }
                    //目标点开始扩散
                    if (_AllVertex[i].y == _DissolutionMinPoint.y)
                    {
                        _AllVertex[i] += _Mesh.normals[i] * Time.deltaTime * _MeltSpeed;
                    }
                }
                //刷新目标网格
                _Mesh.vertices = _AllVertex;
                _Target.GetComponent<MeshFilter>().mesh = _Mesh;
                //重新记录至高点
                _DissolutionMaxPoint = new Vector3(_DissolutionMaxPoint.x
                    , _DissolutionMaxPoint.y - Time.deltaTime * _MeltSpeed, _DissolutionMaxPoint.z);
            }


那么,核心代码主要有这两部分就完成了,之后在其他脚本里,想要动态的控制物体融化的话,可以调用融化开关函数

/// <summary>
    /// 开始融化
    /// </summary>
    public void BeginMelt()
    {
        if (IsCanMelt)
        {
            IsStartMelt = true;
            IsCanMelt = false;
            transform.GetComponent<Collider>().enabled = false;
        }
        else
            Debug.Log("由于未知原因,目标无法融化或处于融化中!");
    }


最后附上动态演示图:



-----by MeshEditor


posted on   王亮1  阅读(756)  评论(0编辑  收藏  举报

编辑推荐:
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)

导航

< 2025年1月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示