Сделал процедурное сердечко на движке игры - получилось прикольно!
Как обычно, используются только символы с обычной клавиатуры. Не вращаются, не масштабируются и не искажаются. Почти текстовый режим с единственным исключением - вывод в произвольных координатах.
Новый вариант движка игры отрабатывает отлично! На этой сцене у меня стабильно 200fps на моем неттопе.
Сердце полностью процедурное. Никаких моделей - только формулы.
Базовый код очень простой:
public void GenerateHeart(int n, string str, Color color, float minDistance = 1.01f) {
float r, y, theta;
float goldenRatio = (1f + Mathf.Sqrt(5f)) / 2f;
float offset = 2f / n;
for (int i = 0; i < n; i++) {
y = (i * offset - 1) + (offset / 2);
r = Mathf.Sqrt(1 - y * y);
theta = 2 * Mathf.PI * i / goldenRatio;
PutCharToHeart(theta, Mathf.Acos(y), str[i % str.Length], color, minDistance);
}
}
public void PutCharToHeart(float u, float v, char ch, Color clr, float minDistance, float scale = 1f, CharAnim chanim = null) {
float sinV = Mathf.Sin(v);
float cosV = Mathf.Cos(v);
float sinU = Mathf.Sin(u);
float cosU = Mathf.Cos(u);
float x = sinV * (15 * sinU - 4 * Mathf.Sin(3 * u));
float z = sinV * (13 * cosU - 5 * Mathf.Cos(2 * u) - 2 * Mathf.Cos(3 * u) - Mathf.Cos(4 * u));
float heartY = 8 * cosV;
Vector3 point = new Vector3(x, heartY, z) * scale;
bool tooClose = false;
foreach (var existing in points)
if (Vector3.Distance(point, existing) < minDistance) {tooClose = true; break;}
// Add
if (!tooClose) {
points.Add(point);
pointsView.Add(point);
codes.Add(ch);
colors.Add(clr);
if (chanim == null) {
flags.Add(0);
anims.Add(null);
} else {
flags.Add(FLAG_ANIM);
anims.Add(chanim);
}
}
}![]()
Получилось вроде симпатично! Думаю добавить в игру. Не забудьте поиграть в текущую версию игры на Steam.