This media is not supported in your browser
VIEW IN TELEGRAM
Вроде бы простая домашка, а получилось очень неплохо)
Я вот сижу и думаю, конец года, надо бы цель на новый год поставить.
Меня привлекает идея хакатонов. А точнее геймджемов.
Хотели бы посмотреть, как я соберу небольшую команду и мы вместе постараемся создать что нибудь прекрасное за небольшое время?)
Меня привлекает идея хакатонов. А точнее геймджемов.
Хотели бы посмотреть, как я соберу небольшую команду и мы вместе постараемся создать что нибудь прекрасное за небольшое время?)
Ошибка, которая стоила мне 3 полных рабочих дня…
В начале этой недели у меня стояла задача - пофиксить вылеты, которые мы нашли во время тестов. Задача вроде бы не сильно сложная: найти причину и устранить ее. Но проблемы появились с самого начала…
Всегда перед началом выполнения какой то задачи, я простраиваю небольшой план в голове, как именно я буду ее решать. В данном случае было все достаточно просто:
1. Повторить ошибку и изучить данные, которые выдает Юнити
2. Найти причину путем несложные проставлений меток (обычно я использую обычный дебаг вывод, просто и быстро)
3. Исправить
Вот только, проблемы появились еще до 1 пункта.
Если вдруг вы работали с Photon Quantum, вы знаете ошибку расхождения состояний (Halting Error). Во время ее появления Юнити не выводит причину ошибки, а все из-за того, что расхождение состояний фиксируется в конце кадра (иногда даже через несколько кадров после совершения расхождения). Это специфика детерминированной системы)
Так вот. На самом деле я уже решал проблемы данного типа, но прикол в том, что после ошибки всегда выдавалось окно с данными, которые разошлись и я мог легко понять, в чем проблема…
В этот раз такого не было. Меня это немного напрягло
Вкратце: я фиксил реконект игроков к лобби. Так как игра у нас с закрытым лобби, реконект нужно было писать самостоятельно.
Изначально я думал что проблема в том, что я не понимаю как работает переподключение и искал проьлему там. Около 8-10 часов я рылся в коде, написанном в самом плагине, но все вроде было хорошо. Реконнект работал. Вот только через некоторое время в игре все равно появлялась эта ошибка.
* прошло 2 дня
я перепробовал все, пересмотрел всю документацию по запуску и реконекту к лобби, посмотрел гайд на их канале, и начал думать, что скорее всего проблема кроется совсем в другом.
И тут я решил проверить, если я уберу реконект и повторю все те же операции, что то поменяется? И знаете что?…
НЕТ!!! Проблема осталась. Все же ошибка происходила в другом месте…
Пошел третий день.
Я начал искать проблему в процессе игры. В начале просто проставлял дебаг выводы, но ни к чему это не привело. Всегда ошибка выводилась после всех выводов. И тут я понял, что детект ошибки не привязан к конкретному событию в коде, он всегда выводится после завершения всего кадра апдейта.
Я отчаялся. И начал комментировать весь код. Постепенно…
Раз за разом я комментировал все больше и больше кода. Но ошибка не пропадала. И вот в я наконец-то нашел строку, которая вызывает ошибку.. Это был момент освобождения массива (f.FreeList)
Но я все равно не понимал, что не так. Всегда работало, а тут вдруг перестало. По переписывался с нейронкой и пришел к выводу что при переподключении все ссылки меняются и их нужно заново инициализировать. Я поверил и переинициализировал все.
Алилуя! Заработало. Ошибки не стало. Но остался один нюанс.
Я не верил, что так топорно решать проблему - это правильное решение.
Я решил обратиться к истокам и перечитал документацию по динамическим массивам. И вдруг я нашел роковую строчку: после освобождения массива его необходимо обнулить (= default). В первый раз, когда я читал документацию, я достаточно торопился и пытался успеть сделать задачу в срок. Но в итоге, оно стоило мне очень много времени и нервов. Я 3 дня подряд ложился после 1-2 ночи (мой режим был 23-8)
Не буду подводить итоги или какую то мораль. Все и так понятно, стоило внимательно и полностью прочитать все, а потом уже приступать к реализации
#ЖизньArtemiZ
В начале этой недели у меня стояла задача - пофиксить вылеты, которые мы нашли во время тестов. Задача вроде бы не сильно сложная: найти причину и устранить ее. Но проблемы появились с самого начала…
Всегда перед началом выполнения какой то задачи, я простраиваю небольшой план в голове, как именно я буду ее решать. В данном случае было все достаточно просто:
1. Повторить ошибку и изучить данные, которые выдает Юнити
2. Найти причину путем несложные проставлений меток (обычно я использую обычный дебаг вывод, просто и быстро)
3. Исправить
Вот только, проблемы появились еще до 1 пункта.
Если вдруг вы работали с Photon Quantum, вы знаете ошибку расхождения состояний (Halting Error). Во время ее появления Юнити не выводит причину ошибки, а все из-за того, что расхождение состояний фиксируется в конце кадра (иногда даже через несколько кадров после совершения расхождения). Это специфика детерминированной системы)
Так вот. На самом деле я уже решал проблемы данного типа, но прикол в том, что после ошибки всегда выдавалось окно с данными, которые разошлись и я мог легко понять, в чем проблема…
В этот раз такого не было. Меня это немного напрягло
Вкратце: я фиксил реконект игроков к лобби. Так как игра у нас с закрытым лобби, реконект нужно было писать самостоятельно.
Изначально я думал что проблема в том, что я не понимаю как работает переподключение и искал проьлему там. Около 8-10 часов я рылся в коде, написанном в самом плагине, но все вроде было хорошо. Реконнект работал. Вот только через некоторое время в игре все равно появлялась эта ошибка.
* прошло 2 дня
я перепробовал все, пересмотрел всю документацию по запуску и реконекту к лобби, посмотрел гайд на их канале, и начал думать, что скорее всего проблема кроется совсем в другом.
И тут я решил проверить, если я уберу реконект и повторю все те же операции, что то поменяется? И знаете что?…
НЕТ!!! Проблема осталась. Все же ошибка происходила в другом месте…
Пошел третий день.
Я начал искать проблему в процессе игры. В начале просто проставлял дебаг выводы, но ни к чему это не привело. Всегда ошибка выводилась после всех выводов. И тут я понял, что детект ошибки не привязан к конкретному событию в коде, он всегда выводится после завершения всего кадра апдейта.
Я отчаялся. И начал комментировать весь код. Постепенно…
Раз за разом я комментировал все больше и больше кода. Но ошибка не пропадала. И вот в я наконец-то нашел строку, которая вызывает ошибку.. Это был момент освобождения массива (f.FreeList)
Но я все равно не понимал, что не так. Всегда работало, а тут вдруг перестало. По переписывался с нейронкой и пришел к выводу что при переподключении все ссылки меняются и их нужно заново инициализировать. Я поверил и переинициализировал все.
Алилуя! Заработало. Ошибки не стало. Но остался один нюанс.
Я не верил, что так топорно решать проблему - это правильное решение.
Я решил обратиться к истокам и перечитал документацию по динамическим массивам. И вдруг я нашел роковую строчку: после освобождения массива его необходимо обнулить (= default). В первый раз, когда я читал документацию, я достаточно торопился и пытался успеть сделать задачу в срок. Но в итоге, оно стоило мне очень много времени и нервов. Я 3 дня подряд ложился после 1-2 ночи (мой режим был 23-8)
Не буду подводить итоги или какую то мораль. Все и так понятно, стоило внимательно и полностью прочитать все, а потом уже приступать к реализации
#ЖизньArtemiZ
Я попробовал снимать сториз, вроде неплохо получается, но хочется развиваться дальше в этом направлении.
Что бы вы хотели видеть у меня в историях?
Что бы вы хотели видеть у меня в историях?
Anonymous Poll
36%
Моменты из личной жизни
24%
Места, в которых я бываю
84%
Моменты с работы и обучения (Unity)
72%
Обучающих контент (полезные советы)
Vector3Extensions.cs
331 B
Полезная находка!
Не всегда, когда сравниваешь расстояния, нужно знать конкретное значение. Иногда достаточно информации, какой вектор длиннее.
Для этого очень хорошо подойдет расширения методов для Vector3.
Чтобы его использовать, просто добавляете файл в проект игры и пишете:
transform.position.IsEnoughClose()
или
transform.position.SqrDistance()
#Фишки
Не всегда, когда сравниваешь расстояния, нужно знать конкретное значение. Иногда достаточно информации, какой вектор длиннее.
Для этого очень хорошо подойдет расширения методов для Vector3.
Чтобы его использовать, просто добавляете файл в проект игры и пишете:
transform.position.IsEnoughClose()
или
transform.position.SqrDistance()
#Фишки
Я немного приболел, видимо в поликлинике недавно заразился. Вроде уже поправляюсь, но сил пока что то делать нет)
Наверное до конца года особо контента не будет, я постараюсь что нибудь выкладывать, но не обещаю.
Сейчас я готовлю идеи на следующий год.
Мы продолжим работу над авточесом, я буду скидывать вам спойлеры)
Я наконец-то подобрал для себя подходящий темп обучения, поэтому периодически буду делиться результатами.
Тень - мой пет проект, который я планирую активно развивать в следующем году. Если все пойдет по плану, то контента будет много)
Еще в планах поучаствовать в геймджемах.
В общем, идей много, все хочется сделать.
Рассказывайте свои планы в комментариях, а я пойду лечиться)
#ЖизньArtemiZ
Наверное до конца года особо контента не будет, я постараюсь что нибудь выкладывать, но не обещаю.
Сейчас я готовлю идеи на следующий год.
Мы продолжим работу над авточесом, я буду скидывать вам спойлеры)
Я наконец-то подобрал для себя подходящий темп обучения, поэтому периодически буду делиться результатами.
Тень - мой пет проект, который я планирую активно развивать в следующем году. Если все пойдет по плану, то контента будет много)
Еще в планах поучаствовать в геймджемах.
В общем, идей много, все хочется сделать.
Рассказывайте свои планы в комментариях, а я пойду лечиться)
#ЖизньArtemiZ
Близится новый год. Очень хочется добавить интерактива для вас, поэтому самый важный опрос в истории канала!
В чем бы вы с удовольствием поучаствовали
В чем бы вы с удовольствием поучаствовали
Anonymous Poll
60%
Геймджемы, организованные мной
60%
Марафоны с определенной тематикой по Unity с победителями в конце
47%
Интенсивы от меня, с возможностью купить личное менторство
47%
Ничего не хочу, выпускайте игры, наконец!
Моя девушка создала канал, если есть любители визуала, подпишитесь, пожалуйста:)
(Она иллюстратор, будет рисовать для моих игр, в том числе)
https://tttttt.me/nastyaschaos
#ЖизньArtemiZ
(Она иллюстратор, будет рисовать для моих игр, в том числе)
https://tttttt.me/nastyaschaos
#ЖизньArtemiZ
Помните, я писал про полезное расширение для Vector3?
так вот, еще одна ооочень простая идея, но иногда полезная, когда вы хотите поменять только одну координату вектора, но сделать это напрямую нельзя
вот такие три метода помогут решить проблему
просто пишем:
#Фишки
так вот, еще одна ооочень простая идея, но иногда полезная, когда вы хотите поменять только одну координату вектора, но сделать это напрямую нельзя
public static Vector3 WithX(this Vector3 vector, float x)
{
return new Vector3(x, vector.y, vector.z);
}
public static Vector3 WithY(this Vector3 vector, float y)
{
return new Vector3(vector.x, y, vector.z);
}
public static Vector3 WithZ(this Vector3 vector, float z)
{
return new Vector3(vector.x, vector.y, z);
}
вот такие три метода помогут решить проблему
просто пишем:
transform.position = transform.position.WithZ(0); // Зануление координаты Z
#Фишки
Автоматический синглтон
Я обычно не использую синглтоны в проектах, так как они от части рушат структуру, но если вы их часто пишете, можно добавить в проект вот такой вот класс:
Вы просто пишите:
Затем:
и экономите кучу времени)
#Фишки
Я обычно не использую синглтоны в проектах, так как они от части рушат структуру, но если вы их часто пишете, можно добавить в проект вот такой вот класс:
using UnityEngine;
public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<T>();
if (_instance == null)
{
GameObject go = new GameObject(typeof(T).Name);
_instance = go.AddComponent<T>();
}
}
return _instance;
}
}
protected virtual void Awake()
{
if (_instance == null)
{
_instance = this as T;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
Вы просто пишите:
public class SceneLoader : Singleton<SceneLoader>
{
// Ваш код
}
Затем:
Singleton<SceneLoader>.Instance.LoadNextLevel();
и экономите кучу времени)
#Фишки
Было ли такое, что вы хотите во время симуляции в Unity узнать значение поля в классе?
Есть несколько вариантов это сделать:
1. С помощью Debug.Log();
2. С помощью перехода в Debug режим инспектора
Но эти варианты не всегда могут быть удобными
Поэтому я создал для вас кастомныйАтрибут !
Добавляете файл в проект и пишете:
Если поле публичное (что я категорически не советую делать), SerializeField можно не писать
Update: Исправил баг с компеляцией
#Фишки
Есть несколько вариантов это сделать:
1. С помощью Debug.Log();
2. С помощью перехода в Debug режим инспектора
Но эти варианты не всегда могут быть удобными
Поэтому я создал для вас кастомный
using UnityEditor;
using UnityEngine;
public class ReadOnlyAttribute : PropertyAttribute { }
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
public class ReadOnlyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
GUI.enabled = false;
EditorGUI.PropertyField(position, property, label);
GUI.enabled = true;
}
}
#endif
Добавляете файл в проект и пишете:
[SerializeField, ReadOnly] private bool _isGrounded;
Если поле публичное (что я категорически не советую делать), SerializeField можно не писать
Update: Исправил баг с компеляцией
#Фишки
Если вы используете однотипные объекты, постоянно их создавая и уничтожая, лучше всего применять пул объектов для них.
В Unity есть встроенный, но если вам нужно быстренько подключить пул без всяких наворотов, удобнее использовать что-то по проще.
Скидываю вам самое простое и быстрое решение:
Пишите в комментах, какие фишки хотите видеть в следующих постах ❤️
#Фишки
В Unity есть встроенный, но если вам нужно быстренько подключить пул без всяких наворотов, удобнее использовать что-то по проще.
Скидываю вам самое простое и быстрое решение:
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool<T> where T : Component
{
private readonly T _prefab;
private readonly Queue<T> _objects = new();
public ObjectPool(T prefab, int initialSize)
{
_prefab = prefab;
for (int i = 0; i < initialSize; i++)
{
CreateObject();
}
}
public T Get()
{
if (_objects.Count == 0)
{
CreateObject();
}
T obj = _objects.Dequeue();
obj.gameObject.SetActive(true);
return obj;
}
public void Return(T obj)
{
obj.gameObject.SetActive(false);
_objects.Enqueue(obj);
}
private void CreateObject()
{
T newObject = Object.Instantiate(_prefab);
newObject.gameObject.SetActive(false);
_objects.Enqueue(newObject);
}
}
#Фишки
Please open Telegram to view this post
VIEW IN TELEGRAM
#Фишки - Посты с полезной информацией про Unity. Расширение, оптимизация или просто совет
#ЖизньArtemiZ - Посты с личной информацией. О том, как я стал программистом и как провожу свое время
#Спойлер - Посты - тизеры к моим текущим проектам. У меня есть как рабочие проекты, так и личные.
#Мнение - рандомный пост с моим личным мнением на ту или иную тему. Скорее всего связанную с Unity
Путеводитель для начинающего разработчика игр на Unity
Нейросети в разработке игр на Unity
Порядок расположения элементов в классе
Как я докатился до жизни такой - Пост о том, как я стал программистом
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegraph
Путеводитель для начинающего разработчика игр на Unity
Привет! 👋 Вы начинаете путь в разработке игр на Unity - одном из самых популярных движков. Эта статья станет вашим путеводителем на первые 1-2 года обучения, предоставив структурированный план, рекомендации и ресурсы для создания собственных игр. 🎮 Мы рассмотрим…
Меня зовут - Артем. Мне 22 года. 5 лет назад я начал изучать Unity, а сейчас работаю в Дубаях!
Здесь я делюсь своим опытом и помогаю новичкам (и не только) освоиться в этой сфере. Все-таки, за пять лет я успел трижды бросить универ и пройти путь от физика до программиста.
Оставайтесь со мной, чтобы не пропустить:
- полезные фишки
- истории из моей жизни
- процесс разработки крупных проектов
Мои работы:
На данный момент я могу поделиться с вами только очень старой демкой, которую я делал в рамках обучения.
Ссылка на билд
Ссылка на исходники
Please open Telegram to view this post
VIEW IN TELEGRAM