有的时候,单单修改一个Mesh的中心点,旋转角度,和Scale并不能满足需求,比如有的时候,我们想让一个模型桥的边稍微变宽点来满足程序上的需求,通过拉伸的话模型比例就变了,这个时候要是能找到我们需要拉伸的点,然后手动把他们进行拉伸,那就省去了美术修改的时间了,而且更关键的是作为程序,我们可以准确的知道我们需要的位置,也能省去不少跟美术沟通的时间。
using UnityEngine;
using UnityEngine.EventSystems;
namespace LDFW.Model
{
public class MeshManipulator : MonoBehaviour, IPointerClickHandler
{
public Camera raycastingCamera;
public Transform draggingSphere;
[ContextMenuItem("Save", "SaveMesh")]
public string savePath = "Assets/";
private Transform vertexSphere;
private int vertexSphereReferencingIndex;
private Mesh originalMesh;
private Mesh currentMesh;
private MeshCollider meshCollider;
private Vector3[] originalVertices;
private Vector3[] currentVertices;
private Vector3 meshSize;
private int vertexCount;
private void Start()
{
MeshFilter meshFilter = GetComponent<MeshFilter>();
if (meshFilter != null)
{
originalMesh = meshFilter.mesh;
currentMesh = MeshGenerator.DuplicateMesh(originalMesh);
meshFilter.mesh = currentMesh;
meshSize = currentMesh.bounds.size;
originalVertices = originalMesh.vertices;
currentVertices = currentMesh.vertices;
vertexCount = originalVertices.Length;
foreach (var collider in GetComponents<Collider>())
DestroyImmediate(collider);
meshCollider = gameObject.AddComponent<MeshCollider>();
if (raycastingCamera == null)
raycastingCamera = Camera.main;
}
}
#if UNITY_EDITOR
private void Update()
{
if (vertexSphere != null)
{
currentVertices[vertexSphereReferencingIndex] = vertexSphere.localPosition;
currentMesh.vertices = currentVertices;
}
}
#endif
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("OnPointerClick");
RaycastHit hit;
Ray ray = raycastingCamera.ScreenPointToRay(eventData.position);
if (meshCollider.Raycast(ray, out hit, raycastingCamera.farClipPlane))
{
Debug.Log("hit point = " + hit.point);
if (vertexSphere != null)
Destroy(vertexSphere.gameObject);
//vertexSphereReferencingIndex = closestVertexIndex;
vertexSphere = Instantiate(draggingSphere.gameObject).transform;
vertexSphere.name = "vertex";
vertexSphere.SetParent(transform);
vertexSphere.position = hit.point;
vertexSphere.gameObject.SetActive(true);
vertexSphereReferencingIndex = FindClosestVertexIndex(vertexSphere.localPosition);
vertexSphere.localPosition = currentVertices[vertexSphereReferencingIndex];
Debug.Log("Closest point = " + currentVertices[vertexSphereReferencingIndex].ToString());
}
}
private int FindClosestVertexIndex(Vector3 position)
{
Debug.Log("position = " + position.ToString());
int closestIndex = -1;
float shortestDistance = float.MaxValue;
float currentDistance;
for (int i = 0; i < vertexCount; i++)
{
currentDistance = (currentVertices[i] - position).magnitude;
if (currentDistance < shortestDistance)
{
shortestDistance = currentDistance;
closestIndex = i;
}
}
return closestIndex;
}
public Mesh GetCurrentMesh()
{
return currentMesh;
}
public void SaveMesh()
{
LDFW.Tools.SaveToDisk.SaveAssetToFile(currentMesh, savePath);
}
}
}
来试验下,这个是原来的模型:
然后我们来改变一下里面闪电的大小: