В настоящее время я добился такого результата (до/после):
До
После
Модель правильно повторяет кривую земли, но толщина вообще не сохраняется. Модель становится очень тонкой, и все детали теряются.
до
после
Я создал диаграмму, показывающую, что происходит по сравнению с . что должно произойти:
график
Вот текущий код:
public LayerMask groundLayer;
public float maxRaycastDistance = 100f;
public float deformationStrength = 1.0f;
private MeshFilter meshFilter;
private Mesh originalMeshe;
private Mesh workingMeshe;
private Vector3[] originalVertice;
private Vector3[] deformedVertice;
public float height = 3f;
private void InitializeMeshe()
{
meshFilter = GetComponent();
var meshRenderers = GetComponent();
height = meshRenderers.bounds.size.y;
originalMeshe = meshFilter.sharedMesh;
workingMeshe = Instantiate(originalMeshe);
originalVertice = workingMeshe.vertices;
deformedVertice = new Vector3[originalVertice.Length];
meshFilter.mesh = workingMeshe;
}
public void DeformMeshe()
{
Vector3[] deformedVerts = new Vector3[originalVertice.Length];
for (int j = 0; j < originalVertice.Length; j++)
{
Vector3 worldPos = meshFilter.transform.TransformPoint(originalVertice[j]);
Vector3 closestPoint = worldPos;
Vector3? groundHeight = GetGroundHeight(worldPos);
if (groundHeight == null)
{
deformedVerts[j] = originalVertice[j];
continue;
}
float closestDistance = Vector3.Distance(worldPos, groundHeight.Value);
if (closestDistance < maxRaycastDistance) closestPoint = groundHeight.Value;
Vector3 targetPosition = Vector3.Lerp(worldPos, closestPoint, deformationStrength);
targetPosition.y += height;
deformedVerts[j] = meshFilter.transform.InverseTransformPoint(targetPosition);
}
workingMeshe.vertices = deformedVerts;
workingMeshe.RecalculateNormals();
workingMeshe.RecalculateBounds();
}
public Vector3? GetGroundHeight(Vector3 worldPos)
{
if (Physics.Raycast(worldPos, Vector3.down, out RaycastHit hitDown, maxRaycastDistance, groundLayer))
return hitDown.point;
if (Physics.Raycast(worldPos, Vector3.up, out RaycastHit hitUp, maxRaycastDistance, groundLayer))
return hitUp.point;
return null;
}
Как я могу исправить свой код для достижения своей цели?
- Первоначальный метод включает в себя передачу лучей лучей в сторону земли, чтобы определите его высоту и соответствующим образом отрегулируйте положение вершин по оси Y.
- Я пытался использовать нормали, чтобы поддерживать постоянное расстояние между точками.
float originalDistance = Vector3.Dot(originalVertice[j], vertexNormals[j]);
Vector3 adjustedPosition = closestPoint + normalWorld * originalDistance;
Vector3 targetPosition = Vector3.Lerp(worldPos, adjustedPosition, deformationStrength);
Результат с нормалями
- Все еще используя нормали, я попытался переместить точки вдоль самолет. Результат идентичен попытке 2.
Vector3 displacementOnPlane = displacement - Vector3.Dot(displacement, worldNormal) * worldNormal;
Vector3 targetPosition = worldPos + displacementOnPlane * deformationStrength;
targetPosition += worldNormal * height;
Подробнее здесь: https://stackoverflow.com/questions/792 ... -thickness
Мобильная версия