После невероятного успеха первой части (22 человекам понравилось и было целых 9 комментов, 3 из которых мои) — автор (я) решил написал продолжение повести о захватывающих приключениях в мире Unity3d.
Постарался подобрать свеженькие фишки.
1. Easy Buttons
Смысл хинта (кратко): Можно 1 строкой добавить вызов любого метода из редактора. При выделении объекта в редакторе появляется кнопка с названием метода, при клике на неё — метод выполняется.
Скачиваем, закидываем в проект, добавляем в коде:
Видим в редакторе:
После нажатия — результат выполнения:
Очень удобно тестировать эффекты или быстро вызывать события, которые по логике игры надо долго ждать. Экономит время.
Код можно скачать здесь
2. Conditional Hide
Смысл: можно легко скрыть ненужные поля. Например у вашего объекта только при использовании самонаведения надо задавать параметры радиус и тп. В остальных случаях их надо скрыть (или задисаблить). Это очень легко сделать.
[Header("Auto Aim")] public bool EnableAutoAim = false; [ConditionalHide("EnableAutoAim", true)] public float Range = 0.0f; [ConditionalHide("EnableAutoAim", true)] public bool AimAtClosestTarget = true; [ConditionalHide("EnableAutoAim", true)] public DemoClass ExampleDataClass = new DemoClass(); [ConditionalHide("EnableAutoAim", true)] public AnimationCurve AimOffsetCurve = new AnimationCurve();
Теперь поля будут показываться только при соблюдении условия EnableAutoAim. Можно так же не скрывать, а просто дисаблить поля, а так же использовать 2 условия.
Благодарности этому парню, там же можно скачать исходный код атрибута.
Штука очень удобная, упрощает процесс редактирования.
Обращу внимание, что первый и второй хинты работают по разному (первый перекрывает CustomEditor для всех объектов, что в некоторых случаях не очень хорошо, второй же CustomPropertyDrawer для своего аттрибута).
3. Скриншоты под разные разрешения одной кнопкой
Стандартные средства Unity для скриншотов довольно унылы — просто делает скриншот текущего разрешения. Но ведь сторам надо кучу скринов, для разных разрешений, разных соотношений сторон (16:9, 4:3, еще какие-то), еще и с какого-нибудь iPad pro с большим разрешением. Свежий пример — пару недельной давности — надо было такие:
3.5 Inch (iPhone 4): 640 x 960 px
4 Inch (iPhone 5): 640 x 1136 px
4.7 Inch (iPhone 6): 750 x 1334 px
5.5 Inch (iPhone 6 Plus): 1242 x 2208 px
iPad (9.7 + 7.9 Inch): 2048 x 1536 px
iPad Pro (12.9 Inch): 2732 x 2048
Под рукой такого зоопарка девайсов обычно не бывает. Выход — простенький скриптик — где создается текстура, туда рендериться камера (или камеры), и сохраняется.
Взять можно тут. А тут пример как переделать на много камер.
Теперь вы владеете мастерством создания скриншотов одной кнопкой.
4. Отправка LogError в Performance Reporting
Предистория: раньше был сервис Parse.com, если в игре возникала ошибка (не Exception, а что нибудь мелкое — например нет спрайта для оружия, или что-то еще), то в кода вызывался Debug.LogError(). Он перехватывался, отправлялся на Parse.com, там заносился в базу, если было много ошибок — скрипт сразу заводил баг-рипорт, чтобы мы обратили внимание. Но ⊂(° ʖ̯°)⊃ из Facebook купили parse и закрыли его, обломав кучу народу. Программе стало некуда отправлять рассказы о неприятностях, которые произошли с ней.
Есть всякие решения (отправлять такие вещи в статистику, использовать еще что-то) — но для любителей велосипедов предлагаю такое решение — отправлять в Performance Reporting (тем более что это самое логичное место где смотреть какие ошибки есть в программе).
Итак, в Unity есть Performance Reporting — но туда попадают только Exceptions. LogError не попадает. Если создавать Exception вместо LogError — то да, ошибка отправится и мы её увидим в Performance Reporting, но прекратиться дальнейшее выполнение скрипта. А там может особо ничего криминального и можно спокойно выполнять его дальше. Если создать Exception и самому его отловить — то скрипт не сыпанется (вы это отловите), но и в Performance Reporting ничего не будет отправлено, и мы про это не узнаем. Выход, который я предлагаю — подцепиться на LogError, при получении ошибки создать исключение в другом классе (пусть сыпется), тогда ошибка будет отправлена в Performance Reporting. Собственно код:
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class ErrorHandler : MonoBehaviour { public string output = ""; public string stack = ""; void Awake() { DontDestroyOnLoad(gameObject); } void OnEnable() { Application.logMessageReceived += HandleLog; } void OnDisable() { Application.logMessageReceived -= HandleLog; } void HandleLog(string logString, string stackTrace, LogType type) { if (type == LogType.Error) { output = logString; stack = stackTrace; Invoke("ThrowException", 0f); } } public void ThrowException() { throw new Exception(output + "\n" + stack); } }
Да, код далек от идеала и делался на скорую руку как замена парсу, со своими обязанностями вроде справляется. То, что при куче ошибок подряд теоретически может работать не совсем верно — понимаю, но на практике такого пока не было.
На загрузочной сцене сделайте объект, на него повешайте этот скрипт. Он сам пометит объект чтобы он не удалялся при загрузке сцен, и подпишется на Debug. При получении LogError скрипт создаст исключение, которое Unity отправит в Performance Reporting. Где вы о нем и узнаете.
Спасибо тем кто дочитал до конца. Надеюсь что-то из приведенного пригодится.
ссылка на оригинал статьи https://habrahabr.ru/post/327304/
Добавить комментарий