1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】インスペクターにプレハブのプレビュー画像を追加する

Last updated at Posted at 2024-12-06

はじめに

ScriptableObjectにプレハブのリストを追加していくと、一見しただけではわからないことがあったためプレハブのプレビュー画像をインスペクター上に追加する実装方法です。

実装イメージ

未実装

スクリーンショット 2024-12-05 174018.png

実装後

スクリーンショット 2024-12-05 174440.png

実装コード

PreviewDrawer.cs
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;

/// <summary>
/// プレビューのサイズ設定
/// </summary>
public class PreviewAttribute : PropertyAttribute
{
    // 定数 //

    static readonly int DefaultImageSize = 100; // プレビュー画像の初期サイズ

    // 変数 //
    
    // サイズが指定されなかった場合の初期値
    public float Height = DefaultImageSize;
}

/// <summary>
/// インスペクター上に画像を描画
/// </summary>
/// MEMO:シリアライズフィールドでインスペクター上にプレハブデータを追加した際、
///       プレハブのプレビュー画像を出力するようにできる
[CustomPropertyDrawer(typeof(PreviewAttribute))]
public class PreviewDrawer : PropertyDrawer
{
    // 定数 //

    static readonly int MarginRate = 2;                                         // インスペクター上に表示する際の余白倍率
    static readonly float Margin = EditorGUIUtility.standardVerticalSpacing;    // インスペクター上に表示する際の余白値

    /// <summary>
    /// GUIイベントに合わせたGUI描画
    /// </summary>
    /// <param name="position">描画座標、サイズ</param>
    /// <param name="property">描画対象のプロパティ</param>
    /// <param name="label">描画対象の情報</param>
    /// MEMO:プレハブ画像を追加するため、通常の描画をオーバーライド
    /// 実装参考URL:https://zenn.dev/gameshalico/articles/51217c728bfb67
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        // 通常のプロパティを描画
        position.height = EditorGUI.GetPropertyHeight(property, label);
        EditorGUI.PropertyField(position, property, label);

        // サイズ情報の取得
        var previewAttribute = (PreviewAttribute)attribute;

        // プレビュー用テクスチャの取得
        var texture = AssetPreview.GetAssetPreview(property.objectReferenceValue);
        if (texture == null) return;

        // 幅を設定
        var width = previewAttribute.Height * texture.width / texture.height;

        // テクスチャを表示する位置を計算
        var imageRect = new Rect
        {
            // 右寄せにして画像を表示
            x = position.xMax - width - Margin,
            y = position.y + position.height + Margin,
            width = width,
            height = previewAttribute.Height
        };

        // 画像を表示
        GUI.DrawTexture(imageRect, texture);
    }

    /// <summary>
    /// GUIの高さの取得
    /// </summary>
    /// <param name="property">対象のシリアライズされたプロパティ</param>
    /// <param name="label">ラベル</param>
    /// <returns>ピクセル単位の高さ</returns>
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        // 高さの追加
        var previewAttribute = (PreviewAttribute)attribute;
        
        // インスペクターに表示する際の高さ+余白
        return previewAttribute.Height + EditorGUI.GetPropertyHeight(property, label) + Margin * MarginRate;
    }
}
#endif

実装箇所
#if UNITY_EDITOR
    // HACK:[Preview(Height = 100)]の部分がリテラルでしか対応出来ていないため定数化出来ておりません。
    [Preview(Height = 100)]
#endif
    [SerializeField, Header("プレハブデータ")]
    GameObject sourcePrefab;    // ディスクのプレハブデータ

注意

エディター拡張部分は#ifで囲むか、Asset > Editorフォルダ内に入れないと
ビルドエラーが発生します。

参考

エディター拡張エラー↓
https://dokuro.moe/unity-its-not-bug-that-propertydrawer-not-found-when-build/

実装↓
https://zenn.dev/gameshalico/articles/51217c728bfb67

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?