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

 

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神码编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值