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

↓首先这是Unity出了个Bug, 颜色乱涂了
Unity漫延的实现思路(流体漫延, 火烧草地的漫延等)_第1张图片
白色区域开始漫延, 当它遇到白球的时候, 会向两边分叉漫延.
这就很神奇.
颜色也会有碰撞吗?
我去网上搜实现的方法, 没搜到.
图形学我懂的不多, 又想实现这类的效果, 怎么办呢, 模拟一个吧
用1万个Cube
先上效果图:
Unity漫延的实现思路(流体漫延, 火烧草地的漫延等)_第2张图片
上代码
主控制类:

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个角的计算
上图先
Unity漫延的实现思路(流体漫延, 火烧草地的漫延等)_第3张图片
上代码:
(另外记得把主控制类里的这行注释取消: //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().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

你可能感兴趣的:(游戏开发,Unity,游戏,unity)