Unity漫延的实现思路(流体漫延, 火烧草地的漫延等)

13 篇文章 0 订阅

↓首先这是Unity出了个Bug, 颜色混乱了
在这里插入图片描述
白色区域开始漫延, 当它遇到白球的时候, 会向两边分叉漫延.
这就很神奇.
颜色也会有碰撞吗?

我想实现这种效果, 于是去网上搜实现的方法, 没搜到.
那就自己模拟一个吧
用了1万个Cube
先上效果图:
在这里插入图片描述
上代码
主控制类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Water : MonoBehaviour
{
    public static Water instance;
    public Dictionary<string, WaterCube> dic = new Dictionary<string, WaterCube>();
    void Awake()
    {
        instance = this;

        CreateAllCubes();
        CreateDiedCubes();

        //启动点
        dic["0:0"].SetActive();
        dic["50:90"].SetActive();
    }

    //生成白色方块
    void CreateAllCubes()
    {
        GameObject prefab = Resources.Load("Prefabs/Cube") as GameObject;

        for (int i = 0; i < 100; i++)
        {
            for (int j = 0; j < 100; j++)
            {
                WaterCube go = Instantiate<WaterCube>(prefab.GetComponent<WaterCube>(), new Vector3(i, j) * 2, Quaternion.identity);
                go.i = i;
                go.j = j;
                dic.Add(i.ToString() + ":" + j.ToString(), go);
            }
        }
    }

    //生成蓝色方块
    void CreateDiedCubes()
    {
        for (int i = 50; i < 60; i++)
        {
            for (int j = 40; j < 80; j++)
            {
                Died(i, j);
            }
        }

        for (int i = 20; i < 70; i++)
        {
            for (int j = 30; j < 40; j++)
            {
                Died(i, j);
            }
        }

        for (int i = 20; i < 40; i++)
        {
            for (int j = 60; j < 80; j++)
            {
                Died(i, j);
            }
        }
    }

    void Died(int i, int j)
    {
        string id = (i).ToString() + ":" + (j).ToString();
        dic[id].isChanged = true;//边
        //dic[id].isChanged2 = true;//角
        dic[id].gameObject.GetComponent<Renderer>().material.color = Color.blue;
    }
}

方块类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WaterCube : MonoBehaviour
{
    Dictionary<string, WaterCube> dic;
    public int i;
    public int j;
    public float speed;
    float time = 0.3f;
    public bool isActive = false;
    public bool isChanged = false;
    public void SetActive()
    {
        speed += 1;
        if (!isActive)
        {
            isActive = true;
        }
    }
    void Start()
    {
        dic = Water.instance.dic;
    }

    void Update()
    {
        if (!isActive)
        {
            return;
        }
        if (!isChanged)
        {
            time -= speed * Time.deltaTime;
            if (time <= 0)
            {
                isChanged = true;
                gameObject.GetComponent<Renderer>().material.color = Color.red;
                Draw();
            }
        }
    }
    public void Draw()
    {
        string next0 = (i - 1).ToString() + ":" + (j).ToString();
        string next1 = (i + 1).ToString() + ":" + (j).ToString();
        string next2 = (i).ToString() + ":" + (j - 1).ToString();
        string next3 = (i).ToString() + ":" + (j + 1).ToString();
        Do(next0);
        Do(next1);
        Do(next2);
        Do(next3);
    }
    private void Do(string id)
    {
        if (dic.ContainsKey(id))
        {
            if (dic[id].speed < speed * 0.4f)
            {
                dic[id].speed = speed * 0.4f;
            }
            dic[id].SetActive();
        }
    }
}

后面又改了一版, 使边界更圆滑, 就是加了4个角的计算
上图先
在这里插入图片描述
上代码:
(另外记得把主控制类里的这行注释取消: //dic[id].isChanged2 = true;//角)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WaterCube : MonoBehaviour
{
    Dictionary<string, WaterCube> dic;
    public int i;
    public int j;
    float force = 0; //周围有几个方块给我施加了转变力
    float time = 0.2f; //转变边所需时间
    float time2 = 0.24f; //转变角所需时间
    public bool isActive = false; //未被激活
    public bool isChanged = false; //未转变完成,边
    public bool isChanged2 = false; //未转变完成,角

    public void SetActive()
    {
        force += 1;
        if (!isActive)
        {
            isActive = true;
        }
    }

    void Start()
    {
        dic = Water.instance.dic;
    }

    void Update()
    {
        if (!isActive)
        {
            return;
        }

        //被激活后, 开始转变, 边
        if (!isChanged)
        {
            float trueSpeed = GetTrueSpeed(force);
            time -= trueSpeed * Time.deltaTime;
            if (time <= 0)
            {
                //时间到了, 转变完成
                isChanged = true;
                Draw();
                //gameObject.GetComponent<Renderer>().material.color = Color.red;
            }
        }

        //被激活后, 开始转变, 角
        if (!isChanged2)
        {
            float trueSpeed = GetTrueSpeed(force);
            time2 -= trueSpeed * Time.deltaTime;
            if (time2 <= 0)
            {
                //时间到了, 转变完成
                isChanged2 = true;
                Draw2();
                gameObject.GetComponent<Renderer>().material.color = Color.red;
            }
        }
    }

    //速度曲线, 可以用不同函数的来算
    float  GetTrueSpeed(float speed)
    {
        //return -2 / speed + 3;
        return 0.7f * speed;
    }

    //4个边相邻的方块
    public void Draw()
    {
        string next0 = (i - 1).ToString() + ":" + (j).ToString();
        string next1 = (i + 1).ToString() + ":" + (j).ToString();
        string next2 = (i).ToString() + ":" + (j - 1).ToString();
        string next3 = (i).ToString() + ":" + (j + 1).ToString();
        Do(next0);
        Do(next1);
        Do(next2);
        Do(next3);
    }

    //4个角相邻的方块
    public void Draw2()
    {
        string next0 = (i - 1).ToString() + ":" + (j - 1).ToString();
        string next1 = (i - 1).ToString() + ":" + (j + 1).ToString();
        string next2 = (i + 1).ToString() + ":" + (j - 1).ToString();
        string next3 = (i + 1).ToString() + ":" + (j + 1).ToString();
        Do(next0);
        Do(next1);
        Do(next2);
        Do(next3);
    }

    private void Do(string id)
    {
        if (dic.ContainsKey(id))
        {
            dic[id].SetActive();
        }
    }
}

性能, 额, 以后有空再说, 没空就这样了, 变量名也懒得改了


数学XY函数的曲线, 可以去↓
https://zh.numberempire.com/graphingcalculator.php?functions=1.5xlog(x)-1%2F36exp(-(36x-36%2F2.7183)%5E4)&xmin=-0.501587&xmax=1.418413&ymin=-0.90833&ymax=0.371671&var=x

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值