Unity之弹床(蹦床效果)

使用代码实现点击一个平面,平面会像弹床一样上下起伏。

using UnityEngine;

/// <summary>
/// 弹床效果.
/// </summary>
public class WaveMechanic : MonoBehaviour
{
	// Fields
	public float animateSpeed;
	public bool animeSplash;
	public int rows = 128;
	public int cols = 128;
	public float dampner = 0.999f;
	public GameObject[] interactObjects;
	public float maxWaveHeight = 0.2f;
	public float maxWaveHeightAnime;
	public Mesh mesh;
	public bool ObjectInteraction;
	public Collider raycastArea;
	public float slowdown;
	public int splashForce = 50;
	public bool swapMe = true;
	public LayerMask unitLayerMask;
	public bool WaveOnTapSwitch;
	
	private int[] buffer1;
	private int[] buffer2;
	private int[] vertexIndices;
	private Vector3[] vertices;
	
	// Methods
	private void checkInput()
	{
		if (this.WaveOnTapSwitch && Input.GetMouseButton(0))
		{
			RaycastHit hit;
			this.unitLayerMask = ~this.unitLayerMask;
			if (this.raycastArea.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100f))
			{
				Bounds bounds = this.mesh.bounds;
				float num = (bounds.max.x - bounds.min.x) / ((float) this.cols);
				float num2 = (bounds.max.z - bounds.min.z) / ((float) this.rows);
				float num3 = (bounds.max.x - bounds.min.x) - ((bounds.max.x - bounds.min.x) * hit.textureCoord.x);
				float num4 = (bounds.max.z - bounds.min.z) - ((bounds.max.z - bounds.min.z) * hit.textureCoord.y);
				float num5 = num3 / num;
				float num6 = num4 / num2;
				if (((num5 >= 5f) && (num5 <= 60f)) && ((num6 <= 50f) && (num6 >= 5f)))
				{
					this.splashAtPoint((int) num5, (int) num6);
				}
			}
		}
	}
	
	private void checkObject()
	{
		if (this.ObjectInteraction)
		{
			Vector3 vector = new Vector3(0f, 1f, 0f);
			foreach (GameObject obj2 in this.interactObjects)
			{
				RaycastHit hit;
				if (Physics.Raycast(obj2.transform.position, -vector, out hit))
				{
					Bounds bounds = this.mesh.bounds;
					float num2 = (bounds.max.x - bounds.min.x) / ((float) this.cols);
					float num3 = (bounds.max.z - bounds.min.z) / ((float) this.rows);
					float num4 = (bounds.max.x - bounds.min.x) - ((bounds.max.x - bounds.min.x) * hit.textureCoord.x);
					float num5 = (bounds.max.z - bounds.min.z) - ((bounds.max.z - bounds.min.z) * hit.textureCoord.y);
					float num6 = num4 / num2;
					float num7 = num5 / num3;
					if (((num6 >= 5f) && (num6 <= 60f)) && ((num7 <= 50f) && (num7 >= 5f)))
					{
						this.splashAtPoint((int) num6, (int) num7);
					}
				}
			}
		}
	}
	
	private void processRipples(int[] source, int[] dest)
	{
		int num = 0;
		int num2 = 0;
		int index = 0;
		for (num2 = 1; num2 < (this.rows - 1); num2++)
		{
			for (num = 1; num < this.cols; num++)
			{
				index = (num2 * (this.cols + 1)) + num;
				dest[index] = ((((source[index - 1] + source[index + 1]) + source[index - (this.cols + 1)]) + source[index + (this.cols + 1)]) >> 1) - dest[index];
				dest[index] = (int) ((dest[index] * this.dampner) - (Time.deltaTime * this.slowdown));
			}
		}
	}
	
	public void splashAtPoint(int x, int y)
	{
		int index = (y * (this.cols + 1)) + x;
		this.buffer1[index] = this.splashForce;
		this.buffer1[index - 1] = this.splashForce;
		this.buffer1[index + 1] = this.splashForce;
		this.buffer1[index + (this.cols + 1)] = this.splashForce;
		this.buffer1[(index + (this.cols + 1)) + 1] = this.splashForce;
		this.buffer1[(index + (this.cols + 1)) - 1] = this.splashForce;
		this.buffer1[index - (this.cols + 1)] = this.splashForce;
		this.buffer1[(index - (this.cols + 1)) + 1] = this.splashForce;
		this.buffer1[(index - (this.cols + 1)) - 1] = this.splashForce;
	}
	
	private void splashAtPointA(int x, int y)
	{
		int index = (y * (this.cols + 1)) + x;
		this.buffer1[index] = this.splashForce + 100;
		this.buffer1[index - 1] = this.splashForce + 200;
		this.buffer1[index + 1] = this.splashForce + 200;
		this.buffer1[index + (this.cols + 1)] = this.splashForce + 200;
		this.buffer1[(index + (this.cols + 1)) + 1] = this.splashForce + 200;
		this.buffer1[(index + (this.cols + 1)) - 1] = this.splashForce + 200;
		this.buffer1[index - (this.cols + 1)] = this.splashForce + 200;
		this.buffer1[(index - (this.cols + 1)) + 1] = this.splashForce + 200;
	}
	
	private void Start()
	{
		MeshFilter component = (MeshFilter) base.GetComponent(typeof(MeshFilter));
		this.mesh = component.mesh;
		this.vertices = this.mesh.vertices;
		this.buffer1 = new int[this.vertices.Length];
		this.buffer2 = new int[this.vertices.Length];
		Bounds bounds = this.mesh.bounds;
		float num = (bounds.max.x - bounds.min.x) / ((float) this.cols);
		float num2 = (bounds.max.z - bounds.min.z) / ((float) this.rows);
		this.vertexIndices = new int[this.vertices.Length];
		int index = 0;
		for (index = 0; index < this.vertices.Length; index++)
		{
			this.vertexIndices[index] = -1;
			this.buffer1[index] = 0;
			this.buffer2[index] = 0;
		}
		for (index = 0; index < this.vertices.Length; index++)
		{
			float num4 = (this.vertices[index].x - bounds.min.x) / num;
			float num5 = (this.vertices[index].z - bounds.min.z) / num2;
			float num6 = ((num5 * (this.cols + 1)) + num4) + 0.5f;
			if (this.vertexIndices[(int) num6] >= 0)
			{
				MonoBehaviour.print("smash");
			}
			this.vertexIndices[(int) num6] = index;
		}
	}
	
	private void Update()
	{
		this.checkInput();
		this.checkObject();
		this.WaveUpdate();
	}
	
	private void WaveUpdate()
	{
		int[] numArray;
		int num;
		if (this.swapMe)
		{
			this.processRipples(this.buffer1, this.buffer2);
			numArray = this.buffer2;
		}
		else
		{
			this.processRipples(this.buffer2, this.buffer1);
			numArray = this.buffer1;
		}
		this.swapMe = !this.swapMe;
		Vector3[] vectorArray = new Vector3[this.vertices.Length];
		int index = 0;
		if (this.animeSplash)
		{
			for (index = 0; index < numArray.Length; index++)
			{
				num = this.vertexIndices[index];
				vectorArray[num] = this.vertices[num];
				vectorArray[num].y += ((numArray[index] * 1f) / ((float) this.splashForce)) * this.maxWaveHeightAnime;
			}
		}
		else
		{
			for (index = 0; index < numArray.Length; index++)
			{
				num = this.vertexIndices[index];
				vectorArray[num] = this.vertices[num];
				vectorArray[num].y += ((numArray[index] * 1f) / ((float) this.splashForce)) * this.maxWaveHeight;
			}
		}
		this.mesh.vertices = vectorArray;
	}
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值