Unity 射线测距以及网格变形

Unity 射线测距以及网格变形


代码很简单没有难度,自己看一下应该就能明白。
OK 老规矩,直接上代码:

射线测距

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

/// <summary>
/// 网格变形器输入 & GL  距离绘制
///  
/// </summary>

public class MeshDeformerInput_ZH : MonoBehaviour
{

    //GL 起始  结束点
    private Vector3 _Target, _End;

	//距离
	private float _Distance = 0;
	//距离文字
	private string _DistanceStr = "";

	//点击计数
	private int _Number = 1;

	[Header("GUI 线段")]
	public Color _ColorGUI;
	[Header ("GUI 文字")]
	public Color _ColorStr;

	void Update()
	{
		if (Input.GetMouseButtonDown(1))
		{
			_Number++;

			Ray _GLRay = Camera.main.ScreenPointToRay(Input.mousePosition);
			RaycastHit _GLHit;
			if (Physics.Raycast(_GLRay, out _GLHit))
			{
				if (_GLHit.transform.tag == "Crash")
				{
					_Target = _GLHit.point;

					if (_Number == 2)
					{
						Ray _DistanceRay = Camera.main.ScreenPointToRay(Input.mousePosition);
						///射线碰到了物体,hit为鼠标碰到的物体,hit1是从该物体发出的射线碰撞到的物体
						RaycastHit _Hit1;
						if (Physics.Raycast(_DistanceRay, out _Hit1))
						{
							_End = _Hit1.point;

							Debug.DrawLine(_Target, _End);

							_Number = 0;
						}
					}
				}
			}

			//防止越界
			if (_Number > 2)
			{
				_Number = 1;
			}
			print(_Number);
		}
	}



	/// <summary>
	/// GL  绘制
	/// </summary>
	private void GLDrawLine(Vector3 _Target, Vector3 _End)
	{

		//返回这个向量的长度(只读)
		_Distance = (_End - _Target).magnitude;

		//如果距离不等于0
		if (_Distance != 0.0)
		{
			//显示位置
			_DistanceStr = _Distance.ToString("f2") + "M";

			//GL 绘制类型 (线段)
			GL.Begin(GL.LINE_STRIP);
			//线段颜色
			GL.Color(_ColorGUI);
			//开始位置
			GL.Vertex3(_Target.x, _Target.y, _Target.z);
			//结束位置
			GL.Vertex3(_End.x, _End.y, _End.z);
			//绘制结束
			GL.End();
		}
	}


	public float _SizeVector2;

	/// <summary>
	/// GUI  文字显示
	/// </summary>

	private void GUIStr(string _DistanceStr)
    {
        //如果距离文字不为空
        if (_DistanceStr != "")
        {
            //世界空间位置
            Vector3 _WorldPosition = new Vector3(((_Target + _End) / 2).x, ((_Target + _End) / 2).y, ((_Target + _End) / 2).z);
            //从世界空间转换到屏幕空间的位置
            Vector3 _Position = Camera.main.WorldToScreenPoint(_WorldPosition);
            //生成位置  在起始点到终点 的一半
            _Position = new Vector2(_Position.x, Screen.height - _Position.y);

            //GUI 颜色
            GUI.color = _ColorStr;
            //文字大小
            Vector2 _StrSize = GUI.skin.label.CalcSize(new GUIContent(_DistanceStr));
			//在屏幕上创建一个文本或纹理标签
			GUI.Label(new Rect(_Position.x - (_StrSize.x / 2), _Position.y - _StrSize.y, _StrSize.x +_SizeVector2, _StrSize.y +_SizeVector2), _DistanceStr);

        }
    }


    private void OnGUI()
    {
        if (_Number==1)
        {
			GUIStr(_DistanceStr);
		}
	}

    private void OnPostRender()
	{
		if (_Number == 1)
		{
			GLDrawLine(_Target, _End);
		}
	}

	
}

网格变形

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

/// <summary>
/// 网格变形器
/// </summary>
[RequireComponent(typeof(MeshFilter))]

public class MeshDeformer_ZH : MonoBehaviour
{

	[Header("弹力")]
	public float _SpringForce = 20f;
	[Header("衰减值")]
	public float _Damping = 5f;

	[Header("初始附加力")]
	public float _Force = 10f;
	[Header("初始衰减力")]
	public float _ForceOffset = 0.1f;

	//变形网格
	private Mesh DeformingMesh;
	//原始顶点数组  移动的顶点数组
	private Vector3[] _OriginalVertices, _DisplacedVertices;
	//顶点速度数组
	private Vector3[] _VertexVelocities;


	//等分标尺
	private float _UniformScale = 1f;

	void Start()
	{
		//变形网格获取
		DeformingMesh = GetComponent<MeshFilter>().mesh;
		//获取变形网格顶点数据
		_OriginalVertices = DeformingMesh.vertices;
		//变形顶点网格数据数组填充
		_DisplacedVertices = new Vector3[_OriginalVertices.Length];

		for (int i = 0; i < _OriginalVertices.Length; i++)
		{
			_DisplacedVertices[i] = _OriginalVertices[i];
		}
		//顶点速度网格速度数组长度填充
		_VertexVelocities = new Vector3[_OriginalVertices.Length];
	}

	void Update()
	{
		if (Input.GetMouseButton(0))
		{
			HandleInput();
		}


		//等分标尺 赋值
		_UniformScale = transform.localScale.x;
		//实时更新变形网格数据
		for (int i = 0; i < _DisplacedVertices.Length; i++)
		{
			UpdateVertex(i);
		}
		//返回顶点位置的副本或分配一个新的顶点位置数组
		DeformingMesh.vertices = _DisplacedVertices;
		//从三角形和顶点重新计算网格的法线。
		DeformingMesh.RecalculateNormals();
	}

	/// <summary>
	/// 点击输入
	/// </summary>
	void HandleInput()
	{
		Ray _InputRay = Camera.main.ScreenPointToRay(Input.mousePosition);
		RaycastHit _Hit;

		if (Physics.Raycast(_InputRay, out _Hit))
		{
			//获取变形网格
			MeshDeformer_ZH _Deformer = _Hit.collider.GetComponent<MeshDeformer_ZH>();
			if (_Deformer)
			{
				Vector3 _HitPoint = _Hit.point;
				_HitPoint += _Hit.normal * _ForceOffset;
				_Deformer.AddDeformingForce(_HitPoint, _Force);
			}
		}
	}


	/// <summary>
	/// 更新顶点  复位
	/// </summary>
	/// <param name="i"></param>
	void UpdateVertex(int i)
	{

		Vector3 _Velocity = _VertexVelocities[i];
		//位移数据 变形顶点数据  减去 原始顶点数组
		Vector3 _Displacement = _DisplacedVertices[i] - _OriginalVertices[i];
		//位移数据 赋值
		_Displacement *= _UniformScale;
		//速度矢量 减等于 位移数据 *  弹力 * 缓动时间
		_Velocity -= _Displacement * _SpringForce * Time.deltaTime;
		//速度矢量 * 等于 1 减去衰减值 * 缓动时间
		_Velocity *= 1f - _Damping * Time.deltaTime;
		//顶点速度数组 缓动时间
		_VertexVelocities[i] = _Velocity;
		//移动顶点数据数组  加等于 速度矢量 * (缓动时间 除以 等分标尺)
		_DisplacedVertices[i] += _Velocity * (Time.deltaTime / _UniformScale);
	}

	/// <summary>
	/// 添加变形力
	/// </summary>
	/// <param 位置="_HitPoint"></param>
	/// <param 力度="_Force"></param>
	public void AddDeformingForce(Vector3 _HitPoint, float _Force)
	{
		//从世界空间到局部空间的位置转换
		_HitPoint = transform.InverseTransformPoint(_HitPoint);
		//循环编辑 变形顶点网格数据
		for (int i = 0; i < _DisplacedVertices.Length; i++)
		{
			AddForceToVertex(i, _HitPoint, _Force);
		}
	}

	/// <summary>
	/// 顶点附加力
	/// </summary>
	/// <param 当前顶点="i"></param>
	/// <param 位置="_HitPoint"></param>
	/// <param 力度="_Force"></param>
	void AddForceToVertex(int i, Vector3 _HitPoint, float _Force)
	{
		// 偏移顶点位置  当前变形顶点网格数据 减去传递值 
		Vector3 _PointToVertex = _DisplacedVertices[i] - _HitPoint;
		//偏移顶点位置 乘 等分标尺
		_PointToVertex *= _UniformScale;
		//返回这个向量的平方长度(只读)
		//衰减力 等于  力度值除以 顶点偏移位置的平方长度
		float _AttenuatedForce = _Force / (1f + _PointToVertex.sqrMagnitude);
		//渐变速度
		float _Velocity = _AttenuatedForce * Time.deltaTime;
		//原始顶点偏移 加等 变形网格数据顶点的法线方向 乘 渐变速度
		_VertexVelocities[i] += _PointToVertex.normalized * _Velocity;
	}
}

组件搭载:

在这里插入图片描述

请添加图片描述

最终效果:
射线测距

在这里插入图片描述

网格变形

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
暂时先这样吧,如果有时间的话就会更新,实在看不明白就留言,看到我会回复的。
路长远兮,与君共勉。

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Maddie_Mo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值