↓首先这是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().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