В ящике должно быть
Handles.DrawLine(midPoint, midPoint + Normals[i] * 10);
. То, что вы сделали с помощью + Vector3.one * 10
, всегда дополнительно смещает направление в направлении X и Y.
Тогда вы бывместо этого используйте Vector3.Cross
, чтобы получить векторы, которые находятся под углом 90 ° к вашему вектору direction
.
Поскольку вы заставляете вершины всегда быть копланарными в XZ в любом случае (в вашем коде вы использовали Vector2
для того, чтобы отрезать компонент Y), вы можете напрямую передать обе позиции на Vector3.Cross
, чтобы выполучим нормаль треугольника, используя Vector3.zero
в качестве одной вершины.
Для первой точки % points
фактически всегда избыточен.
for (int i = 0; i < points; i++)
{
Normals.Add(Vector3.Cross(ControlPoints[i], ControlPoints[(i + 1) % points]).normalized);
}
![enter image description here](https://i.stack.imgur.com/MxjFi.png)
В зависимости от ваших потребностей вы должны быть осторожны, в каком порядке вы проходите в обоих пунктах.Поскольку применяется правило «левой руки», нормаль перевернет свое направление, если порядок обоих векторов будет перевернут в трехмерном пространстве.
Перекрестное произведение двух векторов приводит к третьему вектору, перпендикулярномуна два входных вектора.Величина результата равна амплитудам двух входов, умноженным вместе и затем умноженным на синус угла между входами.Вы можете определить направление вектора результата, используя «правило левой руки».
![](https://docs.unity3d.com/StaticFiles/ScriptRefImages/LeftHandRuleDiagram.png)
Однако - снова - сВы заставляете их быть всегда копланарными в XZ. Разве не ясно, что все нормальные значения всегда будут равны Vector3.up
?Чтобы вы могли пропустить весь обычный расчет и просто сделать
Handles.DrawLine(midPoint, midPoint + Vector3.up * 10);
Кстати: вам не нужен CustomEditor для этого.Вы можете просто сделать это в OnDrawGizmos
или OnDrawGizmosSelected
(вызывается только когда объект или родительский объект выбран в иерархии)
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
if (!initialized)
{
Init();
}
var points = ControlPoints.Count;
Handles.color = Color.green;
for (var i = 0; i < points; i++)
{
Handles.FreeMoveHandle(ControlPoints[i], Quaternion.identity, 1f, Vector3.zero, Handles.RectangleHandleCap);
Handles.DrawLine(ControlPoints[i], ControlPoints[(i + 1) % points]);
if (points > 1)
{
var midPoint = (ControlPoints[i] + ControlPoints[(i + 1) % points]) / 2;
Handles.DrawLine(midPoint, midPoint + Normals[i] * 10);
}
}
}
#endif