Night Train Code - разработка игр
1.5K subscribers
62 photos
1 video
1 file
66 links
🖤 Разработка игр на Unity
🖤 Программирование на C#

Наш форум: @ntc_forum
Наш легаси-чат: @ntc_chat
Download Telegram
Всех с наступающим Новым годом! 🎄☃️

Желаю всем хорошо встретить 2025 и отдохнуть 🥛

А своими ёлками хвастаться можно здесь 🏡
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
34🔥12👍6🎉4
С Новым годом!!! ☃️
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥37🎉175
Опробовал я и ООП, и ECS, и реактивное программирование. Как итог, давно уже использую последнее на постоянной основе. Сначала пользовался своим решением, а популярный UniRx не зацепил меня в своё время и я благополучно его пропустил. Затем я решил не вставать на путь скуфа и начал отстаивать свои зумерские права, пробуя что-то новое, в чём мне успешно помогла новая библиотека R3. Вот небольшой кусок кода из документации, демонстрирующий её мощь (обратите внимание на формирование свойства IsDead в конструкторе):

public class Enemy
{
public ReactiveProperty<long> CurrentHp { get; private set; }

public ReactiveProperty<bool> IsDead { get; private set; }

public Enemy(int initialHp)
{
CurrentHp = new ReactiveProperty<long>(initialHp);
IsDead = CurrentHp.Select(health => health <= 0).ToReactiveProperty();
}
}


Здесь точно есть, где разгуляться, а использовать все фишки этой библиотеки вместе с MVVM (и другими паттернами этого семейства) одно удовольствие. Так сказать, UniRx на стероидах.

По какой причине я перешёл на реактивное программирование помимо разных фишек R3?

Из-за банальной экономии времени, ибо здесь можно легко повторно использовать ранее написанные механики, так как здесь идёт работа именно с данными, а не с конкретными сущностями. Ещё и меньше кода получится, в отличие от того же ECS. Рекомендую попробовать этот подход тем, кто ещё не попробовал. Возможно, это то, что вы ищете.
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍49🔥136👎1😢1
Писать методы расширения в C# можно и к кортежам

Например, можно легко узнать прогресс пройденного времени с результатом от 0 до 1. То есть если пройдёт одна секунда из двух, то мы получим значение 0.5

private void CalculateProgress()
{
_progress.Value = (_elapsedTime, _settings.Duration).Progress01();
}


Само расширение:

public static float Progress01(this (float a, float b) tuple)
{
return Mathf.Clamp01(tuple.a / PreventZero(tuple.b));
}


На ноль делить нельзя, поэтому я написал метод PreventZero(), который принимает в себя float и, при необходимости, заменит 0 на float.Epsilon с сохранением знака числа (плюса или минуса)

public static float PreventZero(this float value)
{
return Mathf.Approximately(value, 0)
? Mathf.Sign(value) * float.Epsilon
: value;
}


Night Train Code
👍35🤔95🔥2
С Днём Великой Победы!
51🎉24🤔10❤‍🔥5😢4
В Unity есть удобный метод Vector3.Distance, которым мы все так часто пользуемся, но почему не всегда он — лучший выбор?

Дело в том, что Vector3.Distance вычисляет корень из квадрата евклидова расстояния между двумя векторами для вычисления реального значения, а это относительно дорогая операция. В некоторых случаях мы можем избежать излишнего извлечения корня, воспользовавшись следующим методом:

public static float SqrDistance(Vector3 first, Vector3 second)
{
float deltaX = first.x - second.x;
float deltaY = first.y - second.y;
float deltaZ = first.z - second.z;
return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
}


Мы поняли, что получение квадрата расстояния — это более дешевая операция, чем получение обычного. Но где нам это может пригодиться? Например, мы можем использовать квадрат расстояния там, где важно сравнение расстояний, а не само значение:

public static bool WithinRadius(Vector3 first, Vector3 second, float distance)
{
return SqrDistance(first, second) < distance * distance;
}


Этот метод проверяет, находится ли один объект внутри определённого радиуса другого. Как видите, здесь нет необходимости в использовании обычного метода Vector3.Distance и мы можем легко оптимизировать этот процесс.

В качестве бонуса покажу ещё один пример. Для того, чтобы найти ближайший к точке объект из коллекции, нам тоже будет достаточно использовать метод SqrDistance вместо Vector3.Distance:

public static T GetClosest<T>(this IEnumerable<T> components, Vector3 position) where T : Component
{
T closest = null;
var minSqrDistance = float.MaxValue;

foreach (T component in components)
{
Transform transform = component.transform;
float sqrDistance = SqrDistance(transform.position, position);

if (sqrDistance < minSqrDistance)
{
closest = component;
minSqrDistance = sqrDistance;
}
}

return closest;
}


Night Train Code
2🔥41👍175🤔2😁1
Всех с наступающим Новым годом!!! 🎄
Please open Telegram to view this post
VIEW IN TELEGRAM
60🎉23🔥8🤯2💯1
а теперь всех с Новым годом!) 🔴
Please open Telegram to view this post
VIEW IN TELEGRAM
53🎉18👍62🤔1