ar
Feedback
Unity: Всё, что вы не знали о разработке

Unity: Всё, что вы не знали о разработке

الذهاب إلى القناة على Telegram

Авторский канал о разработке в Unity от Alex Silaev (CTO в Zillion Whales). Mushroom Wars 2 моих рук дело. Рассказываю об интересный кейсах, делюсь лайфхаками, решениями.

إظهار المزيد
1 774
المشتركون
لا توجد بيانات24 ساعات
لا توجد بيانات7 أيام
-730 أيام

جاري تحميل البيانات...

سحابة العلامات
لا توجد بيانات
هل تواجه مشاكل؟ يرجى تحديث الصفحة أو الاتصال بمدير الدعم الخاص بنا.
الإشارات الواردة والصادرة
---
---
---
---
---
---
جذب المشتركين
مايو '26
مايو '26
+10
في 0 قنوات
أبريل '26
+20
في 0 قنوات
Get PRO
مارس '26
+26
في 0 قنوات
Get PRO
فبراير '26
+38
في 0 قنوات
Get PRO
يناير '26
+28
في 0 قنوات
Get PRO
ديسمبر '25
+29
في 0 قنوات
Get PRO
نوفمبر '25
+18
في 0 قنوات
Get PRO
أكتوبر '25
+45
في 0 قنوات
Get PRO
سبتمبر '25
+46
في 0 قنوات
Get PRO
أغسطس '25
+41
في 1 قنوات
Get PRO
يوليو '25
+35
في 0 قنوات
Get PRO
يونيو '25
+48
في 0 قنوات
Get PRO
مايو '25
+48
في 0 قنوات
Get PRO
أبريل '25
+49
في 1 قنوات
Get PRO
مارس '25
+50
في 1 قنوات
Get PRO
فبراير '25
+42
في 0 قنوات
Get PRO
يناير '25
+39
في 1 قنوات
Get PRO
ديسمبر '24
+27
في 1 قنوات
Get PRO
نوفمبر '24
+61
في 0 قنوات
Get PRO
أكتوبر '24
+44
في 1 قنوات
Get PRO
سبتمبر '24
+21
في 0 قنوات
Get PRO
أغسطس '24
+30
في 0 قنوات
Get PRO
يوليو '24
+32
في 0 قنوات
Get PRO
يونيو '24
+40
في 0 قنوات
Get PRO
مايو '24
+48
في 0 قنوات
Get PRO
أبريل '24
+53
في 0 قنوات
Get PRO
مارس '24
+32
في 0 قنوات
Get PRO
فبراير '24
+81
في 2 قنوات
Get PRO
يناير '24
+78
في 0 قنوات
Get PRO
ديسمبر '23
+67
في 0 قنوات
Get PRO
نوفمبر '23
+28
في 0 قنوات
Get PRO
أكتوبر '23
+46
في 0 قنوات
Get PRO
سبتمبر '23
+73
في 0 قنوات
Get PRO
أغسطس '23
+59
في 0 قنوات
Get PRO
يوليو '23
+907
في 0 قنوات
التاريخ
نمو المشتركين
الإشارات
القنوات
31 مايو0
30 مايو+2
29 مايو0
28 مايو0
27 مايو0
26 مايو0
25 مايو+1
24 مايو+1
23 مايو+1
22 مايو+1
21 مايو0
20 مايو0
19 مايو0
18 مايو0
17 مايو+1
16 مايو+1
15 مايو0
14 مايو0
13 مايو0
12 مايو0
11 مايو0
10 مايو0
09 مايو0
08 مايو+1
07 مايو0
06 مايو0
05 مايو+1
04 مايو0
03 مايو0
02 مايو0
01 مايو0
منشورات القناة
Век живи - век учись Я вот только сегодня узнал, что оказывается можно писать не только так:

var str = $"{value}";
А еще и вот так:

var str = $$"""{{value}}""";
Или вот так:

var str = $$$"""{{{value}}}""";
Или проще говоря, от количества $ символов зависит количество скобочек. В целом довольно удобно иногда может быть. Я вот обнаружил это только сейчас, т.к. мне всегда хватало и одного $. #csharp #strings

2
Overlay У юнити, начиная с 2022.2 появилась возможжность рисовать свой окна в SceneView, при этом не прибегая к костылям вида "подпишусь на колбэк GUI, потом нарисую хрен пойми где хрен пойми как". UnityEditor.Overlays.Overlay - позволяет это сделать очень просто и легко. [Overlay(typeof(SceneView), "YourUniqueId", "Caption", defaultDisplay = true)] public class YourOverlay : Overlay { public override VisualElement CreatePanelContent() { return new Label("Test"); } } В целом довольно удобно, когда нужны какие-то настройки объектов на сцене, раньше приходилось руками рисовать, а сейчас удобная тулза. #unity #editor #sceneview
0
3
Удобное API Вы наверняка сталкивались с такой проблемой: void Method<T>(System.Action<T> callback) {...} То есть мы хотим вызвать метод, который вернет нам колбэк в какой-то момент. Например, что действие завершено. Все вроде хорошо, но если мы начнем это использовать, то сталкнемся с другой проблемой: Method<MyObj>(static (obj) => { // И вот тут нам явно не хватает данных при static }); Отсюда 2 выхода: либо мы используем аллокации при замыкании, либо реализуем некий второй параметр, в который мы сможем положить любые данные: void Method<T1, T2>(T1 t1, System.Action<T1, T2> callback) {...} С точки зрения метода будем считать, что T1 - это замыкание, которое мы передаем в метод: Method<int, MyObj>(123, static (closure, obj) => { ... }); Вроде уже неплохо, но что если у нас вместо простого int будет что-то сложнее, например, кортеж ValueTuple: Method<ValueTuple<int, int>, MyObj>((123, 234), static (closure, obj) => { ... }); Выходит уже неприятно, а если представить, что это мы захотим передать несколько параметров разных своих типов, то будет прям совсем нечитаемо. И тут тоже есть элегантное решение: struct ClosureAPI<TClosure> { public TClosure data; public MyContainer container; public Method<T>(System.Action<T, TClosure> callback) { this.container.Method(this.data, callback); } } ClosureAPI<TClosure> Closure<TClosure>(TClosure data) { return new ClosureAPI<TClosure>() { data = data, container = this, }; } void Method<T1, T2>(T1 t1, System.Action<T1, T2> callback) {...} Таким образом снаружи это будет выглядеть как: container.Closure((123, 234)).Method<MyObj>(static (data, obj) => { ... }); Вот таким образом мы избавляемся от необходимости указывать дженерик тип, который используем. Естественно, если вы передаете все инстансы в метод, то вам не нужно указывать типы, но если (как в примере выше) у вас тип передаете только как дженерик, то такой подход избавит от необходимости указывать дженерик замыкания. #zeroalloc #architecture #code
0
4
Простые лайфхаки Часто встречаю в разных проектах подобные конструкции (на самом деле обычно они страшнее, но я убрал все лишнее): var result = false; if (Method1() == true) result = true; if (Method2() == true) result = true; if (Method3() == true) result = true; ... return result; На самом деле этот код можно записать проще: var result = false; result |= Method1(); result |= Method2(); result |= Method3(); ... return result; Аналогично можно делать и обратную историю: var result = true; result &= ... В целом подобных штук можно найти немало, которые сэкономят время и приведут код с красивому и читаемому виду. #lifehack #basics #code
0
5
Довольно интересная задачка попалась на собеседовании в гугле: Есть матрица (массив массивов) вида [ [1, 0, 0, 0, 0, 1], [0, 1, 0, 1, 1, 1], [0, 0, 1, 0, 1, 0], [1, 0, 0, 0, 1, 0], [1, 0, 1, 1, 0, 0], [1, 0, 0, 0, 0, 1] ] Нужно реализовать метод, который найдет все острова. Островом считаются 1, которые не примыкают к границам. Диагонали не считаются за соединения. То есть на выходе должна быть матрица такого вида: [ [0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0] ] Как вы бы решали такую задачу? Доп вопросы: - Возможно ли решить задачу без аллоцирования памяти? (Стэк константного размера не считается) - Какая минимально возможная сложность по времени (О-нотация)? #interview #task #algorithms
0
6
Unity.Profiling.IgnoredByDeepProfilerAttribute Аттрибут, который спасет вам время, если у вас много кода, который вы точно не хотели бы видеть в профайлере. #attributes #profiling #unity
0
7
Рукожопы (других слов нет) выпустили апдейт юнити, в котором отломали uitk в инспекторе. Так что ждем хотфикс, а пока (если у вас вдруг ломается инспектор) можно отключить uitk и использовать imgui: Project Settings -> Editor -> use IMGUI #editor #unity
0
8
Всем привет ;) Как вы могли заметить, в этом канале нет рекламы, продажи курсов и подобных историй. Так будет продолжаться и
Всем привет ;) Как вы могли заметить, в этом канале нет рекламы, продажи курсов и подобных историй. Так будет продолжаться и дальше. Но я хотел бы предложить свои услуги в качестве консультаций в частном порядке, то есть мы разберем вашу проблему и найдем оптимальное для нее решение. Готов помочь с любыми проблемами на ваших текущих проектах или просто подтянуть знания по какой-то теме. Оплата по договоренности. Пишите в личку: @chromealex
0
9
NoAlias Этот аттрибут используется для Burst и позволяет экономить на инструкциях. Например: int Method(ref int a, ref int b) { b = 13; a = 42; return b; } В данном случае Burst не знает, пересекаются ли данные a и b (хранятся ли в памяти в одном месте или нет. То есть тут будет 3 инструкции mov, 2 для установки значения, а третья - для чтения этого значения. Если же добавить аттрибут NoAlias, возврат данных будет без дополнительной загрузки: int Method([NoAlias] ref int a, ref int b) { b = 13; a = 42; return b; } Аттрибут можно использовать для NativeArray (контейнеров), которые не пересекаются, и в качестве возврата из методов [return: NoAlias]. При этом это имеет смысл, если метод не заинлайнен, т.к. при инлайне аттрибут не будет иметь смысла. #noalias #burst #code
0
10
ResourcesAPI В юнити 6.2 появилась классная штука, которая позволяет переопределить дефолтные методы загрузки ресурсов. И это круто, если подобным образом они будут развиваться и дальше, то когда-нибудь можно будет переписать весь движок 🙂 https://docs.unity3d.com/6000.2/Documentation/ScriptReference/ResourcesAPI.html #unity #api #resources
0
11
Unity.Mathematics На самом деле многие не поняли зачем им использовать Unity.Mathematics, если у них есть Vector2/Vector3 и Mathf, например. Давайте разберем самый простой пример: var a = 10; var b = 20; var c = 30; var result = a * b + c; // Считаем результат У Unity.Mathematics есть math.mad, который внутри делает тоже самое: void mad(int a, int b, int c) => a * b + c; И самая большая ошибка считать, что никакой разницы в коде не будет. А работает это так: при компиляции кода, вызов math.mad мапится напрямую на simd-инструкцию, то есть код превращается из 2х инструкций в одну. Пример с math.mad - это лишь пример того, где вы можете сэкономить, в целом есть всякие select еще, которые тоже все избегают использовать. #unity #simd #math
0
12
Player Loop Вместо MonoBehaviour на сцене можно использовать инжект в текущий луп. Для этого нужно понимать в какой именно мы хотим добавить вызов своего метода. Всего есть 8 групп: TimeUpdate = 0 Initialization = 1 EarlyUpdate = 2 FixedUpdate = 3 PreUpdate = 4 Update = 5 PreLateUpdate = 6 PostLateUpdate = 7 Использовать проще всего с инжектом при инициализации, но в принципе можно вызывать этот код когда угодно, как и удалять свою систему из обработки: [RuntimeInitializeOnLoadMethod] static void Inject() { var loop = PlayerLoop.GetCurrentPlayerLoop(); var sys = new PlayerLoopSystem { type = typeof(YourClassName), updateDelegate = () => Debug.Log("Custom Update") }; var index = 4; // PreUpdate (см список выше) loop.subSystemList[index].subSystemList = loop.subSystemList[index].subSystemList.Append(sys).ToArray(); PlayerLoop.SetPlayerLoop(loop); } #unity #playerloop
0
13
CallerFilePathAttribute Этот аттрибут позволяет получить путь к файлу, из которого происходит вызов метода: private static void Sample(CallerFilePath] string file = null) { UnityEngine.Debug.Log(file); } Еще обратите внимание, что есть CallerMemberName (из какого метода вызов) и CallerLineNumber (на какой строке). #debug #csharp #code
0
14
https://youtu.be/GUVi04UCKsQ Поговорили про AI, какие основные алгоритмы используют для этого, что из себя представляют, где что использовать #streams #ai
0
15
https://youtu.be/TilgB9G1G3g Когда-то давно я показывал видео про наброски rts, в этом видео рассматривается основная механика построения деревьев и поиск данных в них. На ее основе можно строить физику, коллизии, RVO, поиск целей и множество других интересных вещей. #becs #trees
0
16
https://docs.google.com/presentation/d/1LlxyWOz88aXjAQVVJdN3Fss08E8Rnu8k/edit?usp=drivesdk&ouid=113802151767136274653&rtpof=true&sd=true Делюсь с вами моей презой для одного из закрытых ивентов. Тут собрана база, но вполне возможно, что в вашей компании/команде вы отходите от нее, чтобы делать мир лучше :) #events #presentation #allocations
0
17
Marshal.OffsetOf С помощью этого метода я в BECS нахожу где фактически находится поле в структуре, в которое я хотел бы записать данные. Я это использую в кодогене, когда я точно знаю название поля и хочу вписать туда данные, но использовать рефлексию для этого нет никакого желания. Работает примерно так: var offset = Marshal.OffsetOf(type, field.Name); codeGenOutput.Add($"var addr = (byte*)_addressOf(ref obj) + {offset};"); codeGenOutput.Add($"*(({objType}*)addr) = new SomeStruct(...);"); В итоге получается, что мы просто записываем данные в структуру obj без рефлексии и нам не важно приватное там поле или публичное. #unsafe #fieldoffset #marshal
0
18
https://www.youtube.com/watch?v=6syQWOWxUwY Про Players и Teams #becs #tutorials
0
19
https://github.com/chromealex/ME.Monitor/tree/main Написал тут тулзу для мониторинга за серваками. Умеет ping, tcp, rest, выв
https://github.com/chromealex/ME.Monitor/tree/main Написал тут тулзу для мониторинга за серваками. Умеет ping, tcp, rest, выводит графики, рисует маршруты. Предназначена для сборки в качестве standalone/adroid/ios билдов. Строит наглядно визуализацию расположения серверов и маршруты к ним. Для примера есть Config.json с рандомными сервисами, которые можно легко заменить на свои. Проект написан на коленке и там ничего не структурировано, так что без поллитра вряд ли разберетесь. Тем не менее, вполне хорошее решение получилось и свою задачу выполняет отлично. Собираете билд, подменяете конфиг на свои серваки и вперед наблюдать. Предложения принимаются :) #unity #tools #monitoring
0
20
https://youtu.be/4mbOPXLfArM Про Addressables, что такое GlobalEvents как их использовать. #becs #tutorials
0