Unity3D Editor: советы и трюки

в 8:29, , рубрики: unity3d

Решил вкратце в одном документе описать некоторые способы расширения редактора, позволяющие сделать работу с ним более удобной.

В публикации затронуты следующие моменты:

  1. Отображение иконки и текста над объектом в сцене;
  2. Отображение текста или иконки в окне Project;
  3. Шаблоны создаваемых скриптов;
  4. Открытие и создание проекта через контекстное меню проводника;
  5. Добавление подписчиков на событие в инспекторе.


Заранее предупрежу, что для сокращения кода в некоторых скриптах все поля сделал публичными. В реальных проектах так делать не стоит.

Отображение иконки и текста над объектом в сцене

Unity3D Editor: советы и трюки - 1

Название объекта или иконку можно отобразить встроенными средствами редактора: Gizmo and Icon Display Controls.

Иконку также можно отобразить с помощью метода Gizmos.DrawIcon. Файл иконки должен быть расположен в папке «Assets/Gizmos».

public class IconExample : MonoBehaviour
{
    void OnDrawGizmos()
    {
        Gizmos.DrawIcon(transform.position, "Icon.png", true);
    }
} 

Если вы хотите выводить свой текст, то можете воспользоваться следующим кодом:

public static class GizmosUtils
{
    public static void DrawText(GUISkin guiSkin, string text, Vector3 position, Color? color = null, int fontSize = 0, float yOffset = 0)
    {
#if UNITY_EDITOR
        var prevSkin = GUI.skin;
        if (guiSkin == null)
            Debug.LogWarning("editor warning: guiSkin parameter is null");
        else
            GUI.skin = guiSkin;

        GUIContent nameContent = new GUIContent(text);

        GUIStyle style = (guiSkin != null) ? new GUIStyle(guiSkin.GetStyle("Label")) : new GUIStyle();
        if (color != null)
            style.normal.textColor = (Color)color;
        if (fontSize > 0)
            style.fontSize = fontSize;

        Vector2 textSize = style.CalcSize(nameContent);
        Vector3 screenPoint = Camera.current.WorldToScreenPoint(position);

        if (screenPoint.z > 0) // проверка, необходимая чтобы текст не был виден, если  камера направлена в противоположную сторону относительно объекта
        {
            var worldPosition = Camera.current.ScreenToWorldPoint(new Vector3(screenPoint.x - textSize.x * 0.5f, screenPoint.y + textSize.y * 0.5f + yOffset, screenPoint.z));
            UnityEditor.Handles.Label(worldPosition, nameContent, style);
        }
        GUI.skin = prevSkin;
#endif
    }
} 
public class GizmosTextExample : MonoBehaviour
{
    public float yOffset = 16;
    public Color textColor = Color.cyan;
    public int fontSize = 12;

    private void OnDrawGizmos()
    {
        GizmosUtils.DrawText(GUI.skin, "Custom text", transform.position, textColor, fontSize, yOffset);
    }
}
Отображение текста или иконки в окне Project

Unity3D Editor: советы и трюки - 2

Для этого нужно использовать делегат EditorApplication.projectWindowItemOnGUI.
Ниже пример немного отредактированного кода, найденного по ссылке: Extending the editor: Project window.

[InitializeOnLoad]
internal class CustomProjectWindow
{
    static readonly  Color labelColor = new Color(0.75f, 0.75f, 0.75f, 1.0f);

    static CustomProjectWindow()
    {
        EditorApplication.projectWindowItemOnGUI += OnProjectWindowGUI;
    }
     
    static void OnProjectWindowGUI(string pGUID, Rect pDrawingRect)
    {
        string assetpath = AssetDatabase.GUIDToAssetPath(pGUID);
        string extension = Path.GetExtension(assetpath);
        bool icons = pDrawingRect.height > 20;

        if (icons || assetpath.Length == 0)
            return;

        GUIStyle labelStyle = new GUIStyle(EditorStyles.label);
        Vector2 labelSize = labelStyle.CalcSize(new GUIContent(extension));
        
        Rect newRect = pDrawingRect;
        newRect.width += pDrawingRect.x;
        newRect.x = newRect.width - labelSize.x - 4;

        Color prevGuiColor = GUI.color;
        GUI.color = labelColor;
        GUI.Label(newRect, extension, labelStyle);
        GUI.color = prevGuiColor;
    }
}

Отображение текста или иконки в окне Hierarchy

Здесь я, пожалуй, просто оставлю ссылку на статью, в который уже есть хороший пример: «Наводим порядок в Hierarchy View».

Шаблоны создаваемых скриптов

Unity3D Editor: советы и трюки - 3

При создании нового скрипта в окне Project, для него можно выбрать один из существующих шаблонов скриптов.
Если вы хотите, чтобы при создании нового скрипта в нем уже был написан какой-то определенный код, то данные шаблоны можно заранее отредактировать, либо создать свои.

Шаблоны обычно расположены в следующих папках:
Windows: Program FilesUnityEditorDataResourcesScriptTemplates
OS X: /Applications/Unity/Unity.app/Contents/Resources/ScriptTemplates

Опишу параметры в имени шаблона «81-C# Script-NewBehaviourScript.cs»:
«81» – порядковый номер шаблона в контекстном меню;
«C# Script» – отображаемое имя в контекстном меню;
«NewBehaviourScript» – дефолтное имя созданного скрипта.

Открытие и создание проекта через контекстное меню проводника

Unity3D Editor: советы и трюки - 4

В проводник Windows можно добавить пункты для создания или открытия существующего Unity3D проекта.

Готовые файлы реестра можно скачать по ссылке (Tip #63 и Tip #71):
Tip of the day

Добавление подписчиков на событие в инспекторе

Unity3D Editor: советы и трюки - 5

Немного не по теме, но хотелось бы описать довольно полезное нововведение.
В Unity 4.6 в инспекторе наконец-то добавили возможность назначать подписчиков на событие. Теперь можно перенести объекты в список подписчиков и выбрать методы, которые мы хотим выполнить при вызове этого события.
Для этого достаточно в скрипте объявить событие с типом UnityEvent или его наследником.

Пример кода, создающего объекты спустя заданный промежуток времени:

public class InvokeRepeating : MonoBehaviour
{
    public UnityEvent onInvoke;
    public float repeatTime = 3f;
    public float startTime = 1f;

    void Start()
    {
        InvokeRepeating("Execute", startTime, repeatTime);
    }

    void Execute()
    {
        onInvoke.Invoke();
    }
}
public class CreateObject : MonoBehaviour
{
    public Transform Prefab;

    public void Execute()
    {
        Instantiate(Prefab, transform.position, transform.rotation);
    }
}
Прощальные слова

Вот, в общем-то, и все, что я хотел написать. Надеюсь, данная публикация будет полезной для вас.

Автор: strannik_k

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js